ColorFilter初探一

8972 ワード

MaskFilterは1つのPaintのalphaチャネルへの変換であり、ColorFilterはRGBチャネルごとに変換を適用する.ColorFilterから派生したすべてのクラスは、変換を実行するときにalphaチャネルを無視します.
Androidには3つのColorFilterが含まれています.
ColorMatrixColorFilterは4を指定できます.×5のColorMatrixを1つのPaintに適用します.ColorMatrixesは、通常、プログラムで画像を処理するために使用され、マトリクス乗算法を使用してリンク変換を実行することをサポートするため、便利です.
LightingColorFilterに1色目のRGBチャネルを乗算し、2色目を加算します.各変換の結果は0~255に制限されます.
PorterDuffColorFilterは、デジタル画像合成の16のPorter-Duffルールのいずれかを使用して、指定された色をペイントに適用することができる.
ColorMatrixColorFilter:
ColorMatrix mColorMatrix = new ColorMatrix(new float[]{
                        .5f, 0, 0, 0, 0,
                        0, .5f, 0, 0, 0,
                        0, 0, .5f, 0, 0,
                        0, 0, 0, 1, 0,
                });
                drawable.setColorFilter(new ColorMatrixColorFilter(mColorMatrix));
LightingColorFilter:
drawable.setColorFilter(new LightingColorFilter(0xffff0000, 0xff00ff00));
PorterDuffCOlorFilter
drawable.setColorFilter(new PorterDuffColorFilter(0xffff0000, PorterDuff.Mode.ADD));
次にPorterDuffColorFilterについて重点的に説明します
1.PorterDuff.Mode.CLEARの描画はキャンバスにコミットされません.2.PorterDuff.Mode.SRCは、上位ペイント画像3を表示する.PorterDuff.Mode.DSTは、下層描画画像4を表示する.PorterDuff.Mode.SRC_MOVERは正常に描画表示され、上下層に重ね蓋が描画されます.5.PorterDuff.Mode.DST_MOVER上下に表示されます.下の段が上に表示されます.6.PorterDuff.Mode.SRC_INは2つのレイヤーで交差を描画します.上位レベルを表示します.7.PorterDuff.Mode.DST_INは2つのレイヤーで交差を描画します.下位レベルを表示します.8.PorterDuff.Mode.SRC_OUT上段描画非交差部分を取ります.9.PorterDuff.Mode.DST_OUT下に非交差部分を描画します.10.PorterDuff.Mode.SRC_ATOPは、下層の非交差部分と上層の交差部分11をとる.PorterDuff.Mode.DST_ATOPは、上層の非交差部分と下層の交差部分12をとる.PorterDuff.Mode.XORは2つのレイヤーを取って非交差を描画します.2つのレイヤが交差しないように描画します.13.PorterDuff.Mode.DARKENの上下に表示されます.暗くなる.PorterDuff.Mode.LIGHTENの上下に表示されます.変数15.PorterDuff.Mode.MULTIPLYは、2層の描画交差16をとる.PorterDuff.Mode.SCREENの上下に表示されます.
コードは次のとおりです.
public class Xfermodes extends AppCompatActivity {
    private static final Xfermode[] sModes = {
            new PorterDuffXfermode(PorterDuff.Mode.CLEAR),/** [0, 0] */
            new PorterDuffXfermode(PorterDuff.Mode.SRC),/** [Sa, Sc] */ //  
            new PorterDuffXfermode(PorterDuff.Mode.DST),/** [Da, Dc] */ //   
            new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER), /** [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] */ //     
            new PorterDuffXfermode(PorterDuff.Mode.DST_OVER),/** [Sa + (1 - Sa)*Da, Rc = Dc + (1 - Da)*Sc] */ //      
            new PorterDuffXfermode(PorterDuff.Mode.DST_IN),/** [Sa * Da, Sc * Da] */ //      ,       
            new PorterDuffXfermode(PorterDuff.Mode.SRC_IN), /** [Sa * Da, Sc * Da] */ //      ,      
            new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT),/** [Sa * (1 - Da), Sc * (1 - Da)] */ //    (       )
            new PorterDuffXfermode(PorterDuff.Mode.DST_OUT),/** [Da * (1 - Sa), Dc * (1 - Sa)] */ //     (       )
            new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP),/** [Da, Sc * Da + (1 - Sa) * Dc] */ //         ,           
            new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP), /** [Sa, Sa * Dc + Sc * (1 - Da)] */ //          ,          
            new PorterDuffXfermode(PorterDuff.Mode.XOR),/** [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] */ //           
            new PorterDuffXfermode(PorterDuff.Mode.DARKEN),/** [Sa + Da - Sa*Da,Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)] */ //   ,       
            new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN), /** [Sa + Da - Sa*Da,Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)] */ //   ,       
            new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY),/** [Sa * Da, Sc * Dc] */ //        
            new PorterDuffXfermode(PorterDuff.Mode.SCREEN), /** [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] */ //   ,          
            new PorterDuffXfermode(PorterDuff.Mode.ADD), /** Saturate(S + D) */ //         
            new PorterDuffXfermode(PorterDuff.Mode.OVERLAY) /** Saturate(S + D) */ //  ,
    };

    private static final String[] sLabels = {
            "Clear", "Src", "Dst", "SrcOver",
            "DstOver", "SrcIn", "DstIn", "SrcOut",
            "DstOut", "SrcATop", "DstATop", "Xor",
            "Darken", "Lighten", "Multiply", "Screen", "ADD", "OVERLAY"
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new SampleView(this));
    }

    static Bitmap makeDst(int w, int h) {
        Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bm);
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
        p.setColor(0xFFFFCC44);
        c.drawOval(new RectF(0, 0, w * 3 / 4, h * 3 / 4), p);
        return bm;
    }

    static Bitmap makeSrc(int w, int h) {
        Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bm);
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
        p.setColor(0xFF66AAFF);
        c.drawRect(w / 3, h / 3, w * 19 / 20, h * 19 / 20, p);
        return bm;
    }

    class SampleView extends View {
        private static final int ROW_MAX = 4;   // number of samples per row

        private Bitmap mSrcB;
        private Bitmap mDstB;
        private Shader mBG;     // background checker-board pattern
        private static final int W = 64;
        private static final int H = 64;

        public SampleView(Context context) {
            super(context);
            mSrcB = makeSrc(W, H);
            mDstB = makeDst(W, H);

            //        2*2   Bitmap,           ,tips:       width*height      
            /*
                extend:
                      Bitmap.Config.ALPHA_8  Alpha 8   
                      Bitmap.Config.ARGB_4444   4 4    16 
                      Bitmap.Config.ARGB_8888   4 8    32 
                      Bitmap.Config.RGB_565  R 5 ,G 6 ,B 5  16 
                                    ,         
             */
            Bitmap bm = Bitmap.createBitmap(new int[]{0xFFFFFFFF, 0xFFCCCCCC,
                            0xFFCCCCCC, 0xFFFFFFFF}, 2, 2,
                    Bitmap.Config.RGB_565);

            //       ,   x、y     
            mBG = new BitmapShader(bm,
                    Shader.TileMode.REPEAT,
                    Shader.TileMode.REPEAT);
            Matrix m = new Matrix();
            //    ,      6 
            m.setScale(6, 6);
            mBG.setLocalMatrix(m);//  BitmapShader     
        }


        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawColor(Color.GREEN);
            Paint labelP = new Paint(Paint.ANTI_ALIAS_FLAG);//   
            labelP.setTextAlign(Paint.Align.CENTER);

            Paint paint = new Paint();
            paint.setFilterBitmap(false);//          。

            canvas.translate(15, 35);
            int x = 0;
            int y = 0;

            for (int i = 0; i < sModes.length; i++) {
                paint.setStyle(Paint.Style.STROKE);
                paint.setShader(null);//     
                canvas.drawRect(x - 0.5f, y - 0.5f,
                        x + W + 0.5f, y + H + 0.5f, paint);

                //draw the checker-board pattern
                paint.setStyle(Paint.Style.FILL);
                paint.setShader(mBG);
                canvas.drawRect(x, y, x + W, y + H, paint);

                //      ,              
                int sc = canvas.saveLayer(x, y, x + W, y + H, null,
                        Canvas.MATRIX_SAVE_FLAG |
                                Canvas.CLIP_SAVE_FLAG |
                                Canvas.HAS_ALPHA_LAYER_SAVE_FLAG |
                                Canvas.FULL_COLOR_LAYER_SAVE_FLAG |
                                Canvas.CLIP_TO_LAYER_SAVE_FLAG);

                canvas.translate(x, y);
                canvas.drawBitmap(mDstB, 0, 0, paint);
                paint.setXfermode(sModes[i]);

                canvas.drawBitmap(mSrcB, 0, 0, paint);
                paint.setXfermode(null);
                canvas.restoreToCount(sc);

                //    
                canvas.drawText(sLabels[i],
                        x + W / 2, y - labelP.getTextSize() / 2, labelP);

                x += W + 10;

                // wrap around when we've drawn enough for one row
                if ((i % ROW_MAX) == ROW_MAX - 1) {
                    x = 0;
                    y += H + 30;
                }
            }
        }
    }
}
以上がAPIDemoのコードであり、カスタムViewは使用されない場合が多い
iv = (ImageView) findViewById(R.id.iv);
iv.getDrawable().setColorFilter(new PorterDuffColorFilter(0xffff0000, PorterDuff.Mode.ADD));
API 21以上で使用可能
iv.getDrawable().setTint(0xffff0000);
iv.getDrawable().setTintMode(PorterDuff.Mode.MULTIPLY);