Android 图像处理,美团Android研发岗二面

Android 图像处理,美团Android研发岗二面

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

}

});

Android 图像处理,美团Android研发岗二面

最后一弹,共实现负片,怀旧,浮雕,灰度,圆角,油画和左右对称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进行不同程度的虚化,如下:

Android 图像处理,美团Android研发岗二面

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

}

}

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

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

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

}

/**

  • 获取状态栏的高度

  • @return int

上一篇:No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format : or :[:]:


下一篇:
记一次VS2010和VS2015自定义颜色的过程