我有以下场景:一个用作背景的位图和另一个用作覆盖的位图,可以是 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));
这是我通过当前配置得到的更清楚的结果:
我不确定我是否能够在 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+)。
但我相信一定有更好的方法来做到这一点。我想要一种避免过多透支的方法,或者至少可以正确地向我解释那些 Xfermode 的含义并且我没有透支的东西。