如何为透明覆盖创建蒙版?

时间:2012-02-16 04:08:40

标签: android porter-duff

我有以下场景:用作背景的位图和另一个用作叠加的位图,可以是50%透明或不透明(在运行时可更改),第三个位图包含第二个掩码位图。我尝试了不同的Xfermodes配置和绘图订单,但无法找到合适的配置。

我正在使用掩码作为位图,因为我需要能够在两次运行程序之间或配置更改之间保存它。它是在屏幕上用户绘制时创建的,有效地清除战争迷雾

最佳尝试的代码片段。只有我希望它不起作用的是我的面具的透明度。

@Override
protected void onDraw(Canvas canvas) {      
    canvas.drawBitmap(mFogOfWar, mTransformationMatrix, mPaintFog);
    canvas.drawBitmap(mMaskBitmap, mTransformationMatrix, mPaintMask);
    canvas.drawBitmap(mImage, mTransformationMatrix, mPaintImage);
}

Paint个对象:

mPaintImage.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));
mPaintFog.setAlpha(127);
mPaintMask.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

这是我对当前配置更清楚的结果: screenshot

我不确定我是否能够在Paint对象上设置alpha;如果没有,我不介意另一个关于alpha问题的建议或解决方案,最好是不需要重新创建用作战争雾的位图。

修改

通过执行以下操作,我能够得到我想要的结果:

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(mImage, mTransformationMatrix, mPaintImage);
    if (mMaskBitmap != null) {
        canvas.drawBitmap(mFogOfWar, mTransformationMatrix, mPaintFog);
        canvas.drawBitmap(mMaskBitmap, mTransformationMatrix, mPaintMask);
        canvas.drawBitmap(mMaskBitmap, mTransformationMatrix, mPaintImage);
        canvas.drawBitmap(mImage, mTransformationMatrix, mPaintImageSecondPass);
    }

Paint对象:

mPaintImage = new Paint(); // No Xfermode here anymore
mPaintFog.setAlpha(127);
mPaintMask.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mPaintImageSecondPass.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN));

但是五次绘制位图似乎是浪费。由于Android硬件加速,我在OpenGL纹理中运行(我将位图重新调整为设备GPU接受的最高分辨率)并且我在invalidates()中非常小心,它在我的Nexus S上都运行得非常顺畅和我的A500,但我不确定其他设备(无论如何项目将是4.0+)。

但我确信必须有更好的方法来做到这一点。我想要一种避免过多透支的方法,或者至少可以正确地向我解释那些Xfermodes的含义,以及我不会透支的东西。

1 个答案:

答案 0 :(得分:5)

在尝试某种顿悟后,我尝试了一种完全不同的方法 - 并且意识到这个问题的解决方案是一种更简单的方法 - 就像通常那样。由于我只需要两个位图,因此我需要更少的内存来处理它。

绘图:

canvas.drawBitmap(mImage, mTransformationMatrix, mPaintImageRegular);
if (mFogOfWarState != FOG_OF_WAR_HIDDEN) {
    canvas.drawBitmap(mFogOfWar, mTransformationMatrix, mPaintFog);
}

“秘密”是不是使用掩码位图,而是使用另一种颜料擦除战争迷雾

mFogOfWarCanvas.drawPath(mPath, mEraserPaint);

唯一具有Paint的{​​{1}}用于删除:

Xfermode

为了加载和保存我的面具,我会做以下事情:

mEraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));