1. 程式人生 > >自定義View之RGB顏色變化Paint畫筆顏色過濾器setColorFilter,LightingColorFilter光照過濾器

自定義View之RGB顏色變化Paint畫筆顏色過濾器setColorFilter,LightingColorFilter光照過濾器


首先看一下效果:



通過來給RGB改變不同的值,圖片出現不同的變化,其中負值代表削弱相應的顏色,正值代表加強相應的顏色。下面給出主要步驟,下邊會貼原始碼

主要步驟:

1.建立一個類繼承自View,重寫onDraw方法

2.建立畫筆

3.下面給畫筆建立著色器:

什麼是著色器,在通常情況下,我們會給畫筆設定顏色setColor,現在我們不想給畫筆設定單一的顏色,想設定更炫酷的效果,那麼就用到Paint.setShader方法,

setShader的第二個引數是模式,我們這裡使用鏡面模式(還有另外兩種模式),當然shader的種類很多,我們這裡用到BitmapShader,顧名思義是用一個Bitmao設定Paint程式碼如下:

/**
         * 初始化畫筆,抗鋸齒
         */
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        /**
         * 建立bitmap物件
         */
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.nbaba);
        /**
         *為畫筆設定著色器
         */
        mPaint.setShader(new BitmapShader(bitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR));
4.根據seekBar的變化給畫筆paint設定顏色過濾器,不同的過濾器渲染了不同的顏色效果核心程式碼如下:

/**
     * 過濾器物件
     */
    private LightingColorFilter lightingColorFilter;
mPaint.setColorFilter(lightingColorFilter);
那麼建立LightingColorFilter的引數是什麼呢?我們不妨看一下原始碼的解釋:

/**
     * Create a colorfilter that multiplies the RGB channels by one color,
     * and then adds a second color. The alpha components of the mul and add
     * arguments are ignored.
     */
    public LightingColorFilter(@ColorInt int mul, @ColorInt int add) {
        mMul = mul;
        mAdd = add;
    }
大致意思如下:建立一個顏色過濾器,乘以一個顏色,加上一個顏色,引數的透明度被忽略。怎麼理解,第一個引數mul決定相應顏色被削弱的程度,第二個函式add決定了相應顏色的加深程度,如果乘以0x00ffff,那麼紅色被完全削弱,加上0xff0000那麼紅色被加強最深。

下面是完整程式碼:

MainActivity.java

package com.example.zqd.rgbchanged;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener {

    private SeekBar sb_r;
    private SeekBar sb_g;
    private SeekBar sb_b;
    private TextView tv_r;
    private TextView tv_g;
    private TextView tv_b;
    private PictureView pv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        sb_r.setOnSeekBarChangeListener(this);
        sb_g.setOnSeekBarChangeListener(this);
        sb_b.setOnSeekBarChangeListener(this);
    }

    private void initView() {
        pv = (PictureView) findViewById(R.id.pv);
        sb_r = (SeekBar) findViewById(R.id.sb_r);
        sb_g = (SeekBar) findViewById(R.id.sb_g);
        sb_b = (SeekBar) findViewById(R.id.sb_b);
        tv_r = (TextView) findViewById(R.id.tv_r);
        tv_g = (TextView) findViewById(R.id.tv_g);
        tv_b = (TextView) findViewById(R.id.tv_b);
        sb_r.setMax(510);
        sb_g.setMax(510);
        sb_b.setMax(510);
        sb_r.setProgress(255);
        sb_g.setProgress(255);
        sb_b.setProgress(255);
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        pv.changeRGB(sb_r.getProgress() - 255, sb_g.getProgress() - 255, sb_b.getProgress() - 255);
        switch (seekBar.getId()) {
            case R.id.sb_r:
                tv_r.setText(progress - 255 + "");
                break;
            case R.id.sb_g:
                tv_g.setText(progress - 255 + "");
                break;
            case R.id.sb_b:
                tv_b.setText(progress - 255 + "");
                break;
        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }
}
PictureView.java

package com.example.zqd.rgbchanged;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.LightingColorFilter;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by zqd on 2017/10/27.
 */

public class PictureView extends View {

    /**
     * 畫筆
     */
    private Paint mPaint;
    /**
     * 螢幕寬度
     */
    private int w;
    /**
     * 螢幕高度
     */
    private int h;
    /**
     * 過濾器物件
     */
    private LightingColorFilter lightingColorFilter;

    public PictureView(Context context) {
        super(context);
        init();
    }

    public PictureView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public PictureView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        /**
         * 得到寬高
         */
        this.w = w;
        this.h = h;
    }

    private void init() {
        /**
         * 初始化畫筆,抗鋸齒
         */
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        /**
         * 建立bitmap物件
         */
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.nbaba);
        /**
         *為畫筆設定著色器
         */
        mPaint.setShader(new BitmapShader(bitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        /**
         * 平移畫布至螢幕中心點
         */
        canvas.translate(w / 2, h / 2);
        /**
         * 畫圓
         */
        canvas.drawCircle(0, 0, 200, mPaint);
        super.onDraw(canvas);
    }

    /**
     * 獲取RGB值
     *
     * @param r
     * @param g
     * @param b
     */
    public void changeRGB(int r, int g, int b) {
        int mr = 0;
        int mg = 0;
        int mb = 0;
        int ar = 0;
        int ag = 0;
        int ab = 0;

        if (r < 0) {
            mr = r + 255;
            ar = 0;
        } else if (r == 0) {
            mr = 255;
            ar = 0;
        } else {
            mr = 255;
            ar = r;
        }

        if (g < 0) {
            mg = g + 255;
            ag = 0;
        } else if (g == 0) {
            mg = 255;
            ag = 0;
        } else {
            mg = 255;
            ag = g;
        }

        if (b < 0) {
            mb = b + 255;
            ab = 0;
        } else if (b == 0) {
            mb = 255;
            ab = 0;
        } else {
            mb = 255;
            ab = b;
        }
        lightingColorFilter = new LightingColorFilter(Integer.valueOf(transString(Integer.toHexString(mr)) + transString(Integer.toHexString(mg)) + transString(Integer.toHexString(mb)), 16),
                Integer.valueOf(transString(Integer.toHexString(ar)) + transString(Integer.toHexString(ag)) + transString(Integer.toHexString(ab)), 16));
        mPaint.setColorFilter(lightingColorFilter);
        invalidate();
    }

    /**
     * 處理RGB
     *
     * @param s
     * @return
     */
    public String transString(String s) {
        if (s.length() == 1) {
            return "0" + s;
        } else {
            return s;
        }
    }

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.zqd.rgbchanged.MainActivity">

    <com.example.zqd.rgbchanged.PictureView
        android:id="@+id/pv"
        android:layout_width="match_parent"
        android:layout_height="300dp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:paddingRight="10dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_marginRight="10dp"
                android:text="R"
                android:textSize="18sp" />

            <SeekBar
                android:id="@+id/sb_r"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="8" />

            <TextView
                android:id="@+id/tv_r"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:paddingRight="10dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_marginRight="10dp"
                android:text="G"
                android:textSize="18sp" />

            <SeekBar
                android:id="@+id/sb_g"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="8" />

            <TextView
                android:id="@+id/tv_g"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:paddingRight="10dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_marginRight="10dp"
                android:text="B"
                android:textSize="18sp" />

            <SeekBar
                android:id="@+id/sb_b"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="8" />

            <TextView
                android:id="@+id/tv_b"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center" />

        </LinearLayout>
    </LinearLayout>


</LinearLayout>