一、概述
本篇文章介绍的是关于Android图像处理相关的,主要有动态修改图像的色相、饱和度及亮度,颜色矩阵,图像像素点调整、图像矩阵实现图像的平移缩放等,Xfermode相关知识点,渐变相关,图像倒影,像素块的坐标变化等等。
二、实例演示
1.色相、饱和度、亮度
实现效果图如下:
核心代码:
/**
* 调整图像的色相、饱和度、亮度
* @param bm 需要处理的图像
* @param hue 色相
* @param saturation 饱和度
* @param lum 亮度
* @return
*/
public static Bitmap handleImageEffect(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(Paint.ANTI_ALIAS_FLAG);
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, lum, lum, 1);//1:全部透明
//将之前的设置融合
ColorMatrix imageMatrix = new ColorMatrix();
imageMatrix.postConcat(hueMatrix);
imageMatrix.postConcat(saturationMatrix);
imageMatrix.postConcat(lumMatrix);
paint.setColorFilter(new ColorMatrixColorFilter(imageMatrix));
canvas.drawBitmap(bm, 0, 0, paint);//绘制到画布
return bmp;
}
2.颜色矩阵
实现效果图如下:
核心代码:
package com.czhappy.imagedemo.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.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.GridLayout;
import android.widget.ImageView;
import com.czhappy.imagedemo.R;
/**
* Description:颜色矩阵
* User: chenzheng
* Date: 2016/12/20 0020
* Time: 17:42
*/
public class ColorMatrixActivity extends AppCompatActivity {
private ImageView imageview;
private GridLayout gridlayout;
private Bitmap bitmap;
private int mEtWidth, mEtHeight;
private EditText[] mEts = new EditText[20];
private float[] mColorMatrix = new float[20];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_color_matrix);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test1);
imageview = (ImageView) findViewById(R.id.imageview);
gridlayout = (GridLayout) findViewById(R.id.gridlayout);
//在控件绘制完毕调用
gridlayout.post(new Runnable() {
@Override
public void run() {
mEtWidth = gridlayout.getWidth()/5;
mEtHeight = gridlayout.getHeight()/4;
addEt();
initMatrix();
getMatrix();
setImageMatrix();
}
});
}
private void addEt(){
for (int i = 0; i < 20; i++) {
EditText et = new EditText(this);
mEts[i] = et;
gridlayout.addView(et, mEtWidth, mEtHeight);
}
}
private void initMatrix(){
for (int i = 0; i < 20; i++) {
if(i%6==0){
mEts[i].setText("1");
}else{
mEts[i].setText("0");
}
}
}
private void getMatrix(){
for (int i = 0; i < 20; i++) {
mColorMatrix[i] = Float.parseFloat(mEts[i].getText().toString());
}
}
private void setImageMatrix(){
Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
ColorMatrix colorMatrix = new ColorMatrix();
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);
imageview.setImageBitmap(bmp);
}
public void btnChange(View view){
getMatrix();
setImageMatrix();
}
public void btnReset(View view){
initMatrix();
getMatrix();
setImageMatrix();
}
}
3.图像像素点
实现效果图如下:
核心代码:
/**
* 底片效果
* @param bm
* @return
*/
public static 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, Bitmap.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 < width*height; i++) {
color = oldPx[i];
r = Color.red(color);
g = Color.green(color);
b = Color.blue(color);
a = Color.alpha(color);
r = 255-r;
g = 255-g;
b = 255-b;
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);//生成新的像素点
}
bmp.setPixels(newPx, 0, width, 0, 0, width, height);//将新像素点数组赋值给bitmap
return bmp;
}
/**
* 怀旧效果
* @param bm
* @return
*/
public static Bitmap handleImageOldPhoto(Bitmap bm){
int width = bm.getWidth();
int height = bm.getHeight();
int color;
int r, g, b ,a, r1, g1, b1;
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.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 < width*height; i++) {
color = oldPx[i];
r = Color.red(color);
g = Color.green(color);
b = Color.blue(color);
a = Color.alpha(color);
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);
if(r>255){
r=255;
}
if(g>255){
g=255;
}
if(b>255){
b=255;
}
newPx[i] = Color.argb(a, r, g, b);//生成新的像素点
}
bmp.setPixels(newPx, 0, width, 0, 0, width, height);//将新像素点数组赋值给bitmap
return bmp;
}
/**
* 浮雕效果
* @param bm
* @return
*/
public static Bitmap handleImageRelief(Bitmap bm){
int width = bm.getWidth();
int height = bm.getHeight();
int color=0, colorBefore=0;
int r, g, b ,a, r1, g1, b1;
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.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 < width*height; i++) {
colorBefore = oldPx[i-1];
r = Color.red(colorBefore);
g = Color.green(colorBefore);
b = Color.blue(colorBefore);
a = Color.alpha(colorBefore);
color = oldPx[i];
r1 = Color.red(color);
g1 = Color.green(color);
b1 = Color.blue(color);
r = (r - r1 + 127);
g = (g - g1 + 127);
b = (b - b1 + 127);
if(r>255){
r=255;
}
if(g>255){
g=255;
}
if(b>255){
b=255;
}
newPx[i] = Color.argb(a, r, g, b);//生成新的像素点
}
bmp.setPixels(newPx, 0, width, 0, 0, width, height);//将新像素点数组赋值给bitmap
return bmp;
}
4.图像矩阵
实现效果图如下:
核心代码:
package com.czhappy.imagedemo.activity;
import android.graphics.Matrix;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.View;
import android.widget.EditText;
import android.widget.GridLayout;
import com.czhappy.imagedemo.R;
import com.czhappy.imagedemo.view.ImageMatrixView;
/**
* Description:
* User: chenzheng
* Date: 2016/12/21 0021
* Time: 14:54
*/
public class ImageMatrixActivity extends AppCompatActivity {
private GridLayout gridlayout;
private ImageMatrixView imageMatrixView;
private int mEtWidth, mEtHeight;
private EditText[] mEts = new EditText[9];
private float[] mImageMatrix = new float[9];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_matrix);
imageMatrixView = (ImageMatrixView) findViewById(R.id.myview);
gridlayout = (GridLayout) findViewById(R.id.gridlayout);
//在控件绘制完毕调用
gridlayout.post(new Runnable() {
@Override
public void run() {
mEtWidth = gridlayout.getWidth()/3;
mEtHeight = gridlayout.getHeight()/3;
addEts();
initMatrix();
}
});
}
private void initMatrix() {
for (int i = 0; i < 9; i++) {
if(i%4==0){
mEts[i].setText("1");
}else{
mEts[i].setText("0");
}
}
}
private void addEts() {
for (int i = 0; i < 9; i++) {
EditText et = new EditText(this);
et.setGravity(Gravity.CENTER);
mEts[i] = et;
gridlayout.addView(et, mEtWidth, mEtHeight);
}
}
public void btnChange(View view){
getMatrix();
Matrix matrix = new Matrix();
matrix.setValues(mImageMatrix);
imageMatrixView.setImageMatrix(matrix);
imageMatrixView.invalidate();//刷新
//使用系统api
//doApi();
}
public void btnReset(View view){
initMatrix();
getMatrix();
Matrix matrix = new Matrix();
matrix.setValues(mImageMatrix);
imageMatrixView.setImageMatrix(matrix);
imageMatrixView.invalidate();//刷新
}
private void getMatrix(){
for (int i = 0; i < 9; i++) {
mImageMatrix[i] = Float.parseFloat(mEts[i].getText().toString());
}
}
private void doApi(){
getMatrix();
Matrix matrix = new Matrix();
matrix.setScale(2, 2);//将图像变为原来的来2倍
matrix.postTranslate(200, 200);//平移,顺序显示
imageMatrixView.setImageMatrix(matrix);
imageMatrixView.invalidate();//刷新
}
}
5.Xfermode
实现效果图如下:
核心代码:
package com.czhappy.imagedemo.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import com.czhappy.imagedemo.R;
/**
* Description:圆角图片
* User: chenzheng
* Date: 2016/12/22 0022
* Time: 10:19
*/
public class RoundRectXfermodeView extends View {
private Bitmap mBitmap, mOut;
private Paint mPaint;
public RoundRectXfermodeView(Context context) {
super(context);
initView();
}
public RoundRectXfermodeView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public RoundRectXfermodeView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView(){
setLayerType(LAYER_TYPE_SOFTWARE, null);//禁用硬件加速
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test1);
mOut = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(mOut);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
//绘制圆角矩形----dst
canvas.drawRoundRect(new RectF(0, 0, 300, 300), 50, 50, mPaint);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
//绘制图片----src
canvas.drawBitmap(mBitmap, 0, 0, mPaint);
mPaint.setXfermode(null);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(mOut, 0, 0, null);
}
}
6.BitmapShader
实现效果图如下:
核心代码:
package com.czhappy.imagedemo.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
import com.czhappy.imagedemo.R;
/**
* Description:
* User: chenzheng
* Date: 2016/12/22 0022
* Time: 11:03
*/
public class BitmapShaderView extends View {
private Bitmap mBitmap;
private Paint mPaint;
private BitmapShader mBitmapShader;
public BitmapShaderView(Context context) {
super(context);
}
public BitmapShaderView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public BitmapShaderView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
mPaint = new Paint();
mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
//REPEAT:重复,CLAMP:拉伸,MIRROR:镜像
mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
mPaint.setShader(mBitmapShader);
canvas.drawCircle(200, 300, 300, mPaint);
}
}
7.倒影
实现效果图如下:
核心代码:
package com.czhappy.imagedemo.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
import com.czhappy.imagedemo.R;
/**
* Description:倒影
* User: chenzheng
* Date: 2016/12/22 0022
* Time: 11:34
*/
public class ReflectView extends View{
private Bitmap mSrcBitmap, mRefBitmap;
private Paint mPaint;
public ReflectView(Context context) {
super(context);
initView();
}
public ReflectView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public ReflectView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView(){
mSrcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test1);
Matrix matrix = new Matrix();
matrix.setScale(1, -1);//x轴对称
mRefBitmap = Bitmap.createBitmap(mSrcBitmap, 0, 0, mSrcBitmap.getWidth(), mSrcBitmap.getHeight(), matrix, true);
mPaint = new Paint();
//透明度线性渐变
mPaint.setShader(new LinearGradient(0, mSrcBitmap.getHeight(), 0, mSrcBitmap.getHeight()*1.4f,
0xdd000000, 0x10000000, Shader.TileMode.CLAMP));
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(mSrcBitmap, 0, 0, null);
canvas.drawBitmap(mRefBitmap, 0, mSrcBitmap.getHeight(), null);
canvas.drawRect(0, mRefBitmap.getHeight(), mSrcBitmap.getWidth(), mSrcBitmap.getHeight()*2, mPaint);
}
}
8.像素块drawBitmapMesh
实现效果图如下:
核心代码:
package com.czhappy.imagedemo.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
import com.czhappy.imagedemo.R;
/**
* Description:
* User: chenzheng
* Date: 2016/12/22 0022
* Time: 14:13
*/
public class MeshView extends View {
private int WIDTH = 200;//纵向线的条数
private int HEIGHT = 200;//横向线的条数
private int COUNT = (WIDTH+1)*(HEIGHT+1);
private float[] verts = new float[COUNT*2] ;//改变后的坐标
private float[] orig = new float[COUNT*2] ;//原始坐标
private Bitmap mBitmap;
private float k = 1f;
public MeshView(Context context) {
super(context);
initView();
}
public MeshView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public MeshView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView(){
int index = 0;
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test1);
float bmWidth = mBitmap.getWidth();
float bmHeight = mBitmap.getHeight();
for (int i = 0; i < HEIGHT+1; i++) {
float fy = bmHeight*i/HEIGHT;
for (int j = 0; j < WIDTH+1; j++) {
float fx = bmWidth*j/WIDTH;
orig[index*2+0] = verts[index*2+0] = fx;
orig[index*2+1] = verts[index*2+1] = fy+50;
index++;
}
}
}
@Override
protected void onDraw(Canvas canvas) {
for (int i = 0; i < HEIGHT+1; i++) {
for (int j = 0; j < WIDTH+1; j++) {
verts[(i*(WIDTH+1)+j)*2+0] += 0;
//偏移量
float offsetY = (float) Math.sin((float)j/WIDTH*2*Math.PI + k * 2 * Math.PI);
verts[(i*(WIDTH+1)+j)*2+1] = orig[(i*(WIDTH+1)+j)*2+1] + offsetY*50;
}
}
k+=0.1f;
canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, verts, 0, null, 0, null);
invalidate();//重绘
}
}