写点什么

Android 图像处理

用户头像
Android架构
关注
发布于: 2021 年 11 月 07 日

Duang Duang~


学习一下原理:



Matrix:


其中 e,j,o,t 为偏移量


aR+bG+cB+dA+e


fR+gG+hB+iA+j


kR+lG+mB+nA+o


pR+qG+rB+sA+t


=


R1


G1


B1


A1


在 onCreate 函数中用 post 来获取组件的宽高:


mGroup.post(new Runnable() {


@Override


public void run() {


mEtWidth = mGroup.getWidth() / 5;


mEtHeight = mGroup.getHeight() / 4;


addEts();


initMatrix();


}


});



最后一弹,共实现负片,怀旧,浮雕,灰度,圆角,油画和左右对称 7 种特效:


实现的 ImageHelper 如下:


package com.zms.imageprocess;


import android.graphics.Bitmap;


import android.graphics.BitmapFactory;


import android.graphics.Canvas;


import android.graphics.Color;


import android.graphics.ColorMatrix;


import android.graphics.ColorMatrixColorFilter;


import android.graphics.Matrix;


import android.graphics.Paint;


import android.graphics.PorterDuff;


import android.graphics.PorterDuffXfermode;


import android.graphics.Rect;


import android.graphics.RectF;


import java.util.Random;


/**


  • Created by Administrator on 2015/4/1.


*/


public class ImageHelper {


// hue-色相 saturation-饱和度 lum-亮度


public static Bitmap ImageEffect(Bitmap bitmap, float hue, float saturation, float luminance) {


Bitmap mBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);


Canvas canvas = new Canvas(mBitmap);


Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);


// Hue-色相/色调


ColorMatrix hueMatrix = new ColorMatrix();


hueMatrix.setRotate(0, hue); // RED


hueMatrix.setRotate(1, hue); // GREEN


hueMatrix.setRotate(2, hue); // BLUE


// Saturation-饱和度


ColorMatrix saturationMatrix = new ColorMatrix();


saturationMatrix.setSaturation(saturation);


// Luminance-亮度/明度


ColorMatrix luminanceMatrix = new ColorMatrix();


// setScale(float rScale, float gScale, float bScale, float aScale)


luminanceMatrix.setScale(luminance, luminance, luminance, 1);


ColorMatrix imageMatrix = new ColorMatrix();


imageMatrix.postConcat(hueMatrix);


imageMatrix.postConcat(saturationMatrix);


imageMatrix.postConcat(luminanceMatrix);


paint.setColorFilter(new ColorMatrixColorFilter(imageMatrix));


// drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint)


canvas.drawBitmap(bitmap, 0, 0, paint);


return mBitmap;


}


public static Bitmap handleImage(Bitmap bm, int effect) {


Bitmap bitmap = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(),


Bitmap.Config.ARGB_8888);


int width = bm.getWidth();


int height = bm.getHeight();


int color = 0;


int r, g, b, a, r1, g1, b1;


int[] oldPx = new int[width * height];


int[] newPx = new int[width * height];


bm.getPixels(oldPx, 0, width, 0, 0, width, height);


switch (effect) {


case 0: // 负片效果


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);


}


bitmap.setPixels(newPx, 0, width, 0, 0, width, height);


break;


case 1: // 怀旧效果


for (int i = 0; i < width * height; i++) {


color = oldPx[i];


a = Color.alpha(color);


r = Color.red(color);


g = Color.green(color);


b = Color.blue(color);


r1 = (int) (0.393 * r + 0.769 * g + 0.189 * b);


g1 = (int) (0.349 * r + 0.686 * g + 0.168 * b);


b1 = (int) (0.272 * r + 0.534 * g + 0.131 * b);


if (r1 > 255) {


r1 = 255;


}


if (g1 > 255) {


g1 = 255;


}


if (b1 > 255) {


b1 = 255;


}


newPx[i] = Color.argb(a, r1, g1, b1);


}


bitmap.setPixels(newPx, 0, width, 0, 0, width, height);


break;


case 2: // 浮雕效果


int colorBefore = 0;


for (int i = 1; i < width * height; i++) {


colorBefore = oldPx[i - 1];


a = Color.alpha(colorBefore);


r = Color.red(colorBefore);


g = Color.green(colorBefore);


b = Color.blue(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);


}


bitmap.setPixels(newPx, 0, width, 0, 0, width, height);


break;


case 3: // 灰度


int alpha = 0xFF << 24;


for (int i = 0; i < height; i++) {


for (int j = 0; j < width; j++) {


int grey = oldPx[width * i + j];


int red = ((grey & 0x00FF0000) >> 16);


int green = ((grey & 0x0000FF00) >> 8);


int blue = (grey & 0x000000FF);


grey = (int) ((float) red * 0.3 + (float) green * 0.59 + (float) blue * 0.11);


grey = alpha | (grey << 16) | (grey << 8) | grey;


newPx[width * i + j] = grey;


}


}


bitmap.setPixels(newPx, 0, width, 0, 0, width, height);


break;


case 4: // 圆角


int roundPx = 55;


Canvas canvas = new Canvas(bitmap);


int colorRound = 0xff424242;


Paint paint = new Paint();


Rect rect = new Rect(0, 0, bm.getWidth(), bm.getHeight());


RectF rectF = new RectF(rect);


paint.setAntiAlias(true);


canvas.drawARGB(0, 0, 0, 0);


paint.setColor(colorRound);


canvas.drawRoundRect(rectF, roundPx, roundPx, paint);


paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));


canvas.drawBitmap(bm, rect, rect, paint);


break;


case 5: // 油画


int Radio = 0;


Random rnd = new Random();


int iModel = 10;


int i = width - iModel;


while (i > 1) {


int j = height - iModel;


while (j > 1) {


int iPos = rnd.nextInt(10) % iModel;


color = bm.getPixel(i + iPos, j + iPos);


bitmap.setPixel(i, j, color);


j = j - 1;


}


i = i - 1;


}


break;


case 6: // 左右对称


Canvas canvas2 = new Canvas(bitmap);


canvas2.drawColor(Color.BLACK);


canvas2.drawBitmap(bm, 0, 0, null);


Matrix matrix = new Matrix();


float[] values = {-1f, 0.0f, 0.0f, 0.0f, 1f, 0.0f, 0.0f, 0.0f, 1.0f};


matrix.setValues(values);


bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(),


matrix, true);


canvas2.drawBitmap(bitmap, bm.getWidth(), 0, null);


break;


}


return bitmap;


}


}


图像虚化:




上图是原图,下图是虚幻化后效果,可以拖拽 SeekBar 进行不同程度的虚化,如下:



package com.zms.blureffect;


import android.app.Activity;


import android.graphics.Bitmap;


import android.graphics.drawable.BitmapDrawable;


import android.graphics.drawable.Drawable;


import android.os.Bundle;


import android.util.Log;


import android.view.Display;


import android.widget.ImageView;


import android.widget.SeekBar;


import java.lang.reflect.Field;


public class Main extends Activity {


private int scaleWidth = 100;


private int scaleHeight = 100;


private int radius = 5;


private Drawable blurImage;


private String TAG = “BLUR”;


@Override


protected void onCreate(Bundle savedInstanceState) {


super.onCreate(savedInstanceState);


setContentView(R.layout.main);


SeekBar seekBar = (SeekBar) findViewById(R.id.seekBar1);


seekBar.setMax(24);


seekBar.setOnSeekBarChangeListener(new SeekBarListener());


Display display = this.getWindowManager().getDefaultDisplay();


scaleWidth = display.getWidth();


scaleHeight = (display.getHeight() - getStatusBarHeight()) / 2;


blurImage = getResources().getDrawable(R.drawable.note); // 要模糊的图片


BlurImage(blurImage, radius);


}


private class SeekBarListener implements SeekBar.OnSeekBarChangeListener {


// boolean fromUser 是用户操作进度条,还是代码中 setProgress


public void onProgressChanged(


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


SeekBar seekBar, int progress, boolean fromUser) {


System.out.println(progress);


if (seekBar.getProgress() > 0) {


BlurImage(blurImage, seekBar.getProgress());


} else {


// 当模糊半径为 0 时显示原图


ImageView imgAfter = (ImageView) findViewById(R.id.imgAfter);


Bitmap bitmapAfter = ((BitmapDrawable) blurImage).getBitmap();


Bitmap bitmapAfterAdjust = Bitmap.createScaledBitmap(bitmapAfter, scaleWidth,


scaleHeight, true); // 调整大小


imgAfter.setImageBitmap(bitmapAfterAdjust);


}


}


// 当用户开始滑动进度条时


public void onStartTrackingTouch(SeekBar seekBar) {


System.out.println("Start-->" + seekBar.getProgress());


}


// 当用户结束滑动进度条时


public void onStopTrackingTouch(SeekBar seekBar) {


System.out.println("Stop-->" + seekBar.getProgress());


}


}


public void BlurImage(Drawable blurImage, int radius) {


// 模糊前:


ImageView imgBefore = (ImageView) findViewById(R.id.imgBefore);


// Bitmap bitmapBefore =


// BitmapFactory.decodeResource(getResources(),R.drawable.note); // 方法一


Bitmap bitmapBefore = ((BitmapDrawable) blurImage).getBitmap(); // 方法二:drawable 转成 bitmap


Bitmap bitmapBeforeAdjust = Bitmap.createScaledBitmap(bitmapBefore,


scaleWidth, scaleHeight, true);


imgBefore.setImageBitmap(bitmapBeforeAdjust);


// 模糊后:


ImageView imgAfter = (ImageView) findViewById(R.id.imgAfter);


Bitmap bitmapAfter = Blur.fastblur(this, bitmapBefore, radius); // 第三个参数是模糊半径:0<radius<25


Bitmap bitmapAfterAdjust = Bitmap.createScaledBitmap(bitmapAfter,


scaleWidth, scaleHeight, true); // 调整大小


imgAfter.setImageBitmap(bitmapAfterAdjust);


}


/**

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android 图像处理