android图像处理系列之三--图片色调饱和度、色相、亮度处理

原图:


处理后:


下面贴代码:

一、图片处理层:

package com.jacp.tone.view;import java.util.ArrayList;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;import com.jacp.tone.R;/*** 图片调色处理* @author maylian7700@126.com**/
public class ToneLayer {/*** 饱和度标识*/public static final int FLAG_SATURATION = 0x0;/*** 亮度标识*/public static final int FLAG_LUM = 0x1;/*** 色相标识*/public static final int FLAG_HUE = 0x2;/*** 饱和度*/private TextView mSaturation;private SeekBar mSaturationBar;/*** 色相*/private TextView mHue;private SeekBar mHueBar;/*** 亮度*/private TextView mLum;private SeekBar mLumBar;private float mDensity;private static final int TEXT_WIDTH = 50;private LinearLayout mParent;private ColorMatrix mLightnessMatrix;private ColorMatrix mSaturationMatrix;private ColorMatrix mHueMatrix;private ColorMatrix mAllMatrix;/*** 亮度*/private float mLumValue = 1F;/*** 饱和度*/private float mSaturationValue = 0F;/*** 色相*/private float mHueValue = 0F;/*** SeekBar的中间值*/private static final int MIDDLE_VALUE = 127;/*** SeekBar的最大值*/private static final int MAX_VALUE = 255;private ArrayList<SeekBar> mSeekBars = new ArrayList<SeekBar>();public ToneLayer(Context context) {init(context);}private void init(Context context) {mDensity = context.getResources().getDisplayMetrics().density;mSaturation = new TextView(context);mSaturation.setText(R.string.saturation);mHue = new TextView(context);mHue.setText(R.string.contrast);mLum = new TextView(context);mLum.setText(R.string.lightness);mSaturationBar = new SeekBar(context);mHueBar = new SeekBar(context);mLumBar = new SeekBar(context);mSeekBars.add(mSaturationBar);mSeekBars.add(mHueBar);mSeekBars.add(mLumBar);for (int i = 0, size = mSeekBars.size(); i < size; i++) {SeekBar seekBar = mSeekBars.get(i);seekBar.setMax(MAX_VALUE);seekBar.setProgress(MIDDLE_VALUE);seekBar.setTag(i);}LinearLayout saturation = new LinearLayout(context);saturation.setOrientation(LinearLayout.HORIZONTAL);saturation.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));LinearLayout.LayoutParams txtLayoutparams = new LinearLayout.LayoutParams((int) (TEXT_WIDTH * mDensity), LinearLayout.LayoutParams.MATCH_PARENT);mSaturation.setGravity(Gravity.CENTER);saturation.addView(mSaturation, txtLayoutparams);LinearLayout.LayoutParams seekLayoutparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);saturation.addView(mSaturationBar, seekLayoutparams);LinearLayout hue = new LinearLayout(context);hue.setOrientation(LinearLayout.HORIZONTAL);hue.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));mHue.setGravity(Gravity.CENTER);hue.addView(mHue, txtLayoutparams);hue.addView(mHueBar, seekLayoutparams);LinearLayout lum = new LinearLayout(context);lum.setOrientation(LinearLayout.HORIZONTAL);lum.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));mLum.setGravity(Gravity.CENTER);lum.addView(mLum, txtLayoutparams);lum.addView(mLumBar, seekLayoutparams);mParent = new LinearLayout(context);mParent.setOrientation(LinearLayout.VERTICAL);mParent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));mParent.addView(saturation);mParent.addView(hue);mParent.addView(lum);}public View getParentView() {return mParent;}/*** 设置饱和度值* @param saturation*/public void setSaturation(int saturation) {mSaturationValue = saturation * 1.0F / MIDDLE_VALUE;}/*** 设置色相值* @param hue*/public void setHue(int hue) {mHueValue = hue * 1.0F / MIDDLE_VALUE;}/*** 设置亮度值* @param lum*/public void setLum(int lum) {mLumValue = (lum - MIDDLE_VALUE) * 1.0F / MIDDLE_VALUE * 180;}public ArrayList<SeekBar> getSeekBars(){return mSeekBars;}/*** * @param flag*            比特位0 表示是否改变色相,比位1表示是否改变饱和度,比特位2表示是否改变明亮度*/public Bitmap handleImage(Bitmap bm, int flag) {Bitmap bmp = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(),Bitmap.Config.ARGB_8888);// 创建一个相同尺寸的可变的位图区,用于绘制调色后的图片Canvas canvas = new Canvas(bmp); // 得到画笔对象Paint paint = new Paint(); // 新建paintpaint.setAntiAlias(true); // 设置抗锯齿,也即是边缘做平滑处理if (null == mAllMatrix) {mAllMatrix = new ColorMatrix();}if (null == mLightnessMatrix) {mLightnessMatrix = new ColorMatrix(); // 用于颜色变换的矩阵,android位图颜色变化处理主要是靠该对象完成}if (null == mSaturationMatrix) {mSaturationMatrix = new ColorMatrix();}if (null == mHueMatrix) {mHueMatrix = new ColorMatrix();}switch (flag) {case FLAG_HUE: // 需要改变色相mHueMatrix.reset();mHueMatrix.setScale(mHueValue, mHueValue, mHueValue, 1); // 红、绿、蓝三分量按相同的比例,最后一个参数1表示透明度不做变化,此函数详细说明参考// // android// docbreak;case FLAG_SATURATION: // 需要改变饱和度// saturation 饱和度值,最小可设为0,此时对应的是灰度图(也就是俗话的“黑白图”),// 为1表示饱和度不变,设置大于1,就显示过饱和mSaturationMatrix.reset();mSaturationMatrix.setSaturation(mSaturationValue);break;case FLAG_LUM: // 亮度// hueColor就是色轮旋转的角度,正值表示顺时针旋转,负值表示逆时针旋转mLightnessMatrix.reset(); // 设为默认值mLightnessMatrix.setRotate(0, mLumValue); // 控制让红色区在色轮上旋转的角度mLightnessMatrix.setRotate(1, mLumValue); // 控制让绿红色区在色轮上旋转的角度mLightnessMatrix.setRotate(2, mLumValue); // 控制让蓝色区在色轮上旋转的角度// 这里相当于改变的是全图的色相break;}mAllMatrix.reset();mAllMatrix.postConcat(mHueMatrix);mAllMatrix.postConcat(mSaturationMatrix); // 效果叠加mAllMatrix.postConcat(mLightnessMatrix); // 效果叠加paint.setColorFilter(new ColorMatrixColorFilter(mAllMatrix));// 设置颜色变换效果canvas.drawBitmap(bm, 0, 0, paint); // 将颜色变化后的图片输出到新创建的位图区// 返回新的位图,也即调色处理后的图片return bmp;}}


二、主界面:

package com.jacp.tone;import java.util.ArrayList;import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;import com.jacp.tone.view.ToneLayer;/*** 启动的主界面* @author maylian7700@126.com**/
public class ImageToneActivity extends Activity implements OnSeekBarChangeListener {private ToneLayer mToneLayer;private ImageView mImageView;private Bitmap mBitmap;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);init();}private void init(){mToneLayer = new ToneLayer(this);mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);mImageView = (ImageView) findViewById(R.id.img_view);mImageView.setImageBitmap(mBitmap);((LinearLayout) findViewById(R.id.tone_view)).addView(mToneLayer.getParentView());ArrayList<SeekBar> seekBars = mToneLayer.getSeekBars();for (int i = 0, size = seekBars.size(); i < size; i++){seekBars.get(i).setOnSeekBarChangeListener(this);}}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {int flag = (Integer) seekBar.getTag();switch (flag){case ToneLayer.FLAG_SATURATION:mToneLayer.setSaturation(progress);break;case ToneLayer.FLAG_LUM:mToneLayer.setLum(progress);break;case ToneLayer.FLAG_HUE:mToneLayer.setHue(progress);break;}mImageView.setImageBitmap(mToneLayer.handleImage(mBitmap, flag));}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {}
}


三、布局文件:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayout android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:id="@+id/img_view"android:layout_gravity="center"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/tone_view"/></LinearLayout>
</ScrollView>


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/31939.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图片调色学习

色相环 色相混合正红&#xff08;0&#xff09;正黄&#xff08;60&#xff09;&#xff0c;透明度为&#xff08;50%&#xff09;即红黄等比例混合橙色&#xff08;30&#xff09; (060&#xff09;/230 真实调整透明度混合出并不一定为两者均值的色相,需要选择不同的混合方法…

图片颜色调节

云区 粉色云彩&#xff1a; 粉色云彩&#xff1a; 打开星图&#xff0c;清新滤镜马卡龙&#xff0c; 调节打开智能优化&#xff0c; 降低光感-100&#xff08;根据图片调&#xff09;、 色温最高、 色调最高&#xff0c; 增加结构让云更清晰&#xff0c; 增加饱和度。 晚霞&a…

excel如何快速将英文表格翻译为中文表格

1.打开excel&#xff0c;如下图想要快速将英文表格翻译为中 2.首先我们全选要翻译的表格区域单元格&#xff0c;接着点击【DIY工具箱】 ​ 3.点击【翻译】&#xff0c;选择【有道翻译】 4.接着鼠标点击【开始】 5.最后点击【确定】即可 6.完成效果如下图

CV大模型应用:Grounded-Segment-Anything实现目标分割、检测与风格迁移

Grounded-Segment-Anything实现目标分割、检测与风格迁移 文章目录 Grounded-Segment-Anything实现目标分割、检测与风格迁移一、Segment-Anything介绍二、Grounded-Segment-Anything1、简介2、测试 一、Segment-Anything介绍 代码链接&#xff1a;https://github.com/faceboo…

计算机视觉的应用6-利用VGG模型做毕加索风格图像迁移

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用5-利用VGG模型做毕加索风格图像迁移&#xff0c;本文将利用VGG模型实现毕加索风格图像迁移的方法。首先&#xff0c;我们将简要说明图像风格迁移的原理&#xff0c;然后使用PyTorch框架&#xff0c…

如何让ChatGPT帮我们提高开发效率

3 天前 ChatGPT云炬学长 ​关注 ChatGPT非常可怕&#xff01;才不到短短的几个月时间有上亿用户。 火爆程度以至于官方都不得不暂停plus用户的升级&#xff0c;以缓解压力。 ChatGPT能够发展那么快&#xff0c;确实是因为他真的很强大&#xff01; 能帮我们做ppt、帮我们做…

《联众》并购案细节公布,海虹海外公司浮出水面(ZT)

《联众》一夜身价暴增到2亿美金&#xff0c;《海虹>以及联众创始人成功套现1亿美金&#xff01;这是中韩国际资本合作的典范&#xff1f;还是海外资本的大举进攻的信号&#xff1f;或者就是互联网第二次井喷的前奏&#xff1f;在历史给予答案之前&#xff0c;让我们理顺并购…

微信授权登录:移动端[unionid](一)

专栏简介 &#x1f492;个人主页 &#x1f4c4;本栏目录 &#x1f4d6;心灵鸡汤&#x1f4d6; 生活中其实没有绝境&#xff0c;绝境在于你自己的心没有打开。 ✍相关博文✍ 微信分享开发&#xff1a;准备工作微信PC端扫码登录 如果你有…

第三方对接-微信登陆对接

对接第三方之微信登陆 由于目前市面上社交软件的使用排行来看&#xff0c;基本上微信一马当先。因此在大多数应用上都会内置微信登陆的场景&#xff0c;这时候我们就非常有必要熟悉微信的登录流程。 微信登陆 微信官方开发文档说明目前移动应用上微信登录仅支持原生登陆方式…

对三大数学软件 Mathematica 、Maple 、MATLAB 的小测试比较

今天一时兴起&#xff0c;突然想试试几个数学软件的功能&#xff0c;就测试了一个不定积分&#xff0c;看看哪个算得最好&#xff0c;最简洁。 计算&#xff1a; 以下计算结果我都一一验算了。 1).先在Mathematica&#xff08;我用的是在线的wolframalpha&#xff09;中计算,结…

【计算机图形学(译)】 二、各种各样的数学

【计算机图形学(译&#xff09;】 二、各种各样的数学 2 各种各样的数学 Miscellaneous Math2.1 集合和映射 Sets and Mapping2.1.1 反向映射 Inverse Mappings2.1.2 区间 Intervalsoft2.1.3 对数 Logarithms 2.2 解二次方程 Solving Quadratic Equations2.3 三角学 Trigonomet…

和托托一起学计算机图形学(一)-初识计算机图形学

文章目录 初识计算机图形学一、计算机科学与视觉信息处理二、计算机图形学的应用三、总结 数字图像基础一、像素二、RGB和CMY颜色模型三、颜色编码四、查色表五、图像文件六、总结 初识计算机图形学 一、计算机科学与视觉信息处理 计算机图形学&#xff1a;建模&#xff08;建…

如何使用 ChatGPT 掌握讲故事的艺术

想出一个故事情节&#xff0c;虽然有时很有趣&#xff0c;但可能是一个耗时的过程。或者你可能会发现自己遇到了作家的障碍——每个作家存在的祸根。 这个重要的灵感火花是 ChatGPT 可以提供帮助的地方。OpenAI流行的文本生成聊天机器人可以协助写作过程的任何部分&#xff0c…

仅剩1位73岁开发者苦撑!能求解超复杂物理方程式的计算程序,要没人维护了...

明敏 Alex 发自 凹非寺量子位 | 公众号 QbitAI 高能物理先进计算必备程序之一&#xff0c;快要没人维护了。 随着唯一的长期维护者达到73岁高龄&#xff0c;计算系统FORM的命运开始变得扑朔迷离起来。 过去30多年&#xff0c;这个程序被视为粒子物理学研究的基础工具之一&#…

苹果的头显,只要看一眼就行

阅读本文大概需要 1.66 分钟。 今年的 WWDC23 开发者大会&#xff0c;不少人表示 iOS 更新了个寂寞&#xff0c;但 Vision Pro 头显却意外吸引眼球&#xff0c;看来苹果工程师都忙着搞头显去了。 苹果的头显终于还是来了&#xff0c;关于它的传闻&#xff0c;似乎这几年从未间断…

AN OVERVIEW OF LANGUAGE MODELS RECENT DEVELOPMENTS AND OUTLOOK

LLM系列相关文章&#xff0c;针对《AN OVERVIEW OF LANGUAGE MODELS: RECENT DEVELOPMENTS AND OUTLOOK》的翻译。 语言模型综述&#xff1a;近年来的发展与展望 摘要1 引言2 语言模型的类型2.1 结构化LM2.2 双向LM2.3 置换LM 3 语言单元3.1 字符3.2 单词和子单词3.2.1 基于统…

使用 Sealos 三分钟打造鉴黄神器,我有个大胆的想法……

"NSFW" 是 "Not Safe For Work" 的缩写&#xff0c;通常用于标记那些在工作场所可能不适当的的在线内容。这种内容可能包含暴力、色情、血腥、或者其他可能被认为是令人反感或冒犯的材料&#xff0c;最常见的原因……是 18 成人内容。在许多在线平台&#…

8年前端带你HTML+CSS入门到实战(附视频+源码)

本文主要是解决&#xff1a; ☆ 想要自学前端开发&#xff0c; ☆ 但又不太想看博客文章&#xff0c; ☆ 觉得自学有点吃力&#xff0c;有点不知道学习步骤的同学 目录 一、HTML 1、需要了解熟练的标签 2、不太常用的标签 3、怎么算是HTML学好了&#xff0c;可以继续学CSS了…

NLP中的词向量对比:word2vec/glove/fastText/elmo/GPT/bert

点击上方&#xff0c;选择星标或置顶&#xff0c;每天给你送干货&#xff01; 阅读大概需要15分钟 跟随小博主&#xff0c;每天进步一丢丢 作者&#xff1a;JayLou&#xff0c;NLP算法工程师 知乎专栏&#xff1a;高能NLP之路 地址&#xff1a;https://zhuanlan.zhihu.com/p/56…

6款AI写作工具类网站推荐(第二版)

我们搜集了一些AI写作工具&#xff0c;希望对你有帮助&#xff0c;不论是在提升工作效率方面&#xff0c;还是在了解最新的AI技术方面&#xff0c;帮助你提升工作效率。 Notion AI https://www.notion.so/product/ai NotionAi可以提供AI智能写作&#xff0c;还能检查代码、语法…