目標僅僅是繪製位圖並在其上方繪製刪除位圖底層區域的形狀。PorterduffXfermode:清除位圖的一部分
我已經創建了概念代碼的簡單證明,試圖理解我應該如何去做這件事。在這裏的各個線程我發現無數的提示如何使用:
android.graphics.PorterDuff.Mode.CLEAR
下面的代碼只是創建一個具有藍色背景的屏幕並添加了一個自定義視圖。該視圖在其畫布上繪製了一個粉紅色背景,位圖圖像(帶有輕微邊框以顯示粉紅色背景),以及黃色覆蓋圓圈表示每個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]);
}
}
}
}
}
這是試驗的結果:
清澈模式是左上角,其示出爲黑色。
在另一個我試圖使用它的例子中,我有一個DialogFragment,其中CLEAR模式擦除了整個DialogFragment,這樣可以看到下面的活動。因此,我在這個測試中使用了許多不同背景顏色的原因。
難道這可能是清除整個活動像素像其他例子讓我相信嗎?我會認爲只有與視圖相關的畫布像素可以被擦除,但在另一個例子中,自定義視圖,底層圖像視圖和DialogFragment背景的像素全部被清除。
有人能幫我理解究竟發生了什麼,爲什麼我會這麼糟糕嗎?
謝謝。
編輯: 我紛紛轉載,確認了我的懷疑的例子。添加此確切的自定義視圖時,但在DialogFragment中,基礎活動變爲可見。
這似乎是一個非常明確的指標,對我來說,Mode.CLEAR
以某種方式擦除的下方還有意見畫布?我的猜測是第一個例子中的黑色是頂級視圖中的黑色?
我想我做的事情很不對勁的地方:S
謝謝...讓我的一天! –
它會減慢繪畫,不是嗎? – sandrstar
這應該是被接受的答案。超級有用。謝謝! –