【Android】自定義View那點事(三)ColorFilter篇

前言

前面學習Xfermode的使用,我們可以自定義各種不同樣式的View,本節(jié)我們學習關于顏色處理相關的內容?,F在很多圖片處理軟件都具有濾鏡功能,選擇不同風格濾鏡可以改變圖片色彩呈現不同風格。Android開發(fā)文檔中提供了相應的API供開發(fā)者使用,這樣我們自己可以實現圖片濾鏡效果。這節(jié)我們主要講ColorMatrixColorFilter,ColorMatrixColorFilter通過ColorMatrix設置4*5的矩陣變換RGBA參數調整顏色。

色彩科普

在開始如何調整圖片顏色之前,我們先了解一下關于色彩方面的知識。Ps:理論知識來源于度娘

  • 色相

色相是色彩的首要特征,是區(qū)別各種不同色彩的最準確的標準。事實上任何黑白灰以外的顏色都有色相的屬性,而色相也就是由原色、間色和復色來構成的。色相,色彩可呈現出來的質地面貌。自然界中各個不同的色相是無限豐富的,如紫紅、銀灰、橙黃等。色相即各類色彩的相貌稱謂。

  • 色調

色調指的是一幅畫中畫面色彩的總體傾向,是大的色彩效果。這種在不同顏色的物體上,籠罩著某一種色彩,使不同顏色的物體都帶有同一色彩傾向,這樣的色彩現象就是色調。

  • 灰度

灰度使用黑色調表示物體,即用黑色為基準色,不同的飽和度的黑色來顯示圖像。 每個灰度對象都具有從 0%(白色)到100%(黑色)的亮度值。使用黑白或灰度掃描儀生成的圖像通常以灰度顯示。

  • 對比度

對比度指的是一幅圖像中明暗區(qū)域最亮的白和最暗的黑之間不同亮度層級的測量,差異范圍越大代表對比越大,差異范圍越小代表對比越小,好的對比率120:1就可容易地顯示生動、豐富的色彩,當對比率高達300:1時,便可支持各階的顏色。但對比率遭受和亮度相同的困境,現今尚無一套有效又公正的標準來衡量對比率,所以最好的辨識方式還是依靠使用者眼睛。

  • 飽和度

飽和度可定義為彩度除以明度,與彩度同樣表征彩色偏離同亮度灰色的程度。注意,與彩度完全不是同一個概念。但由于其和彩度決定的是出現在人眼里的同一個效果,所以才會出現視彩度與飽和度為同一概念的情況。

主角ColorMatrix

ColorMatrix通過設置4*5的矩陣數值改變圖片的顏色和透明度。我們來看看官方文檔的描述。No picture,say the JJ,來上圖。

Paste_Image.png

可以看到4*5矩陣每一行的運算結果分別代表RGBA的最終的數值,以及它們取值范圍在0-255之間。而每一行最后一個數值代表偏移量,例如想讓R增加100偏移量,則將矩陣數組第四個數值設置為100。
ColorMatrix的reset()方法可以看到,顏色矩陣RGBA的初始情況。

Paste_Image.png

美圖濾鏡效果

  • 原圖
Paste_Image.png
|1,0,0,0,0|
|0,1,0,0,0|
|0,0,1,0,0|
|0,0,0,1,0|
  • 泛黃矩陣
Paste_Image.png
|1,0,0,0,100|
|0,1,0,0,100|
|0,0,1,0,0|
|0,0,0,1,0|
  • 偏紅矩陣
Paste_Image.png
|2,0,0,0,0|
|0,1,0,0,0|
|0,0,1,0,0|
|0,0,0,1,0|
  • 底片矩陣
Paste_Image.png
|-1,0,0,0,255|
|0,-1,0,0,255|
|0,0,-1,0,255|
|0,0,0,1,0|

主要代碼

開發(fā)流程簡介
1.獲取圖片資源draweBitmap
2.canvasBitmap獲取draweBitmap用于創(chuàng)建畫布canvas的大小
3.ColorMatrix設置顏色矩陣,ColorMatrixColorFilter加載ColorMatrix,paint設置ColorMatrixColorFilter
4.canvas使用paint繪制draweBitmap
5.imageView加載canvasBitmap
主視圖部分

public class ColorFilterView extends LinearLayout{

 
    ImageView imageView;
    Button btnSetting;
    Bitmap draweBitmap;
    Bitmap canvasBitmap;
    Canvas canvas;
    Paint paint;
    float[] ColorMatrixFloat = new float[20];
    ColorMatrixDialog colorMatrixDialog;
    public ColorFilterView(Context context) {
        super(context);
        initView(context);
    }
    public ColorFilterView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }
    private void initView(final Context context) {
        this.setOrientation(VERTICAL);

        imageView = new ImageView(context);
        BitmapFactory.Options option = new BitmapFactory.Options();
        DisplayMetrics displayMetrics = new DisplayMetrics();
        ((Activity)context).getWindow().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        draweBitmap = Utils.CompressImage(context, R.drawable.meizi,option,displayMetrics);
        canvasBitmap = Bitmap.createBitmap(option.outWidth,option.outHeight, Bitmap.Config.ARGB_8888);
        addView(imageView);
        
        canvas = new Canvas(canvasBitmap);
        paint = new Paint();
        canvas.drawBitmap(draweBitmap,0,0,paint);
        imageView.setImageBitmap(canvasBitmap);

        btnSetting = new Button(context);
        btnSetting.setText("MatrixSeeting");
        btnSetting.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                colorMatrixDialog = new ColorMatrixDialog(context,ColorMatrixFloat);
                colorMatrixDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
                    @Override
                    public void onDismiss(DialogInterface dialog) {
                        changeMatrix(ColorMatrixFloat);
                    }
                });
                colorMatrixDialog.show();
            }
        });
        addView(btnSetting); 
    }
    private void changeMatrix(float[]  color){

        ColorMatrix colorMatrix = new ColorMatrix();
        colorMatrix.set(color);
        ColorMatrixColorFilter colorMatrixColorFilter = new ColorMatrixColorFilter(colorMatrix);
        paint.setColorFilter(colorMatrixColorFilter);
        canvas.drawBitmap(draweBitmap,0,0,paint);
        imageView.setImageBitmap(canvasBitmap);
    }

}

設置顏色矩陣Dialog

public class ColorMatrixDialog extends Dialog {

    RecyclerView recyclerView;
    List<EditText> editTextList = new ArrayList<>();
    float[] colors;
    Button btnOk;
    public ColorMatrixDialog(Context context,float[] colors) {
        super(context);
        init(context);
        this.colors = colors;
    }

    public ColorMatrixDialog(Context context, int themeResId) {
        super(context, themeResId);
        init(context);
    }
    private void init(Context context){
        LinearLayout linearLayout = new LinearLayout(context);
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        recyclerView = new RecyclerView(context);
        recyclerView.setLayoutManager(new GridLayoutManager(context,5));
        recyclerView.setAdapter(new EditextAdapter());
        linearLayout.addView(recyclerView);
        btnOk = new Button(context);
        btnOk.setText("OK");
        btnOk.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int num = 0;
                for(EditText editText : editTextList){
                    try {
                        String value = editText.getText().toString();
                        float floatValue = Float.valueOf(value);
                        colors[num] = floatValue;
                    }catch (NumberFormatException e){
                        e.printStackTrace();
                    }
                    num++;
                }
                dismiss();
            }
        });
        linearLayout.addView(btnOk);
        addContentView(linearLayout,new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
    }
    class EditextAdapter extends RecyclerView.Adapter<EditTextViewHolder>{

        @Override
        public EditTextViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            EditText editText = new EditText(parent.getContext());
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            layoutParams.weight = 1;
            editText.setLayoutParams(layoutParams);
            editText.setGravity(View.TEXT_ALIGNMENT_CENTER);
            editText.setInputType(InputType.TYPE_CLASS_NUMBER|InputType.TYPE_NUMBER_FLAG_DECIMAL|InputType.TYPE_NUMBER_FLAG_SIGNED);
            editTextList.add(editText);
            return new EditTextViewHolder(editText);
        }

        @Override
        public void onBindViewHolder(EditTextViewHolder holder, int position) {
            holder.editText.setText("0");
        }

        @Override
        public int getItemCount() {
            return 20;
        }
    }
    class EditTextViewHolder extends RecyclerView.ViewHolder{
        EditText editText;
        public EditTextViewHolder(View itemView) {
            super(itemView);
            editText = (EditText)itemView;
        }
    }
}

補充內容

除了使用顏色矩陣改變,在官方文檔中還可以看到ColorMatrix另外幾個方法

Paste_Image.png
Paste_Image.png
Paste_Image.png

這三個方法分別設置飽和度、亮度、色相。

  • 演示代碼
private void changeRGBA(){
        float R = (rSeekBar.getProgress() -127) * 1.0f /127 * 180;
        float G = gSeekBar.getProgress() * 1.0f / 127;
        float B = bSeekBar.getProgress() * 1.0f / 127;

        //色相
        ColorMatrix colorMatrixRotate = new ColorMatrix();
        colorMatrixRotate.setRotate(0,R);
        colorMatrixRotate.setRotate(1,R);
        colorMatrixRotate.setRotate(2,R);
        //飽和度
        ColorMatrix colorMatrixSaturation = new ColorMatrix();
        colorMatrixSaturation.setSaturation(G);
        //亮度
        ColorMatrix colorMatrixScale = new ColorMatrix();
        colorMatrixScale.setScale(B,B,B,1);

        ColorMatrix colorMatrix = new ColorMatrix();
        colorMatrix.postConcat(colorMatrixRotate);
        colorMatrix.postConcat(colorMatrixSaturation);
        colorMatrix.postConcat(colorMatrixScale);
        ColorMatrixColorFilter colorMatrixColorFilter = new ColorMatrixColorFilter(colorMatrix);
        paint.setColorFilter(colorMatrixColorFilter);
        canvas.drawBitmap(draweBitmap,0,0,paint);
        imageView.setImageBitmap(canvasBitmap);
    }
  • 效果展示
620019632-5815ffd94819e_articlex.gif
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容