¿Cómo crear una máscara para una superposición transparente?

Tengo el siguiente escenario: un mapa de bits que se utiliza como fondo y otro mapa de bits que se utiliza como superposición que puede ser 50% transparente u opaco (cambiable en tiempo de ejecución) y un tercer mapa de bits que contiene una máscara para este segundo mapa de bits. He intentado diferentes configuraciones Xfermodes y órdenes de dibujo, pero no fue capaz de encontrar la correcta.

Estoy utilizando la máscara como un mapa de bits, porque tengo que ser capaz de guardar entre dos ejecuciones del programa o entre los cambios de configuración. Se crea como el usuario dibuja en la pantalla, efectivamente la limpieza de la niebla de la guerra .

Código de fragmentos de por mejor intento. Lo único que no funcionó como yo deseaba que hiciera era la transparencia de mi máscara.

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

Paint objetos:

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

Esto es lo que obtengo con la configuración actual para ser más clara: captura de pantalla

No estoy seguro si voy a ser capaz de hacer este ajuste el alfa en el objeto de la pintura; Si no, no me importa otra sugerencia o solución para la cuestión alfa, preferiblemente uno donde la recreación del mapa de bits que se utiliza como una niebla de guerra no es necesario.

EDITAR:

Pude obtener los resultados que quiero haciendo lo siguiente:

 @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); } 

Objetos de 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)); 

Pero dibujar los mapas de bits cinco veces parece un desperdicio. Como esto se ejecuta en una textura OpenGL debido a la aceleración de hardware de Android (vuelvo a ajustar los mapas de bits a la resolución más alta aceptada por la GPU del dispositivo) y tomo mucho cuidado en mi invalidates() funciona sorprendentemente suave en mi Nexus S y mi A500, pero no estoy seguro sobre otros dispositivos (el proyecto va a ser 4.0+ de todos modos).

Pero estoy convencido de que debe haber una mejor manera de hacerlo. Me gustaría una manera que evitó que mucho overdrawn o que por lo menos podría explicarme correctamente lo que esos Xfermodes significan y que no estoy overdrawing cosas.

One Solution collect form web for “¿Cómo crear una máscara para una superposición transparente?”

He intentado un enfoque completamente diferente después de tener una especie de epifanía – y me di cuenta de que la solución para este problema era un enfoque mucho más simple – como suele ser. Y como sólo necesito dos mapas de bits, necesito menos memoria para trabajar con él.

Para dibujar:

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

El "secreto" era que en vez de dibujar en el mapa de bits de la máscara, estoy borrando la niebla de la guerra usando otra pintura:

 mFogOfWarCanvas.drawPath(mPath, mEraserPaint); 

La única Paint que tiene un Xfermode es la utilizada para borrar:

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

Y para la carga y el ahorro de mi máscara, hago lo siguiente:

 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(); } 
  • Android: Circular Dibujable
  • Dibuje las áreas superpuestas en un trayecto
  • Mezclar dos imágenes junto con multiplicar y% de opacidad
  • PorterDuff y ruta
  • Superposición de color de Android - Modos de PorterDuff
  • Porter-Duff: ¿comportamiento diferente para diferentes formas?
  • Android con PorterDuff para combinar imágenes
  • Android Porter-Duff Composición de rendimiento
  • Android ColorFilter - Modos de Porter-Duff
  • Android Gauge Animation Pregunta
  • Android personalizado XferMode / PorterDuff.Mode
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.