所以我試圖加快我們正在做的一些繪圖(繪製一部分帶alpha透明度的圓弧),並試圖將整個圓弧緩存到一個單獨的位圖中,並顯示它有選擇地使用alpha蒙版。PorterDuffXfermode DST_IN不按預期工作
從研究,我已經做了(針對Android,this example的Xfermodes API演示和this tool),如果我有例如下面的兩個圖形:
和使用以下繪製:
Xfermode DST_IN = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
canvas.drawBitmap(circle, 0, 0, paint);
paint.setXfermode(DST_IN);
canvas.drawBitmap(arc, 0, 0, paint);
paint.setXfermode(null);
我應該得到這個結果:
當目標圖像(圓)被夾到其中源圖像(電弧)的繪製的區域。相反,我得到了整個圈子。如果我只是繪製圓弧,它會出現在正確的位置,如果我使用DST_OUT,則會得到預期結果(圓圈的其他三個象限)的倒數。
我也確保禁用此視圖的硬件渲染,以防Xfermode出現問題,但這並沒有什麼區別。
我打破了它到一個單獨的項目在試圖得到它的工作,並使用下面的代碼最簡單的層面,我還是有同樣的問題:
public class ClippedView extends View {
private Xfermode DST_IN, DST_OUT;
private Paint paint;
public ClippedView(Context context) {
super(context);
init();
}
private void init() {
setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
DST_IN = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
DST_OUT = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.GREEN);
canvas.drawRect(0, 0, getWidth()/2, getHeight()/2, paint);
paint.setColor(Color.BLACK);
paint.setXfermode(DST_IN);
canvas.drawCircle(getWidth()/2, getHeight()/2, getWidth()/2, paint);
paint.setXfermode(null);
}
}
我使用它錯了嗎?我只是想念一些東西?我發現了一個錯誤? :)
謝謝!我沒有意識到onDraw畫布包含窗口背景 - 這使得發生的事情變得更有意義。我使用位圖路徑,因爲沒有簡單的方法將閉合的圓弧繪製爲路徑,然後在clipPath()中使用它。除非你有其他建議,否則我會找到一條自己繪製路徑的路線? – kcoppock
我有一個視圖,我需要刷新每1/25秒。每次創建一個新的透明'Bitmap',然後使用'PotterDuff.Mode',就會花費我大量的FPS和內存,所以這種方法會失敗。我嘗試在屏幕上繪圖(onDraw()提供'Canvas'),但問題是每個PotterDuff.Mode.CLEAR都會使我的Canvas變黑而不是透明(沒有綁定到'Canvas'的'Bitmap') 。所以我明白問題是「目的地已經被窗口背景填充了」?那麼如何用透明背景和PotterDuff.Mode.SRC_IN創建一個快速刷新的視圖?什麼意思是「它會在層中工作」? – cadavre
不要每次創建一個新的位圖,重新使用它。 –