Beo*_*son 5 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);
}
Run Code Online (Sandbox Code Playgroud)
Paint 对象:
mPaintImage.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));
mPaintFog.setAlpha(127);
mPaintMask.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
Run Code Online (Sandbox Code Playgroud)
这是我对当前配置更清楚的结果:

我不确定我是否能够在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);
}
Run Code Online (Sandbox Code Playgroud)
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));
Run Code Online (Sandbox Code Playgroud)
但是五次绘制位图似乎是浪费.由于Android硬件加速,我在OpenGL纹理中运行(我将位图重新调整为设备GPU接受的最高分辨率)并且我invalidates()在我的Nexus S和A500上运行时非常顺畅,但是我不确定其他设备(无论如何项目将是4.0+).
但我相信必须有更好的方法来做到这一点.我想要一种避免过度透支的方法,或者至少可以正确地向我解释那些Xfermodes的含义以及我不会透支的东西.
在经历了某种顿悟之后,我尝试了一种完全不同的方法 - 并且意识到这个问题的解决方案是一种更简单的方法 - 通常是这样.由于我只需要两个位图,因此我需要更少的内存来处理它.
用于绘图:
canvas.drawBitmap(mImage, mTransformationMatrix, mPaintImageRegular);
if (mFogOfWarState != FOG_OF_WAR_HIDDEN) {
canvas.drawBitmap(mFogOfWar, mTransformationMatrix, mPaintFog);
}
Run Code Online (Sandbox Code Playgroud)
"秘密"是不是使用掩码位图,而是使用另一种颜料消除战争的迷雾:
mFogOfWarCanvas.drawPath(mPath, mEraserPaint);
Run Code Online (Sandbox Code Playgroud)
唯一Paint有一个Xfermode是用于擦除的:
mEraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
Run Code Online (Sandbox Code Playgroud)
为了加载和保存我的面具,我做了以下事情:
private void createFogAndMask(File dataDir) {
BitmapDrawable tile = (BitmapDrawable) getResources().getDrawable(R.drawable.fog_of_war);
tile.setTileModeXY(TileMode.REPEAT, TileMode.REPEAT);
mFogOfWar = Bitmap.createBitmap(mImageBounds.width(), mImageBounds.height(), Config.ARGB_8888);
mFogOfWarCanvas = new Canvas(mFogOfWar);
tile.setBounds(mImageBounds);
tile.draw(mFogOfWarCanvas);
tile = null;
// Try to load an existing mask
File existingMask = new File(dataDir, getMaskFileName());
if (existingMask.exists()) {
Bitmap existingMaskBitmap = BitmapFactory.decodeFile(existingMask.getAbsolutePath());
mFogOfWarCanvas.drawBitmap(existingMaskBitmap, new Matrix(), mPaintImageRegular);
mFogOfWarCanvas.drawPaint(mMaskEraserPaint);
existingMaskBitmap.recycle();
System.gc();
}
}
public void saveMask(File folder) throws IOException {
if (!mReady || mImagePath == null) return;
mImage.recycle();
System.gc();
if (!folder.exists()) {
folder.mkdirs();
}
File savedFile = new File(folder, getMaskFileName());
// Change all transparent pixels to black and all non-transparent pixels to transparent
final int length = mImageBounds.width() * mImageBounds.height();
final int[] pixels = new int[length];
mFogOfWar.getPixels(pixels, 0, mImageBounds.width(), 0, 0, mImageBounds.width(), mImageBounds.height());
for (int i = 0; i < length; i++) {
if (pixels[i] == Color.TRANSPARENT) {
pixels[i] = Color.BLACK;
} else {
pixels[i] = Color.TRANSPARENT;
}
}
mFogOfWar.setPixels(pixels, 0, mImageBounds.width(), 0, 0, mImageBounds.width(), mImageBounds.height());
FileOutputStream output = new FileOutputStream(savedFile);
mFogOfWar.compress(CompressFormat.PNG, 80, output);
output.flush();
output.close();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8462 次 |
| 最近记录: |