大家好,欢迎来到IT知识分享网。
一、Matrix——图像处理之图形特效处理
Android的图像变换矩阵是一个3 x 3的矩阵,如下:
矩阵初识值:
[1 0 0]
[0 1 0]
[0 0 1]
图像处理通常包含以下四种基本变换:
Translate——平移变换
Rotate——旋转变换
Scale——缩放变换
Skew——错切变换
至于具体怎么运算不需要了解太多,知道矩阵都有什么值,每个位置对应什么含义,会设置就行。
使用:
private float[] mImageMatrix = new float[9]; //一个以为数组存矩阵的值
Matrix matrix = new Matrix(); //创建Matrix对象
matrix.setValues(mImageMatrix); //将一维数组转换成图形变换矩阵
—————————————-
//在绘图中
canvas.drawBitmap(mBitmap,matrix,null);
—————————————-
//在自定义View中
setImageMatrix(matrix);
—————————————-
//为matrix设置各种值
matrix.setRotate()—-旋转变换
matrix.setTranslate()—-平移变换
matrix.setScale()—-缩放变换
matrix.setSkew()—-错切变换
pre()和post()—-提供矩阵的前乘和后乘运算
//注意:set方法会重置矩阵中的所有值,而post和pre方法不会
//post:前乘:参数所代表的矩阵乘上当前矩阵
//pre:后乘:当前矩阵乘上参数所代表的矩阵
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
关于它的应用:
一个图片放缩的例子,来源于洪洋的博客:
package com.example.librarydemo;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
public class ZoomImgeView extends android.support.v7.widget.AppCompatImageView implements ScaleGestureDetector.OnScaleGestureListener,
View.OnTouchListener,ViewTreeObserver.OnGlobalLayoutListener{
private static final String TAG = ZoomImgeView.class.getSimpleName() ;
public static final float SCALE_MAX = 4.0f;
private float initScale = 1.0f;
private final float[] matrixValues = new float[9];
private boolean once = true;
private ScaleGestureDetector mScaleGestureDetector = null;
private final Matrix mScaleMatrix = new Matrix();
public ZoomImgeView(Context context) {
this(context, null);
}
@SuppressLint(“ClickableViewAccessibility”)
public ZoomImgeView(Context context, AttributeSet attrs) {
super(context, attrs );
super.setScaleType(ScaleType.MATRIX);
mScaleGestureDetector = new ScaleGestureDetector(context ,this);
this.setOnTouchListener(this);
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
float scale = getScale();
float scaleFactor = detector.getScaleFactor();
if(getDrawable() == null){
return true;
}
if((scale < SCALE_MAX && scaleFactor >1.0f) || (scale > initScale && scaleFactor < 1.0f)){
if(scaleFactor * scale < initScale)
{
scaleFactor = initScale / scale;
}
if(scaleFactor * scale > SCALE_MAX)
{
scaleFactor = SCALE_MAX /scale;
}
mScaleMatrix.postScale(scaleFactor ,scaleFactor ,getWidth()/2,getHeight() /2);
setImageMatrix(mScaleMatrix);
}
return true;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return mScaleGestureDetector.onTouchEvent(event);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
@Override
public void onGlobalLayout() {
if(once)
{
Drawable d = getDrawable();
if(d == null)
return;
Log.i(TAG,d.getIntrinsicWidth() +”, “+d.getIntrinsicHeight());
int width = getWidth();
int height = getHeight();
int dw = d.getIntrinsicWidth();//与设备有关,获取
int dh = d.getIntrinsicHeight();
float scale = 1.0f;
if(dw >width && dh <=height ){
scale = width * 1.0f /dw;
}
if(dh > height && dw <= width){
scale = height * 1.0f /dh;
}
if(dw >width && dh >height){
scale = Math.min(dw * 1.0f /width , dh *1.0f / height);
}
initScale = scale;
mScaleMatrix.postTranslate((width -dw) / 2, (height – dh) /2);
mScaleMatrix.postScale(scale ,scale ,getWidth() /2 ,getHeight() /2);
setImageMatrix(mScaleMatrix);
once = false;
}
}
public float getScale(){
mScaleMatrix.getValues(matrixValues);
return matrixValues[Matrix.MSCALE_X];
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow( );
getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow( );
getViewTreeObserver().addOnGlobalLayoutListener(this);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
二、ColorMatrix——颜色矩阵
它是一个 4 x 5 的颜色矩阵。
下面介绍几中效果:
1)灰度效果
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
2)颜色反转
-1,0,0,1,1,
0,-1,0,1,1,
0,0,-1,1,1,
0,0,0,1,0,
3)怀旧效果
0.39F,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,
4)去色效果
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,
5)高饱和度
1.438F,-0.122F,-0.016F,0,-0.03F,
-0.062F,1.378F,-0.1016F,0,0.05F,
-0.062F,-0.122F,1.483F,0,-0.02F,
0,0,0,1,0,
一个练习Demo:
package com.example.matrixcolordemo;
import android.database.MatrixCursor;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener{
private SeekBar seek1,seek2,seek3;
ColorMatrix colorMatrix1,colorMatrix2 ,colorMatrix3;
ImageView img;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img = findViewById(R.id.img);
seek1 = findViewById(R.id.seek1);
seek2 = findViewById(R.id.seek2);
seek3 = findViewById(R.id.seek3);
seek1.setOnSeekBarChangeListener(this);
seek2.setOnSeekBarChangeListener(this);
seek3.setOnSeekBarChangeListener(this);
// float[] arr = 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};
colorMatrix1 = new ColorMatrix();
colorMatrix2 = new ColorMatrix();
colorMatrix3 = new ColorMatrix();
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
//设置色相
colorMatrix1.reset();
colorMatrix1.setRotate(0,(seek1.getProgress() -128f) *1.0f / 128f* 180);
colorMatrix1.setRotate(1,(seek1.getProgress() -128f) *1.0f / 128f* 180);
colorMatrix1.setRotate(2,(seek1.getProgress() -128f) *1.0f / 128f* 180);
//设置饱和度
colorMatrix2.reset();
colorMatrix2.setSaturation(seek2.getProgress() /128f);
//设置亮度
colorMatrix3.reset();
colorMatrix3.setScale(seek3.getProgress() /128f,
seek3.getProgress() /128f,
seek3.getProgress() /128f,
1);
//效果叠加
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.reset();
colorMatrix.postConcat(colorMatrix1);
colorMatrix.postConcat(colorMatrix2);
colorMatrix.postConcat(colorMatrix3);
img.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/49705.html