Android绘图机制 Demo(简单完成美图秀秀的滤镜)
1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<ImageView
android:id="@+id/image_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2" />
<GridLayout
android:id="@+id/grid_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
android:columnCount="5"
android:rowCount="4"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_change"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="改变"/>
<Button
android:id="@+id/btn_reset"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="重置"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_gray"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="灰度"/>
<Button
android:id="@+id/btn_reverse"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="反转"/>
<Button
android:id="@+id/btn_nostalgia"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="怀旧"/>
<Button
android:id="@+id/btn_discoloration"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="去色"/>
<Button
android:id="@+id/btn_high_saturation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="饱和"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_negative"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="底片"/>
<Button
android:id="@+id/btn_old_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="老照片"/>
</LinearLayout>
</LinearLayout>
2.java
package com.example.android_image;
import androidx.appcompat.app.AppCompatActivity;
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.Paint;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridLayout;
import android.widget.ImageView;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity {
@BindView(R.id.image_view)
ImageView imageView;
@BindView(R.id.grid_layout)
GridLayout gridLayout;
@BindView(R.id.btn_change)
Button btnChange;
@BindView(R.id.btn_reset)
Button btnReset;
@BindView(R.id.btn_gray)
Button btnGray;
@BindView(R.id.btn_reverse)
Button btnReverse;
@BindView(R.id.btn_nostalgia)
Button btnNostalgia;
@BindView(R.id.btn_discoloration)
Button btnDiscoloration;
@BindView(R.id.btn_high_saturation)
Button btnHighSaturation;
@BindView(R.id.btn_negative)
Button btnNegative;
@BindView(R.id.btn_old_image)
Button btnOldImage;
private Bitmap bitmap;
private int mEtWidth;
private int mEtHeight;
private EditText[] editTexts = new EditText[20];
private float[] colorMatrices = new float[20];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
imageView.setImageBitmap(bitmap);
gridLayout.post(new Runnable() {
@Override
public void run() {
mEtWidth = gridLayout.getWidth() / 5;
mEtHeight = gridLayout.getHeight() / 4;
addEts();
initMatrix();
}
});
}
private void addEts() {
for (int i = 0; i < 20; i++) {
EditText editText = new EditText(MainActivity.this);
editTexts[i] = editText;
gridLayout.addView(editText, mEtWidth, mEtHeight);
}
}
private void initMatrix() {
for (int i = 0; i < 20; i++) {
if (i % 6 == 0) {
editTexts[i].setText(String.valueOf(1));
} else {
editTexts[i].setText(String.valueOf(0));
}
}
}
private void getMatrix() {
for (int i = 0; i < 20; i++) {
colorMatrices[i] = Float.valueOf(editTexts[i].getText().toString());
}
}
private void setImageMatrix() {
Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
Bitmap.Config.ARGB_8888);
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.set(colorMatrices);
Canvas canvas = new Canvas(bmp);
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
canvas.drawBitmap(bitmap, 0, 0, paint);
imageView.setImageBitmap(bmp);
}
private void specialEffect(int type) {
switch (type) {
case 1://灰度
colorMatrices = new float[]{0.33f, 0.59f, 0.11f, 0, 0,
0.33f, 0.59f, 0.11f, 0, 0,
0.33f, 0.59f, 0.11f, 0, 0,
0, 0, 0, 1, 0};
break;
case 2://反转
colorMatrices = new float[]{-1, 0, 0, 1, 1,
0, -1, 0, 1, 1,
0, 0, -1, 1, 1,
0, 0, 0, 1, 0};
break;
case 3://怀旧
colorMatrices = new float[]{0.393f, 0.769f, 0.189f, 0, 0,
0.349f, 0.686f, 0.168f, 0, 0,
0.272f, 0.534f, 0.131f, 0, 0,
0, 0, 0, 1, 0};
break;
case 4://去色
colorMatrices = new float[]{1.5f, 1.5f, 1.5f, 0, -1,
1.5f, 1.5f, 1.5f, 0, -1,
1.5f, 1.5f, 1.5f, 0, -1,
0, 0, 0, 1, 0};
break;
case 5://高饱和度
colorMatrices = new float[]{1.438f, -0.122f, -0.016f, 0, -0.03f,
-0.062f, 1.378f, -0.016f, 0, 0.05f,
-0.062f, -0.122f, 1.483f, 0, -0.02f,
0, 0, 0, 1, 0};
break;
}
for (int i = 0; i < 20; i++) {
editTexts[i].setText(String.valueOf(colorMatrices[i]));
}
}
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, 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);
return bmp;
}
private Bitmap handleImageOld(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 = (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;
} 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;
}
@OnClick({R.id.btn_change, R.id.btn_reset,
R.id.btn_gray, R.id.btn_reverse, R.id.btn_nostalgia,
R.id.btn_discoloration, R.id.btn_high_saturation,
R.id.btn_negative, R.id.btn_old_image})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.btn_change://作用矩阵效果
getMatrix();
setImageMatrix();
break;
case R.id.btn_reset://重置矩阵效果
initMatrix();
getMatrix();
setImageMatrix();
break;
case R.id.btn_gray://灰度
specialEffect(1);
setImageMatrix();
break;
case R.id.btn_reverse://反转
specialEffect(2);
setImageMatrix();
break;
case R.id.btn_nostalgia://怀旧
specialEffect(3);
setImageMatrix();
break;
case R.id.btn_discoloration://去色
specialEffect(4);
setImageMatrix();
break;
case R.id.btn_high_saturation://高饱和度
specialEffect(5);
setImageMatrix();
break;
case R.id.btn_negative://底片
imageView.setImageBitmap(handleImageNegative(bitmap));
break;
case R.id.btn_old_image://老照片
imageView.setImageBitmap(handleImageOld(bitmap));
break;
}
}
}
3.运行效果;