高級UI-濾鏡和顏色通道

濾鏡在圖片處理裏面有不少的運用,尤爲是相機使用了大量的濾鏡,經過對顏色通道的調和,能夠呈現出各類各樣的效果html

對圖像進行必定的過濾加工處理,使用Paint設置濾鏡效果
不少高級UI使用時候須要關閉硬件加速,不關閉的話,有些API沒法支持java

Alpha濾鏡處理

MaskFilter處理類
paint.setMaskFilter(maskfilter)
如下兩種處理基於下面的初始化web

//關閉硬件加速
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);

模糊遮罩濾鏡(BlurMaskFilter類)

構造函數原型canvas

public BlurMaskFilter(float radius, Blur style)

使用例子數組

paint.setMaskFilter(new BlurMaskFilter(20, BlurMaskFilter.Blur.NORMAL));
RectF rectF = new RectF(100, 100, 200, 200);
canvas.drawRect(rectF, paint);
canvas.drawBitmap(bitmap, 400, 100, paint);

設置參數是,有四個參數:NORMAL,INNER,OUTER,SOLID
其參數效果以下
濾鏡和顏色通道-BlurMaskFilterapp

浮雕遮罩濾鏡(EmbossMaskFilter類)

其構造函數原型爲ide

public EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius)

direction:指定長度爲xxx的數組標量[x,y,z],用來指定光源的位置
ambient:指定周邊背景光源(0~1)
specular:指鏡面反射係數
blurRadius:指定模糊半徑
使用例子svg

float[] direction = {100, 100, 100};
paint.setMaskFilter(new EmbossMaskFilter(direction, 0.6F, 8, 20));
rectF = new RectF(100, 100, 300, 300);
canvas.drawRect(rectF, paint);
canvas.drawBitmap(bitmap, 500, 100, paint);

獲得的效果以下圖所示
濾鏡和顏色通道-EmbossMaskFilter函數

顏色RGB的濾鏡處理

ColorMatrix處理類
濾鏡的全部處理效果都是經過顏色矩陣的變換實現的。
好比:美顏相機實現的特效(高光、復古、黑白)
關於RGB濾鏡處理是基於矩陣變換的,那麼色彩信息矩陣是怎麼表示的呢
四階表示
濾鏡和顏色通道-色彩信息四階矩陣
若是想將色彩(0,255,0,255)更改成半透明時,可使用下面的的矩陣運算來表示
濾鏡和顏色通道-半透明
而在真正的運算時,採用的是五階矩陣
考慮下面這個變換:
一、紅色份量值更改成原來的2倍;
二、綠色份量增長100;
則使用4階矩陣的乘法沒法實現,因此,應該在四階色彩變換矩陣上增長一個"啞元座標",來實現所列的矩陣運算:
濾鏡和顏色通道-五階矩陣運算
這個矩陣中,份量值用的是100
例如提取顏色,這裏只顯示綠色和透明度spa

public class RGBFliterView extends View {
    private RectF rectF;

    public RGBFliterView(Context context) {
        super(context);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //關閉硬件加速
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        Paint paint = new Paint();
        paint.setColor(Color.argb(200,200,200,200));
        paint.setAntiAlias(true);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);
        //過濾前
        rectF = new RectF(100, 100, 300, 300);
        canvas.drawRect(rectF, paint);
        canvas.drawBitmap(bitmap, 500, 100, paint);
        //這個矩陣表明要提出綠色和透明度
        ColorMatrix matrix = new ColorMatrix(new float[]{
                0, 0, 0, 0, 0,
                0, 1, 0, 0, 0,
                0, 0, 0, 0, 0,
                0, 0, 0, 1, 0
        });
        //設置顏色過濾器
        paint.setColorFilter(new ColorMatrixColorFilter(matrix));
        //過濾後
        rectF = new RectF(100, 600, 300, 800);
        canvas.drawRect(rectF, paint);
        canvas.drawBitmap(bitmap, 500, 600, paint);
    }
}

獲得的效果圖以下
濾鏡和顏色通道-RGB過濾

常見的色彩處理有這樣一些運用

  1. 色彩的平移運算(加法運算)
  2. 色彩的縮放運算(乘法運算)

顏色加強:
[ 1.2 F 0 0 0 0 0 1.2 F 0 0 0 0 0 1.2 F 0 0 0 0 0 1 0 ] \begin{bmatrix} 1.2F & 0 & 0 & 0 & 0 \\\\ 0 & 1.2F & 0 & 0 & 0 \\\\ 0 & 0 & 1.2F & 0 & 0 \\\\ 0 & 0 & 0 & 1 & 0 \end{bmatrix}

反相效果:
[ 1 0 0 0 255 0 1 0 0 255 0 0 1 0 255 0 0 0 1 0 ] \begin{bmatrix} -1 & 0 & 0 & 0 & 255 \\\\ 0 & -1 & 0 & 0 & 255 \\\\ 0 & 0 & -1 & 0 & 255 \\\\ 0 & 0 & 0 & 1 & 0 \end{bmatrix}

黑白效果(R+G+B=1):
去色原理:只要把RGB三通道的色彩信息設置成同樣;即:R=G=B,那麼圖像就變成了灰色,而且,爲了保證圖像亮度不變,同一個通道中的R+G+B=1:如:0.213+0.715+0.072=1; RGB=0.213, 0.715, 0.072;三個數字是根據色彩光波頻率及色彩心理學計算出來的
[ 0.213 F 0.715 F 0.072 F 0 0 0.213 F 0.715 F 0.072 F 0 0 0.213 F 0.715 F 0.072 F 0 0 0 0 0 1 0 ] \begin{bmatrix} 0.213F & 0.715F & 0.072F & 0 & 0 \\\\ 0.213F & 0.715F & 0.072F & 0 & 0 \\\\ 0.213F & 0.715F & 0.072F & 0 & 0 \\\\ 0 & 0 & 0 & 1 & 0 \end{bmatrix}

髮色效果(好比紅色和綠色交換,把第一行和第二行交換):
[ 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 ] \begin{bmatrix} 0 & 1 & 0 & 0 & 0 \\\\ 1 & 0 & 0 & 0 & 0 \\\\ 0 & 0 & 1 & 0 & 0 \\\\ 0 & 0 & 0 & 1 & 0 \end{bmatrix}

復古風格:
[ 1 / 2 F 1 / 2 F 1 / 2 F 0 0 1 / 3 F 1 / 3 F 1 / 3 F 0 0 1 / 4 F 1 / 4 F 1 / 4 F 0 0 0 0 0 1 0 ] \begin{bmatrix} 1/2F & 1/2F & 1/2F & 0 & 0 \\\\ 1/3F & 1/3F & 1/3F & 0 & 0 \\\\ 1/4F & 1/4F & 1/4F & 0 & 0 \\\\ 0 & 0 & 0 & 1 & 0 \end{bmatrix}
以上是使用矩陣本身去變換,但在實際中仍是有一些可用的API的
此時使用的話,按照以下方法使用

ColorMatrix matrix = new ColorMatrix();
matrix.set(src)

有能夠直接使用的方法

  • 設置色彩的縮放函數
matrix.setScale(1.2F, 1.2F, 1.2F, 1);
  • 設置飽和度,飽和度設置(1,是原來不變;0灰色;>1增長飽和度)
matrix.setSaturation(value);`
  • 色彩旋轉函數
//axis,表明繞哪個軸旋轉,0,1,2 (0紅色軸,1綠色,2藍色)
//degrees:旋轉的度數
matrix.setRotate(axis, degrees);
  • ColorFilter使用的子類 ColorMatrixColorFilter:色彩矩陣的顏色過濾器 LightingColorFilter(mul, add):過濾顏色和加強色彩的方法(光照顏色過濾器) PorterDuffColorFilter(color, mode):圖形混合濾鏡,Mode模式與Xfermode一致
相關文章
相關標籤/搜索