PorterduffXfermode:清除的位图的部分 [英] PorterduffXfermode: Clear a section of a bitmap

查看:200
本文介绍了PorterduffXfermode:清除的位图的部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的目标很简单,就是画一个位图,在它的顶部绘制形状的擦除位图的潜在区域。

The goal is simply to draw a bitmap and over the top of it draw shapes that ERASE the underlying area of the bitmap.

我创建理念code简单的证明,试图了解我到底如何去了解这一点。在这里的各个线程我发现关于使用多种提示:

I have created simple proof of concept code to try and understand how exactly I should go about this. In the various threads here I have found numerous hints about using:

android.graphics.PorterDuff.Mode.CLEAR

下面简单的code创建一个具有蓝色背景的画面,并增加了一个自定义视图。这个观点来自其画布上一个粉红色的背景,位图图像(有轻微的边框,显示粉红色的背景),和黄色叠加界重新presenting每个PorterDuffXfermode。

The code below simply creates a screen with a blue background and adds a custom view. This view draws on its canvas a pink background, the bitmap image (with a slight border to show the pink background), and yellow overlaying circles representing each PorterDuffXfermode.

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.graphics.Paint.Style;
import android.graphics.PorterDuff.Mode;
import android.graphics.RectF;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.RelativeLayout;

public class Test extends Activity {
    Drawing d = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        RelativeLayout.LayoutParams rlp = null;

        // Create the view for the xfermode test
        d = new Drawing(this);
        rlp = new RelativeLayout.LayoutParams(600, 900);
        rlp.addRule(RelativeLayout.CENTER_IN_PARENT);
        d.setLayoutParams(rlp);

        RelativeLayout rl = new RelativeLayout(this);
        rl.setBackgroundColor(Color.rgb(0, 0, 255));
        rl.addView(d);

        // Show the layout with the test view
        setContentView(rl);
    }

    public class Drawing extends View {
        Paint[] pDraw = null;
        Bitmap bm = null;

        public Drawing(Context ct) {
            super(ct);

            // Generate bitmap used for background
            bm = BitmapFactory.decodeFile("mnt/sdcard/Pictures/test.jpg");

            // Generate array of paints
            pDraw = new Paint[16];

            for (int i = 0; i<pDraw.length; i++) {
                pDraw[i] = new Paint();
                pDraw[i].setARGB(255, 255, 255, 0);
                pDraw[i].setStrokeWidth(20);
                pDraw[i].setStyle(Style.FILL);
            }

            // Set all transfer modes
            pDraw[0].setXfermode(new PorterDuffXfermode(Mode.CLEAR));
            pDraw[1].setXfermode(new PorterDuffXfermode(Mode.DARKEN));
            pDraw[2].setXfermode(new PorterDuffXfermode(Mode.DST));
            pDraw[3].setXfermode(new PorterDuffXfermode(Mode.DST_ATOP));
            pDraw[4].setXfermode(new PorterDuffXfermode(Mode.DST_IN));
            pDraw[5].setXfermode(new PorterDuffXfermode(Mode.DST_OUT));
            pDraw[6].setXfermode(new PorterDuffXfermode(Mode.DST_OVER));
            pDraw[7].setXfermode(new PorterDuffXfermode(Mode.LIGHTEN));
            pDraw[8].setXfermode(new PorterDuffXfermode(Mode.MULTIPLY));
            pDraw[9].setXfermode(new PorterDuffXfermode(Mode.SCREEN));
            pDraw[10].setXfermode(new PorterDuffXfermode(Mode.SRC));
            pDraw[11].setXfermode(new PorterDuffXfermode(Mode.SRC_ATOP));
            pDraw[12].setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
            pDraw[13].setXfermode(new PorterDuffXfermode(Mode.SRC_OUT));
            pDraw[14].setXfermode(new PorterDuffXfermode(Mode.SRC_OVER));
            pDraw[15].setXfermode(new PorterDuffXfermode(Mode.XOR));
        }

        @Override
        public void onDraw(Canvas canv) {
            // Background colour for canvas
            canv.drawColor(Color.argb(255, 255, 0, 255));

            // Draw the bitmap leaving small outside border to see background
            canv.drawBitmap(bm, null, new RectF(15, 15, getMeasuredWidth() - 15, getMeasuredHeight() - 15), null);

            float w, h;
            w = getMeasuredWidth();
            h = getMeasuredHeight();

            // Loop, draws 4 circles per row, in 4 rows on top of bitmap
            // Drawn in the order of pDraw (alphabetical)
            for(int i = 0; i<4; i++) {
                for(int ii = 0; ii<4; ii++) {
                    canv.drawCircle((w / 8) * (ii * 2 + 1), (h / 8) * (i * 2 + 1), w / 8 * 0.8f, pDraw[i*4 + ii]);
                }
            }
        }
    }

}

这是测试的结果:

CLEAR模式是左上方,它显示为黑色。

The CLEAR mode is the top left, which shows as black.

在另一个例子中,我试图用这个,我有一个DialogFragment,其中CLEAR模式擦除整个DialogFragment这样的活动之下可以看出。因此,我之所以在该试验中使用了许多不同的背景色。

In another example where I was trying to use this I had a DialogFragment where CLEAR mode erased the entire DialogFragment so that the activity beneath could be seen. Hence the reason I used many different background colours in this test.

难道这可能被清除像其他的例子中,整个活动的像素使我相信?我会一直以为只有帆布与视图的像素能够被擦除,但在我的其他例如自定义视图的像素,基本图像查看和DialogFragment背景都被清除。

Could this possibly be clearing the pixels of the entire activity like that other example led me to believe? I would've thought only the pixels of canvas related to the view could be erased, but in my other example the pixels of the custom view, underlying image view and DialogFragment background were all cleared.

可能有人请帮助我理解到底是怎么回事,为什么我会这么可怕的错误?

Could someone please help me understand what exactly is going on and why I am going so terribly wrong?

感谢。

编辑: 我已复制,确认了我的怀疑的一个例子。当加入这种精确定制视图,但在一个DialogFragment,底层活动变得可见。

I have reproduced an example that confirms my suspicions. When adding this exact custom view, but in a DialogFragment, the underlying activity becomes visible.

这似乎是一个pretty的明确的指标对我来说, Mode.CLEAR 以某种方式擦除下方以及意见的印刷品吗?我的猜测是黑色的第一个例子是顶层观点?

This seems a pretty clear indicator to me that the Mode.CLEAR is somehow erasing the canvas of the views underneath as well? My guess would be the black in the first example is that of the top level view?

我想我做的事情非常错误的地方:•

I am thinking I am doing something very wrong somewhere :S

推荐答案

现在的问题是硬件加速。关闭它,你的画有明确的特殊景观。如果您使用的是自定义视图,为此在构造函数:

The problem is hardware acceleration. Turn it OFF for the particular View that you are painting with CLEAR. If you're using a custom view, do this in the constructors:

if (android.os.Build.VERSION.SDK_INT >= 11) 
{
     setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

您也可以拨打setLayerType在视图上的参考。

You can also call setLayerType on a view reference.

这篇关于PorterduffXfermode:清除的位图的部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆