android 中提供这样一个颜色矩阵来进行图像效果处理
这样的一个矩阵作为初始化的一个矩阵,因为带进去数据之后,RGB 没有变化,并没有改变原有效果
总结:
a,b,c,d,e 控制的是新像素点的R1
第2行,控制绿
第3行,控制blue
第4行,控制的是透明度
而整个矩阵的第5列,e,j,o,t 称为颜色的偏移量,他们是一个常量
改变一个颜色,不仅仅可以使用偏移量增加,同样可以改变系数扩大比例
代码:
package com.example.imagedeal;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.Bitmap.Config;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
//在android 中通过矩阵来处理图像是非常常用的方法
//矩阵计算公式
//第一个矩阵每行* 第二个矩阵每列 = 新矩阵中的一行
public class ImageHelper {
/**
*
* @param bm 图像
* @param hun 色相
* @param saturation 饱和度
* @param lum 亮度
* @return
*/
//三个参数为所需要调整的属性值
public static Bitmap handleImageEffect(Bitmap bm,float hun,float saturation,float lum){
Bitmap bmp= Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Config.ARGB_8888);
Canvas canvas=new Canvas(bmp);
Paint paint =new Paint(Paint.ANTI_ALIAS_FLAG);
//后面的操作都在画布上
//创建一个图像,将所有的效果表现出来
ColorMatrix hunMatrix=new ColorMatrix();
hunMatrix.setRotate(0, hun);//red
hunMatrix.setRotate(1, hun);//green
hunMatrix.setRotate(2, hun);//blue \
ColorMatrix saturationMatrix=new ColorMatrix();
saturationMatrix.setSaturation(saturation);
ColorMatrix lumMatrix =new ColorMatrix();
//在内部也是使用颜色数组 20位一维数组 将0,6,12,18 定义的Scale 值
//当RGB 三种形式以等量的形式 混合的时候就会产生白色 也就是说将rScale ,gScale ,bScale 设置同一个值,就会是白色 并且大于1,就可以增加他的亮度 。这一切都是矩阵实现的
lumMatrix.setScale(lum, lum, lum, 1);
ColorMatrix iamgeMatrix=new ColorMatrix();
iamgeMatrix.postConcat(hunMatrix);
iamgeMatrix.postConcat(saturationMatrix);
iamgeMatrix.postConcat(lumMatrix);
paint.setColorFilter(new ColorMatrixColorFilter(iamgeMatrix));
canvas.drawBitmap(bm, 0, 0, paint);
return bmp;
}
//根据像点实现特效 底片效果
public static Bitmap handlerImageNeative(Bitmap bm){
int width=bm.getWidth();
int height=bm.getHeight();
int color=0 ;//当前取出来的颜色
int r,g,b,a; // 保存从颜色中取出来的颜色分量
Bitmap bmp=Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888);
//如何遍历图片的所有像素点?
//bm.getWidth() 像素宽
//bm.getHeight()//像素高
int [] oldPx=new int[width*height];// 大小可以通过 相乘得到 像素数组 存储像素点
int [] newPx=new int[width*height];
//offset 起点时 需要读取像素点偏移的量 通常为0
//读取数组时的一个行距 多少个算是一行 通常情况下也是使用width 与原图保持一致
//xy 第一次 读取x y 的坐标 设置为0 从起点开始
//width 从bitmap 中读取的像素长度
//height 从bitmap 中读取的像素的高度
//
bm.getPixels(oldPx, 0, width, 0, 0, width, height);
//通过以上两行 代码就可以 将图像所有的像素点以数组的形式 保存到了oldPx 中
//有了这样一个像素数组 那么就好办了,for 循环
for(int i=0;i<width*height;i++){
color=oldPx[i];
//颜色取出来,但是我们操作的的是RGB 分量 还需要定义4个变量rgba
r=Color.red(color);//r 分量
g=Color.green(color);//g 分量
b=Color.green(color);
a=Color.alpha(color);
//分离了rgba 四个分量
//接下来就可以通过算法对这四个分量进行操作
r=255-r;
g=255-g;
b=255-b;
//保证处理的三个值依然在255 -0 之间
if(r>255){
r=255;
}else if(r<0){
r=0;
}
if(g>255){
g=255;
}else if(g<0){
g=0;
}
if(b>255){
b=255;
}else if(b<0){
b=0;
}
//最后新建数组存储新的像素点
newPx[i]=Color.argb(a,r, g, b); //就合成了一个新的颜色 并把颜色赋给新的像素点
//通过所有的循环 来做处理
//把数组重新设置给bitmap 的时候, 他的整个效果已经发生了新的改变
}
bmp.setPixels(newPx, 0, width, 0, 0, width, height);
return bmp;
}
//怀旧效果
public static Bitmap handlerImageOldPhoto(Bitmap bm){
return null;
}
//
public static Bitmap handlerImagePixlsRelief(Bitmap bm){
// 因为用到前一个点,所以循环的时候,是从1开始的。
return null;
}
}
package com.example.imagedeal;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.GridLayout;
import android.widget.ImageView;
public class ColorMatrix extends Activity {
private ImageView mImageView;
private GridLayout mGroup;
private Bitmap bitmap;
private int mEtWidth,mEtHeight;
private EditText [] mEts=new EditText[20];
private float [] mColorMatrix=new float[20];//每个EditText 的具体输入值 这个20 的一维数组, 对应的就是4*5 的矩阵 这个就是核心所在
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.color_activity);
bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.a);
mImageView=(ImageView) findViewById(R.id.imageview);
mGroup=(GridLayout) findViewById(R.id.group);
mImageView.setImageBitmap(bitmap);
//动态创建20个EditText
//获取gridLayout 的宽和高
mGroup.post(new Runnable() {
@Override
public void run() {
//控制 绘制完毕后执行 获取宽和高 4行5列
mEtWidth=mGroup.getWidth()/5;
mEtHeight=mGroup.getHeight()/4;
addEts();
initMatrix();
}
});
}
private void addEts(){
for(int i=0;i<20;i++){
EditText editText =new EditText(ColorMatrix.this);
mEts[i]=editText;
mGroup.addView(editText,mEtWidth,mEtHeight);
}
}
//初始化矩阵 第0,第6,12,18 都是1 其他的都是0 初始化的时候,就需要将这些editText 设置为1
private void initMatrix(){
for(int i=0;i<20;i++){
if(i%6==0){
mEts[i].setText(String.valueOf(1));
}else{
mEts[i].setText(String.valueOf(0));
}
}
}
public void btnChage(View view){
getMatrix();
setImageMatrix();
}
public void btnRset(View view){
initMatrix();//重新初始化
getMatrix();
setImageMatrix();
}
private void getMatrix(){
for(int i=0;i<20;i++){
mColorMatrix[i]=Float.valueOf(mEts[i].getText().toString());
}
}
//需要把颜色矩阵 作用与 图片上 产生一个图片处理效果
private void setImageMatrix(){
Bitmap bmp=Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
android.graphics.ColorMatrix colormatrix=new android.graphics.ColorMatrix();
//通过set方法将一个数组变为一个颜色矩阵
colormatrix.set(mColorMatrix);
Canvas canvas=new Canvas(bmp);
Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);//抗锯齿
paint.setColorFilter(new ColorMatrixColorFilter(colormatrix));//这样便拥有了神奇的画笔
canvas.drawBitmap(bitmap, 0, 0, paint);
mImageView.setImageBitmap(bmp);//处理后的图片设置到Imageview
}
}
package com.example.imagedeal;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.Menu;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
// 图像分析之 RGB 模型
//色调/色相 --物体传递的颜色
//饱和度 --颜色的纯度 从0(灰) 到100% (饱和)来进行描述
//亮度/明度 --颜色 的相对明暗程度
//图像经过放大后,会呈现一个个点阵,每一个点就是一个像素点 ,通过控制RGB 的颜色 配比,就可以显示出不同颜色
//ABC 3个像素点 求b点的底片效果算法 B.r =255-B.r B.g=255-B.g B.b=255-B.b 每一个像素点经过这样的换算,就是一个底片效果
//老照片效果
public class MainActivity extends Activity implements OnSeekBarChangeListener {
private ImageView iv;
private SeekBar seek_hue;
private SeekBar seek_saturation;
private SeekBar seek_lum;
private static int MAX_VALUE = 255;// 颜色取值0-255
private static int MID_VALUE = 127;
private float mHue,mSatauration,mLum;
private Bitmap bitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.a);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.imageview);
seek_hue = (SeekBar) findViewById(R.id.seekbar_hue);
seek_saturation = (SeekBar) findViewById(R.id.seekbar_saturation);
seek_lum = (SeekBar) findViewById(R.id.seekbar_lum);
seek_hue.setOnSeekBarChangeListener(this);
seek_saturation.setOnSeekBarChangeListener(this);
seek_lum.setOnSeekBarChangeListener(this);
seek_hue.setMax(MAX_VALUE);
seek_saturation.setMax(MAX_VALUE);
seek_lum.setMax(MAX_VALUE);
seek_hue.setProgress(MID_VALUE);
seek_saturation.setProgress(MID_VALUE);
seek_lum.setProgress(MID_VALUE);
iv.setImageBitmap(bitmap);
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
switch (seekBar.getId()) {
case R.id.seekbar_hue://色调
//这样一个取值范围 并不是固定的,是一个经验值,最能作用与ColorMatrix
mHue=(progress-MID_VALUE)*1.0F/MID_VALUE*180;
break;
case R.id.seekbar_saturation:
mSatauration=progress*1.0F/MID_VALUE;// 取值返回是0-2
break;
case R.id.seekbar_lum:
mLum=progress*1.0F/MID_VALUE;//
break;
default:
break;
}
iv.setImageBitmap(ImageHelper.handleImageEffect(bitmap, mHue, mSatauration, mLum));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
package com.example.imagedeal;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ImageView;
public class PixelsEfect extends Activity{
private ImageView iv1,iv2,iv3,iv4;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pixels_activity);
Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.a);
iv1=(ImageView) findViewById(R.id.image1);
iv2=(ImageView) findViewById(R.id.image2);
iv3=(ImageView) findViewById(R.id.image3);
iv4=(ImageView) findViewById(R.id.image4);
iv1.setImageBitmap(bitmap);
iv2.setImageBitmap(ImageHelper.handlerImageNeative(bitmap));
}
}
activity_main
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<ImageView
android:id="@+id/imageview"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="24dp" />
<SeekBar
android:id="@+id/seekbar_hue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/imageview"
/>
<SeekBar
android:id="@+id/seekbar_saturation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/seekbar_hue"
/>
<SeekBar
android:id="@+id/seekbar_lum"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/seekbar_saturation"
/>
</RelativeLayout>
color_activity
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<ImageView
android:id="@+id/imageview"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="2" />
<GridLayout
android:id="@+id/group"
android:layout_width="match_parent"
android:layout_weight="3"
android:columnCount="5"
android:layout_height="0dp"
android:rowCount="4" >
</GridLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="btnChage"
android:text="change" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="btnRset"
android:text="reset" />
</LinearLayout>
</LinearLayout>
pixels activity
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal" >
<ImageView
android:id="@+id/image1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<ImageView
android:id="@+id/image2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal" >
<ImageView
android:id="@+id/image3"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<ImageView
android:id="@+id/image4"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>