Android paint application II porterduffxfermode

In this article, learn the layer blending mode of paint, namely mpaint.setxfermode (New porterduffxfermode (porterduff. Mode. Src_in)); 18 mixed modes are provided in porterduff. Mode

        CLEAR       (0),
        SRC         (1),
        DST         (2),
             /**注释1
         * <p>
         *     <img src="{@docRoot}reference/android/images/graphics/composite_SRC_OVER.png" />
         *     <figcaption>The source pixels are drawn over the destination pixels.</figcaption>
         * </p>
         * <p>\(\alpha_{out} = \alpha_{src} + (1 - \alpha_{src}) * \alpha_{dst}\)</p>
         * <p>\(C_{out} = C_{src} + (1 - \alpha_{src}) * C_{dst}\)</p>
         */
        SRC_OVER    (3),
        DST_OVER    (4),
        SRC_IN      (5),
        DST_IN      (6),
        SRC_OUT     (7),
        DST_OUT     (8),
        SRC_ATOP    (9),      
        DST_ATOP    (10),
        XOR         (11),
        DARKEN      (16),
        LIGHTEN     (17),
        MULTIPLY    (13),
        SCREEN      (14),
        ADD         (12),
        OVERLAY     (15);

Invalid Sign

So how do these 18 modes mix? Here are two points to note, that is, the area of SRC source image and the area of DST target image. The layer mixing mode acts on the area where they intersect, and the effect of layer mixing mode acts on the area of SRC source image, The graphics drawn by porterduff.mode.clear will not be submitted to the canvas. Porterduff.mode.src displays the upper graphics porterduff.mode.dst displays the lower graphics porterduff.mode.src_ Over is drawn normally, and the upper and lower layers are drawn with overlapping porterduff.mode.dst_ Over is drawn normally, and the lower layer is porterduff.mode.src_ In takes the intersection area of two layers and displays the upper porterduff.mode.dst_ In takes the intersection area of two layers and displays the lower porterduff.mode.src_ Out draws the non intersecting part of the upper layer, and the intersecting part is transparent porterduff.mode.dst_ Out draws the non intersecting part of the lower layer, and the intersecting part is transparent porterduff.mode.src_ Atop draws the upper intersection part and the lower non intersection part porterduff.mode.dst_ Atop draws the intersection part of the lower layer and the non intersection part of the upper layer. Porterduff.mode.xor removes the intersection area of the upper and lower layers, and draws the non intersection area. Porterduff.mode.darken draws all the areas of the upper and lower layers. The color of the intersection part is deepened. Porterduff.mode.lighten draws all the areas of the upper and lower layers, and the color of the intersection part is lit. Porterduff.mode.multiple draws the intersection area, The colors of the intersection part are superimposed on porterduff.mode.screen to draw all the areas of the upper and lower layers, the filter colors of the intersection part are superimposed on porterduff.mode.add to draw all the areas of the upper and lower layers, the saturation of the intersection part is added on porterduff.mode.overlay to draw all the areas of the upper and lower layers, and the intersection part is superimposed to see the effect map

  @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.WHITE);

        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;
        //sModes 图层混合集合
        for (int i = 0; i < sModes.length; i++) {
            // draw the border
            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);
            int sc = canvas.saveLayer(x, y, x + W, y + H, null, Canvas.ALL_SAVE_FLAG);
            canvas.translate(x, y);
            canvas.drawBitmap(makeDst(2 * W / 3, 2 * H / 3), 0, 0, paint);
            paint.setXfermode(sModes[i]);
            canvas.drawBitmap(makeSrc(2 * W / 3, 2 * H / 3), W / 3, H / 3, paint);
            paint.setXfermode(null);
            canvas.restoreToCount(sc);

            // draw the label
            labelP.setTextSize(20);
            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;
            }
        }
    }
        // 画圆一个完成的圆
    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, h), p);
        return bm;
    }

    // create a bitmap with a rect, used for the "src" image
    // 矩形右下角留有透明间隙
    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(0, 0, w * 19 / 20, h * 19 / 20, p);
        return bm;
    }

A diagram is used to illustrate the drawing area of the above code

The red area represents the drawn SRC image, and the gray is the drawn area of the DST image. A green circle is drawn in this area, that is, the DST image. The intersection area of the two is the yellow part

Let's take a look at the layer blending example provided by Google

 // create a bitmap with a circle, used for the "dst" image
    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;
    }

    // create a bitmap with a rect, used for the "src" image
    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;
    }

Whether it is SRC image or DST image, the drawing area of the two images fills the whole area, because the drawing areas of the two images are different, resulting in different effects after calling the layer mixing mode.

Here we use porterduff.mode.dst_ Take atop as an example, the lower layer represents the circle in the effect drawing, and the upper layer represents the box, which represents drawing the intersection part of the lower layer and the non intersection part of the upper layer. In the first effect drawing, draw the intersection part of the lower layer, that is, the intersection part of the yellow circle and the blue box, and then draw the non intersection part of the upper layer. Because the intersection area drawn by the two is only the pink part in the drawing, The layer blending mode only works on SRC, that is, the blue box, so the first effect appears

In Google's demo code, the drawing areas of the upper and lower layers are different, DST_ Atop draws the intersection part of the lower layer and the non intersection part of the upper layer, that is, it draws the circle of the intersection part and then draws the box of the non intersection part, so the second effect appears

In layer rendering, there are several points to note: 1) the first one is called DST, that is, the lower level image, after which it is called SRC, that is, the upper image 2. Before drawing, that is, before using the layer blending mode, we first call canvas.saveLayer to render it, then canvas.restoreToCount 3 will draw the rectangle area of SRC and DST. Different regions will have different effects. 4) if necessary, turn off the hardware acceleration setlayertype (view. Layer_type_software, null)

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>