Android 图像处理(1)

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

}

}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

dRen-1713017907035)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

[外链图片转存中…(img-vKIDcYix-1713017907035)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 22
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值