发表文章

[最新] Matrix和ColorMatrix

sliverbullets 3月前 1

版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/sliverbullets/article/details/81347967

一、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:后乘:当前矩阵乘上参数所代表的矩阵

关于它的应用:
一个图片放缩的例子,来源于鸿洋_的博客:

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

二、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) {

    }
}

参考链接

相关推荐
最新评论 (0)
返回
发表文章
sliverbullets
文章数
17
评论数
0
注册排名
982776