Easy Tutorial
❮ Android Tutorial Socket Intro Verilog2 Integrated Design ❯

8.3.9 Paint API — ColorFilter (Color Filter) (1/3)

Category Android Basic Tutorial

Introduction to This Section:

>

In the previous section, we learned about MaskFilter (mask), and used its two subclasses BlurMaskFilter for a blur effect and EmbossMaskFilter for an emboss effect. In this section, we will learn about another API — ColorFilter (color filter). Like MaskFilter, we do not use this class directly but instead use its three subclasses:

Color Matrix Color Filter: ColorMatrixColorFilter

Lighting Color Filter: LightingColorFilter

Porter-Duff Color Filter: PorterDuffColorFilter

In this section, let's learn about the first one, ColorMatrixColorFilter. Open the documentation for ColorMatrixColorFilter,

It roughly says: Colors are transformed through a 4 x 5 color matrix, which can modify pixel saturation, convert YUV to RGB, etc.! The ColorMatrix in the constructor is the color matrix, which is also the core of our study, let me explain one by one!

PS: ColorMatrix API documentation


1. Popularization of Related Knowledge:

RGBA Model:

>

Have you heard of RGBA? Yellow, green, and blue are the three primary colors of light, and RGBA adds transparency on this basis! R (Red), G (Green), B (Blue), A (Alpha transparency); Also, it should be distinguished from the three primary colors of pigments, the most obvious difference is that yellow is used in the three primary colors of pigments to replace green in the three primary colors of light! Just know about it, those interested can search Baidu themselves~

Some Terms:


2. Interpretation of ColorMatrix

>

As the title suggests, a color matrix (4 * 5), we can modify the values in the matrix to achieve effects like black and white photos, yellowed old photos, high contrast, etc.! The hand-torn color matrix explanation diagram is as follows:

I don't know if you understand the above image, if you have studied calculus, you must be very familiar with this, it's nothing more than a cross product of the matrix, if you haven't studied it, it doesn't matter The calculation method is the one in the lower right corner, multiply each row of the color matrix by each column of the color matrix component!

A very typical example, the comparison of the results before and after processing, we can also let a color value * a constant, for example, let the third row (blue) multiply by 2, the effect will become blue, of course, we must write code to verify the above results!


3. Write Code to Verify the Role of ColorMatrix

>

Here is a common example, an ImageView, 4 * 5 EditTexts, a reset button, and a generate button, Let's see the effect diagram:

In order, they are the original picture, yellowed, greened, reddened, high contrast, hue transformation, and yellow retro

Next, let's write the code to achieve the above effects: Code Implementation:

First is the layout file activity_main.xml:

<?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"
    android:padding="5dp">

    <ImageView
        android:id="@+id/img_show"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2" />

    &lt;GridLayout
        android:id="@+id/gp_matrix"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="3"
        android:columnCount="5"

```java
Bitmap bmp = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(),
        Bitmap.Config.ARGB_8888);
android.graphics.ColorMatrix colorMatrix = new android.graphics.ColorMatrix();
colorMatrix.set(mColorMatrix);

Canvas canvas = new Canvas(bmp);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
canvas.drawBitmap(mBitmap, 0, 0, paint);
img_show.setImageBitmap(bmp);

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btn_Change:
            getMatrix();
            setImageMatrix();
            break;
        case R.id.btn_reset:
            initMatrix();
            getMatrix();
            setImageMatrix();
            break;
    }
}

The code is very simple; it just loads the layout and then adds 20 EditTexts into a GridLayout. The post() method is used to ensure that the GridLayout's width and height are obtained after it has been loaded, otherwise the values might not be retrieved! Then three methods are defined: initializing the matrix, getting the matrix values, and processing the image based on the matrix values. Isn't it simple?

However, you might have some doubts here:

>

"Can we only modify the color matrix to process images? It would be very troublesome to do this every time, who would remember the values that should be filled in the matrix?

Answer: There definitely are, we can look back at the documentation, and we can find several very commonly used methods: setRotate (int axis, float degrees): Set the hue

setSaturation (float sat): Set the saturation

setScale (float rScale, float gScale, float bScale, float aScale): Set the brightness

Let's try these three methods with an example!


4. Process images using the three methods of ColorMatrix

Running effect picture :

Code implementation :

First, let's write a utility class for image processing. We pass in Bitmap, hue, saturation, and brightness, and after processing, we return the processed image: ImageHelper.java :

/**
 * Created by Jay on 2015/10/28 0028.
 */
public class ImageHelper {
    /**
     * This method is used to process the image, adjust according to hue, saturation, and brightness
     *
     * @param bm: The image to be processed
     * @param hue: Hue
     * @param saturation: Saturation
     * @param lum: Brightness
     *
     */
    public static Bitmap handleImageEffect(Bitmap bm, float hue, float saturation, float lum) {
        Bitmap bmp = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bmp);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

        ColorMatrix hueMatrix = new ColorMatrix();
        hueMatrix.setRotate(0, hue);    //0 represents R, red
        hueMatrix.setRotate(1, hue);    //1 represents G, green
        hueMatrix.setRotate(2, hue);    //2 represents B, blue

        ColorMatrix saturationMatrix = new ColorMatrix();
        saturationMatrix.setSaturation(saturation);

        ColorMatrix lumMatrix = new ColorMatrix();
        lumMatrix.setScale(lum, lum, lum, 1);

        ColorMatrix imageMatrix = new ColorMatrix();
        imageMatrix.postConcat(hueMatrix);
        imageMatrix.postConcat(saturationMatrix);
        imageMatrix.postConcat(lumMatrix);

        paint.setColorFilter(new ColorMatrixColorFilter(imageMatrix));
        canvas.drawBitmap(bm, 0, 0, paint);

        return bmp;
    }
}

Next, let's create the layout as well, activity_main.xml :

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

<ImageView
        android:id="@+id/img_meizi"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="24dp"
        android:layout_marginTop="24dp" />


<TextView
        android:id="@+id/txt_hue"
        android:layout_width="wrap_content"
        android:layout_height="32dp"
        android:layout_below="@id/img_meizi"
        android:gravity="center"
        android:text="Hue    :"
        android:textSize="18sp" />

&lt;SeekBar
    android:id="@+id/sb_hue"
    android:layout

private final static int MID_VALUE = 127; private float mHue = 0.0f; private float mStauration = 1.0f; private float mLum = 1.0f; private Bitmap mBitmap;

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.img_meizi); bindViews(); }

private void bindViews() { img_meizi = (ImageView) findViewById(R.id.img_meizi); sb_hue = (SeekBar) findViewById(R.id.sb_hue); sb_saturation = (SeekBar) findViewById(R.id.sb_saturation); sb_lum = (SeekBar) findViewById(R.id.sb_lum);

img_meizi.setImageBitmap(mBitmap);
sb_hue.setMax(MAX_VALUE);
sb_hue.setProgress(MID_VALUE);
sb_saturation.setMax(MAX_VALUE);
sb_saturation.setProgress(MID_VALUE);
sb_lum.setMax(MAX_VALUE);
sb_lum.setProgress(MID_VALUE);

sb_hue.setOnSeekBarChangeListener(this);
sb_saturation.setOnSeekBarChangeListener(this);
sb_lum.setOnSeekBarChangeListener(this);

}

@Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { switch (seekBar.getId()) { case R.id.sb_hue: mHue = (progress - MID_VALUE) * 1.0F / MID_VALUE * 180; break; case R.id.sb_saturation: mStauration = progress * 1.0F / MID_VALUE; break; case R.id.sb_lum: mLum = progress * 1.0F / MID_VALUE; break; } img_meizi.setImageBitmap(ImageHelper.handleImageEffect(mBitmap, mHue, mStauration, mLum)); }

@Override public void onStartTrackingTouch(SeekBar seekBar) {}

@Override public void onStopTrackingTouch(SeekBar seekBar) {} }

The code is equally simple, so I won't explain it here~


5. Download the code sample for this section:

ColorMatrixDemo.zip

ColorMatrixDemo2.zip


Summary of this section:

>

Well, in this section, we introduced the first ColorMatrixColorFilter in ColorFilter, the color matrix filter. The core is actually the ColorMatrix. We can set the values of the 4x5 matrix ourselves when processing images, or we can directly call the methods provided by ColorMatrix to adjust hue, saturation, and brightness! Image processing is nothing more than this, and there is another way to modify the pixel points, which we will also discuss later. The content of this section refers to the video on the doctor (Xu Yisheng)'s iMooc website: Android Image Processing - Start with Meitu Xiuxiu. If you don't want to read the text, you can watch the video, which is quite well explained.

-1.0 Android Basic Tutorial

-1.0.1 2015 Latest Android Basic Tutorial Catalog

-1.1 Background and System Architecture Analysis

-1.2 Development Environment Setup

-1.2.1 Developing Android Apps with Eclipse + ADT + SDK

-1.2.2 Developing Android Apps with Android Studio

-1.3 Solving SDK Update Issues

-1.4 Genymotion Emulator Installation

-1.5.1 Git Tutorial on Basic Operations of Local Repositories

-1.5.2 Git: Using GitHub to Set Up a Remote Repository

-1.6 How to Play with 9 (Nine Sister) Images

-1.7 Interface Prototype Design

-1.8 Project-Related Analysis (Various Files, Resource Access)

-1.9 Android Program Signing and Packaging

-1.11 Decompiling APK to Obtain Code & Resources

-[2.1 The Concept of View and

-

❮ Android Tutorial Socket Intro Verilog2 Integrated Design ❯