(4) -- color matrix for Android image processing

Keywords: Android xml encoding

We know that adjusting the color matrix can change the color effect of an image. Image processing is largely looking for the color matrix of an image. We can not only process the image through ColorMatrix, but also modify the value of the matrix accurately to achieve color effect processing.
The color matrix of 4X5 is simulated below, and the color effect of a picture is changed by changing the value in the matrix. Layout through GridLayout (not only in this way), make 4 rows and 5 columns, and simulate the effect of 4 * 5. The code is as follows:

/**
 * Use the matrix value of color matrix to change the picture
 * It mainly uses the formula of matrix to change its offset or change its base value R red G Green B blue A transparency
 * The corresponding color matrix value is applied to the original image to form a new frontal color style image.
 * @author fanshenxia
 *
 */
public class ColorMatrixActivity extends Activity implements OnClickListener {
    private ImageView mImg;
    private GridLayout mGrid;
    private Button mBtnUse, mBtnReset;
    private Bitmap mBitmap;
    private int mEtWidth, mEtHeight;
    private EditText[] mEts = new EditText[20];
    private float[] mColorMatrix = new float[20];

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_matrix_color);
        init();
    }

    private void init() {
        mImg = findViewById(R.id.iv_color);
        mGrid = findViewById(R.id.grid_color);
        mBtnUse = findViewById(R.id.use_color);
        mBtnReset = findViewById(R.id.reset_color);

        mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.boyimg);
        mBtnUse.setOnClickListener(this);
        mBtnReset.setOnClickListener(this);

        mGrid.post(new Runnable() {
            @Override
            public void run() {
                // Get width and height information
                mEtWidth = mGrid.getWidth() / 5;
                mEtHeight = mGrid.getHeight() / 4;
                addEts();
                initMatrix();
            }
        });
    }

    // Add EditText
    private void addEts() {
        for (int i = 0; i < 20; i++) {
            EditText editText = new EditText(ColorMatrixActivity.this);
            mEts[i] = editText;
            mGrid.addView(editText, mEtWidth, mEtHeight);
        }
    }

    // Initialize color matrix to initial state
    private void initMatrix() {
        for (int i = 0; i < 20; i++) {
            if (i % 6 == 0) {
                mEts[i].setText(String.valueOf(1));
            } else {
                mEts[i].setText(String.valueOf(0));
            }
        }
    }

    // Get matrix value
    private void getMatrix() {
        for (int i = 0; i < 20; i++) {
            mColorMatrix[i] = Float.valueOf(mEts[i].getText().toString());
        }
    }

    //Set matrix value to image
    private void setImgMatrix() {
        Bitmap curBitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), Config.ARGB_8888);
        ColorMatrix colorMatrix = new ColorMatrix();
        colorMatrix.set(mColorMatrix);

        Canvas canvas  = new Canvas(curBitmap);
        Paint paint = new Paint();
        paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
        canvas.drawBitmap(mBitmap, 0, 0, paint);

        mImg.setImageBitmap(curBitmap);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.use_color:
            getMatrix();
            setImgMatrix();
            break;
        case R.id.reset_color:
            initMatrix();
            getMatrix();
            setImgMatrix();
            break;
        default:
            break;
        }
    }
}

Layout file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/iv_color"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/boyimg" />

    <GridLayout
        android:id="@+id/grid_color"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:columnCount="5"
        android:rowCount="4" >
    </GridLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal" >
        <Button
            android:id="@+id/use_color"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_margin="5dp"
            android:layout_weight="1"
            android:text="use" />

        <Button
            android:id="@+id/reset_color"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_margin="5dp"
            android:layout_weight="1"
            android:text="reset" />
    </LinearLayout>

</LinearLayout>

The operation effect is as follows:

Run the above code, change the image color effect by changing the matrix value.

Common image color matrix processing effects:

  • Gray effect, color matrix is as follows:
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

Image inversion effect, color matrix is as follows:

-1,0,0,1,1,
0,-1,0,1,1,
0,0,-1,1,1,
0,0,0,1,0

Nostalgic effect, the color matrix is as follows:

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

The color matrix is as follows:

Write code here

High saturation effect, color matrix as follows:

Write code here

For the convenience of seeing the effect, I added several buttons:

     <Button
            android:id="@+id/grey_color"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_margin="5dp"
            android:layout_weight="1"
            android:text="Grayscale effect" />

        <Button
            android:id="@+id/reversal_color"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_margin="5dp"
            android:layout_weight="1"
            android:text="Inverse effect " />

        <Button
            android:id="@+id/old_color"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_margin="5dp"
            android:layout_weight="1"
            android:text="Nostalgic effect" />

Some code was added:

private float[] mGreyMatrix,mReversalMatrix,mOldMatrix;
private void initSomethingMatirx() {
        //Grayscale
        mGreyMatrix = 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};
        //Reversal
        mReversalMatrix = new float[]{
                -1,0,0,1,1,
                0,-1,0,1,1,
                0,0,-1,1,1,
                0,0,0,1,0
        };
        //Nostalgia
        mOldMatrix = 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
        };
    }
    //Then set the matrix in the click event

The operation effect is as follows:

The complete code is as follows:

public class ColorMatrixActivity extends Activity implements OnClickListener {
    private ImageView mImg;
    private GridLayout mGrid;
    private Button mBtnUse, mBtnReset, mBtnGrey, mBtnReversal,mBtnOld;
    private Bitmap mBitmap;
    private int mEtWidth, mEtHeight;
    private EditText[] mEts = new EditText[20];
    private float[] mColorMatrix = new float[20];
    private float[] mGreyMatrix,mReversalMatrix,mOldMatrix;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_matrix_color);
        init();
    }

    private void init() {
        initSomethingMatirx();

        mImg = findViewById(R.id.iv_color);
        mGrid = findViewById(R.id.grid_color);
        mBtnUse = findViewById(R.id.use_color);
        mBtnReset = findViewById(R.id.reset_color);
        mBtnGrey = findViewById(R.id.grey_color);
        mBtnReversal = findViewById(R.id.reversal_color);
        mBtnOld = findViewById(R.id.old_color);

        mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.boyimg);
        mBtnUse.setOnClickListener(this);
        mBtnReset.setOnClickListener(this);
        mBtnGrey.setOnClickListener(this);
        mBtnReversal.setOnClickListener(this);
        mBtnOld.setOnClickListener(this);

        mGrid.post(new Runnable() {
            @Override
            public void run() {
                // Get width and height information
                mEtWidth = mGrid.getWidth() / 5;
                mEtHeight = mGrid.getHeight() / 4;
                addEts();
                initMatrix();
            }
        });
    }

    private void initSomethingMatirx() {
        mGreyMatrix = 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};

        mReversalMatrix = new float[]{
                -1,0,0,1,1,
                0,-1,0,1,1,
                0,0,-1,1,1,
                0,0,0,1,0
        };

        mOldMatrix = 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
        };
    }

    // Add EditText
    private void addEts() {
        for (int i = 0; i < 20; i++) {
            EditText editText = new EditText(ColorMatrixActivity.this);
            mEts[i] = editText;
            mGrid.addView(editText, mEtWidth, mEtHeight);
        }
    }

    // Initialize color matrix to initial state
    private void initMatrix() {
        for (int i = 0; i < 20; i++) {
            if (i % 6 == 0) {
                mEts[i].setText(String.valueOf(1));
            } else {
                mEts[i].setText(String.valueOf(0));
            }
        }
    }

    // Get matrix value
    private void getMatrix() {
        for (int i = 0; i < 20; i++) {
            mColorMatrix[i] = Float.valueOf(mEts[i].getText().toString());
        }
    }

    // Set matrix value to image
    private void setImgMatrix() {
        Bitmap curBitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), Config.ARGB_8888);
        ColorMatrix colorMatrix = new ColorMatrix();
        colorMatrix.set(mColorMatrix);

        Canvas canvas = new Canvas(curBitmap);
        Paint paint = new Paint();
        paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
        canvas.drawBitmap(mBitmap, 0, 0, paint);

        mImg.setImageBitmap(curBitmap);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.use_color:
            getMatrix();
            setImgMatrix();
            break;
        case R.id.reset_color:
            initMatrix();
            getMatrix();
            setImgMatrix();
            break;
        case R.id.grey_color:
            mColorMatrix = mGreyMatrix;
            setImgMatrix();
            break;
        case R.id.reversal_color:
            mColorMatrix = mReversalMatrix;
            setImgMatrix();
            break;
        case R.id.old_color:
            mColorMatrix = mOldMatrix;
            setImgMatrix();
            break;
        default:
            break;
        }
    }
}

Posted by kath421 on Sun, 03 May 2020 06:03:59 -0700