Android图像处理之色彩特效处理

参考《Android群英传》6.6

一、改变色光属性

        Android系统中封装了ColorMatrix类,就是颜色矩阵,通过这个类可以很方便的改变矩阵值来处理颜色效果。创建一个ColorMatrix和创建普通类是一样的。

        ColorMatrix中改变色光属性的几个方法:

        setRotate(axis, degrees):设置颜色的色调。

        第一个参数:系统分别用了0,1,2代表Red,Green,Blue三种颜色的处理。

        第二个参数:需要处理的值。

       ColorMatrix hueMatrix = new ColorMatrix();
       hueMatrix.setRotate(0, hue);
       hueMatrix.setRotate(1, hue);
       hueMatrix.setRotate(2, hue);

        setSaturation(saturation):设置颜色的饱和度。参数就是颜色饱和度的值,饱和度为0时,图像就成灰度图像了。

		ColorMatrix saturationMatrix = new ColorMatrix();
		saturationMatrix.setSaturation(saturation);

        setScale(rScale, gScale, bScale, aScale):设置图像亮度,当三原色以相同比例混合时,就会显示出白色,当亮度为0时,图像就全黑了。

		ColorMatrix lumMatrix  = new ColorMatrix();
		lumMatrix.setScale(lum, hue, saturation, 1);

        postConcat(hueMatrix):将以上三种方式处理的效果叠加起来显示混合效果。

		ColorMatrix colorMatrix = new ColorMatrix();
		colorMatrix.postConcat(hueMatrix);
		colorMatrix.postConcat(saturationMatrix);
		colorMatrix.postConcat(lumMatrix);

实例代码:

package com.example.androidcolormatrix;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class SeekBarActivity extends Activity implements OnSeekBarChangeListener {
	private ImageView imageView;
	private Bitmap bitmap;
	private SeekBar seekbarHue,seekbarSaturation,seekbarLum;
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		//初始化组件
		imageView = (ImageView) findViewById(R.id.imageView);
		seekbarHue = (SeekBar) findViewById(R.id.seekbarHue);
		seekbarSaturation = (SeekBar) findViewById(R.id.seekbarSaturation);
		seekbarLum = (SeekBar) findViewById(R.id.seekbarLum);
		
		//给拖动条设置初值
		seekbarHue.setProgress(50);
		seekbarSaturation.setProgress(50);
		seekbarLum.setProgress(50);
		
		//给imageview添加位图
		bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.we);
		imageView.setImageBitmap(bitmap);
		
		//给拖动条添加监听
		seekbarHue.setOnSeekBarChangeListener(this);
		seekbarSaturation.setOnSeekBarChangeListener(this);
		seekbarLum.setOnSeekBarChangeListener(this);
		
	}
	
	
	//设置ColorMatrix返回设置之后的位图
	private Bitmap handleImage(Bitmap bm, float hue, float saturation, float lum){
		Bitmap bmp = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(bmp);
		Paint paint = new Paint();
		
		ColorMatrix hueMatrix = new ColorMatrix();
		hueMatrix.setRotate(0, hue);
		hueMatrix.setRotate(1, hue);
		hueMatrix.setRotate(2, hue);
		
		ColorMatrix saturationMatrix = new ColorMatrix();
		saturationMatrix.setSaturation(saturation);
		
		ColorMatrix lumMatrix  = new ColorMatrix();
		lumMatrix.setScale(lum, hue, saturation, 1);

		ColorMatrix colorMatrix = new ColorMatrix();
		colorMatrix.postConcat(hueMatrix);
		colorMatrix.postConcat(saturationMatrix);
		colorMatrix.postConcat(lumMatrix);
		
		paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
		canvas.drawBitmap(bm, 0, 0, paint);
		
		return bmp;
	}
	
	@Override
	public void onProgressChanged(SeekBar bar, int progress, boolean fromUser){
		float mHue = 0;
		float mSaturation = 0;
		float mLum = 0;
		float MID_VALUE = 50;
		switch (bar.getId()) {
		case R.id.seekbarHue:
			mHue = (progress - MID_VALUE) * 1.0F / MID_VALUE * 180;
			break;
		case R.id.seekbarSaturation:
			mSaturation = progress * 1.0F / MID_VALUE;
			break;	
		case R.id.seekbarLum:
			mLum = progress * 1.0F / MID_VALUE;
			break;
		default:
			break;
		}
		imageView.setImageBitmap(handleImage(bitmap, mHue, mSaturation, mLum));
		
	}
	@Override
	public void onStartTrackingTouch(SeekBar arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void onStopTrackingTouch(SeekBar arg0) {
		// TODO Auto-generated method stub
		
	}
	
}

效果图:

Android图像处理之色彩特效处理_第1张图片

Android图像处理之色彩特效处理_第2张图片


二、Android颜色矩阵——ColorMatrix

       具体分析一下颜色矩阵:

      mycolormatrix.xml:

  



    

    
    
    
    
        

        MyColorMatrixActivity.java:

package com.example.androidcolormatrix;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
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 MyColorMatrixActivity extends Activity {
	
	private ImageView imageView;
	private GridLayout group;
	private Bitmap bitmap;
	
	private EditText[] edits = new EditText[20];
	private float[] editstext = new float[20];
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.mycolormatrix);
		//初始化组件
		imageView = (ImageView) findViewById(R.id.imageView);
		group  = (GridLayout) findViewById(R.id.group);
		
		bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.we);
		imageView.setImageBitmap(bitmap);
		
		
		group.post(new Runnable() {
			public void run() {
				addEdits();
				fillEdits();
			}
		});
		
	}
	
	//生成并添加20个编辑框
	private void addEdits(){
		for (int i = 0; i < 20; i++) {
			edits[i] = new EditText(MyColorMatrixActivity.this);
			edits[i].setHeight(group.getHeight() / 4);
			edits[i].setWidth(group.getWidth() / 5);
			group.addView(edits[i]);
		}
	}
	//为20个编辑框赋初值
	private void fillEdits(){
		for (int i = 0; i < 20; i++) {
			if(i % 6 == 0){
				edits[i].setText(String.valueOf(1));
			}else{
				edits[i].setText(String.valueOf(0));
			}
		}
	}
	
	public void onClickChange(View view){
		
		getAndSetImageView();
		
	}
	
	public void onClickReseet(View view){
		fillEdits();
		getAndSetImageView();
		
	}
	
	private void getAndSetImageView(){
		for (int i = 0; i < 20; i++) {
			editstext[i] = Float.valueOf(edits[i].getText().toString());
		}
		Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
		ColorMatrix colorMatrix = new ColorMatrix();
		colorMatrix.set(editstext);
		Canvas canvas = new Canvas(bmp);
		Paint paint = new Paint();
		paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
		canvas.drawBitmap(bitmap, 0, 0, paint);
		imageView.setImageBitmap(bmp);
	}
}

效果图:

Android图像处理之色彩特效处理_第3张图片

列举几种常见的矩阵值:

灰度效果:

0.33 , 0.59 , 0.11 , 0 , 0

0.33 , 0.59 , 0.11 , 0 , 0

0.33 , 0.59 , 0.11 , 0 , 0

0       , 0      ,  0      , 1 , 0

图像反转:

-1 , 0 , 0 , 1 , 1

0 , -1 ,0 , 1 , 1

0 , 0 , -1 , 1 , 1

0  ,   0  ,   0   ,    1  ,0

怀旧效果:

0.393 , 0.769 , 0.189 , 0 , 0

0.349 , 0.686 , 0.168 , 0  ,0

0.272 , 0.543 , 0.131 ,0 ,0

0         , 0          ,0          ,1 ,0

去色效果:

1.5 , 1.5 , 1.5 , 0 , -1

1.5 , 1.5 , 1.5 , 0 , -1

1.5 , 1.5 , 1.5 , 0 , -1

0    , 0     ,0     , 1 ,0

高饱和度:

1.438 , -0.122 , -0.016 , 0 , -0.03

-0.062, 1.378 , -0.016 , 0 , 0.05

-0.062, -0.122 ,1.438, 0 , -0.02

0        ,  0          , 0        , 1 ,0


二、像素点分析

         通过改变每个像素点的具体ARGB,可以更加精确地处理图像。

         注意:传递进来的原始图片是不能修改的,一般根据原始图片生成一张新的图片来修改。

         使用的方法;

         bitmap.getPixels(pixels, offset, stride, x, y, width, height):

         pixels:接收位图颜色值的数组

         offset:写入到pixels[]中的第一个像素索引值

         stride:pixels[]中的行间距

         x:从位图中读取的第一个像素的x坐标

         y:从位图中读取的第一个像素的y坐标

         width:从每一行中读取的像素宽度

         height:读取的行数

         通常情况下使用:bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, width, height);

                                         bitmap.setPixels(pixels, 0, bitmap.getWidth(), 0, 0, width, height);

 

        介绍几种常用的处理效果算法:

         底片效果:r = 255 - r;

                             g = 255 - g;

                             b = 255 - b;

 

         老照片效果:r = (int) (0.393*r+0.769*g+0.189*b);

                                g = (int) (0.349*r+0.686*g+0.168*b);
                                b = (int) (0.272*r+0.534*g+0.131*b);

         浮雕效果:B.r = C.r - B.r + 127;

                             B.g = C.g - B.g + 127;

                             B.b = C.b - B.b + 127;

代码:

negative.xml:



    
    



NegativeActivity.java:

package com.example.androidcolormatrix;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.widget.ImageView;

public class NegativeActivity extends Activity {
	
	private ImageView imageView;
	private Bitmap bitmap;
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.negative);
		
		imageView = (ImageView) findViewById(R.id.imageView);
		
		bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.we);
		imageView.setImageBitmap(handleImageNegative1(bitmap));
	}
	
	//底片效果
	private Bitmap handleImageNegative(Bitmap bm){
		int width = bm.getWidth();
		int height = bm.getHeight();
		
		int color;
		int r,g,b,a;
		
		Bitmap bmp = Bitmap.createBitmap(width, height, Config.ARGB_8888);
		 
		int[] oldPx = new int[width*height];
		int[] newPx = new int[width*height];
		
		bm.getPixels(oldPx, 0, width, 0, 0, width, height);
		
		for(int i = 0; i 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);
		}
		bmp.setPixels(newPx, 0, width, 0, 0, width, height);
		
		return bmp;
	}
	
	private Bitmap handleImageNegative1(Bitmap bm){
		int width = bm.getWidth();
		int height = bm.getHeight();
		
		int color;
		int r,g,b,a;
		
		Bitmap bmp = Bitmap.createBitmap(width, height, Config.ARGB_8888);
		 
		int[] oldPx = new int[width*height];
		int[] newPx = new int[width*height];
		
		bm.getPixels(oldPx, 0, width, 0, 0, width, height);
		
		for(int i = 1; i 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);
		}
		bmp.setPixels(newPx, 0, width, 0, 0, width, height);
		
		return bmp;
	}
	
	//老照片效果
	private Bitmap handleImageNegative2(Bitmap bm){
		int width = bm.getWidth();
		int height = bm.getHeight();
		
		int color;
		int r,g,b,a;
		
		Bitmap bmp = Bitmap.createBitmap(width, height, Config.ARGB_8888);
		 
		int[] oldPx = new int[width*height];
		int[] newPx = new int[width*height];
		
		bm.getPixels(oldPx, 0, width, 0, 0, width, height);
		
		for(int i = 0; i 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);
		}
		bmp.setPixels(newPx, 0, width, 0, 0, width, height);
		
		return bmp;
	}
}

效果图:

Android图像处理之色彩特效处理_第4张图片

源码下载:http://download.csdn.net/detail/fancheng614/9921341


     



        


你可能感兴趣的:(android进阶,Android群英传)