次のシナリオがあります。背景として使用されるビットマップと、50%透明または不透明(実行時に変更可能)のオーバーレイとして使用される別のビットマップ、およびこの2番目のビットマップのマスクを含む3番目のビットマップ。さまざまなXfermodes構成と描画順序を試しましたが、正しいものを見つけることができませんでした。
プログラムの2回の実行間、または構成の変更間でマスクを保存できる必要があるため、マスクをビットマップとして使用しています。これは、ユーザーが画面に描画するときに作成され、戦争の霧を効果的にクリーンアップします。
最善の試みによるからのコードスニペット。思ったように動かなかったのは、マスクの透明度だけでした。
@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オブジェクトにアルファを設定してこれを実行できるかどうかはわかりません。そうでない場合は、アルファ問題の別の提案や解決策、できれば戦争の霧として使用されているビットマップの再現が必要ないものを気にしません。
編集:
次のようにすることで、希望する結果を得ることができました。
@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));
しかし、ビットマップを5回描画するのは無駄のようです。これはAndroidハードウェアの高速化によりOpenGLテクスチャで実行され(ビットマップをデバイスのGPUで受け入れられる最高の解像度に再スケーリングします)invalidates()
、Nexus SとA500の両方で驚くほどスムーズに実行されるように細心の注意を払っていますが、他のデバイスについてはよくわかりません(プロジェクトはとにかく4.0以降になる予定です)。
しかし、私はそれを行うためのより良い方法があるに違いないと確信しています。私は、その多くの過剰描画を回避する方法、または少なくともそれらのXfermodesが何を意味するのかを正しく説明でき、私がものを過剰描画していない方法を望んでいます。