Android – Enmascarar un mapa de bits con otro mapa de bits

Tengo dos mapas de bits. Aquí está Bitmap 1:

Mapa de bits 1: Antecedentes

Y aquí está Bitmap 2:

Mapa de bits 2: marco

Cuáles serán los resultados finales:

Bitmap Final

Me gustaría un código, sin embargo, me gustaría más una referencia a una documentación o tutorial. Me gustaría entender el código completamente y he estado buscando en developer.android.com durante tanto tiempo sin suerte. Gracias.

¿Sobre 3 años y ninguna respuesta? Yo puedo arreglar eso.

Como se indica en los comentarios, el mapa de bits 2 es transparente alrededor de los bordes y en el centro (sólo el contorno está allí) por lo que el primer paso es llenar el centro con blanco. Hay un montón de algoritmos de relleno de inundación disponibles. Utilicé https://stackoverflow.com/a/8925653/852795 porque era fácil, aunque hay otros que son ciertamente más rápidos. Esto es necesario ya que permite el paso siguiente.

El segundo paso es combinar el mapa de bits 2 lleno con el mapa de bits 1 utilizando el compositor Porter / Duff . PorterDuff.Mode.SRC_ATOP efectivamente pintará el mapa de bits 1 en el área ahora blanca del mapa de bits 2, dejando el área fuera del contorno transparente.

Aquí está el código:

 package test.testapplication; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Point; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.graphics.Bitmap.Config; import java.util.LinkedList; import java.util.Queue; public class MainActivity extends AppCompatActivity { Bitmap mask, background, filledMask, overlay; Canvas c; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mask = BitmapFactory.decodeResource(getResources(), R.drawable.mask); background = BitmapFactory.decodeResource(getResources(), R.drawable.background); // get the mask, copy it to filledMask and then flood from the center with CYAN filledMask = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Config.ARGB_8888); c = new Canvas(filledMask); c.drawBitmap(mask, 0, 0, new Paint()); Point center = new Point(filledMask.getWidth() / 2, filledMask.getHeight() / 2); floodFill(filledMask, center, Color.TRANSPARENT, Color.WHITE); // create new overlay Bitmap, draw the filledMask and then add the background using PorterDuff overlay = Bitmap.createBitmap(filledMask.getWidth(), filledMask.getHeight(), Config.ARGB_8888); c = new Canvas(overlay); Paint p = new Paint(); p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP)); c.drawBitmap(filledMask, 0, 0, new Paint()); c.drawBitmap(background, 0, 0, p); DrawView drawView = new DrawView(this); // set background to light blue in order to see transparent areas drawView.setBackgroundColor(0xffd2d7fe); setContentView(drawView); drawView.requestFocus(); } public class DrawView extends View { Paint p = new Paint(); int top = 0; public DrawView(Context context) { super(context); } protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawBitmap(mask, 0, 0, p); top += mask.getHeight(); canvas.drawBitmap(filledMask, 0, top, p); top += filledMask.getHeight(); canvas.drawBitmap(background, 0, top, p); top += background.getHeight(); canvas.drawBitmap(overlay, 0, top, p); } } // method from https://stackoverflow.com/a/8925653/852795 public void floodFill(Bitmap bmp, Point pt, int targetColor, int replacementColor) { Queue<Point> q = new LinkedList<>(); q.add(pt); while (q.size() > 0) { Point n = q.poll(); if (bmp.getPixel(nx, ny) != targetColor) continue; Point w = n, e = new Point(nx + 1, ny); while ((wx > 0) && (bmp.getPixel(wx, wy) == targetColor)) { bmp.setPixel(wx, wy, replacementColor); if ((wy > 0) && (bmp.getPixel(wx, wy - 1) == targetColor)) q.add(new Point(wx, wy - 1)); if ((wy < bmp.getHeight() - 1) && (bmp.getPixel(wx, wy + 1) == targetColor)) q.add(new Point(wx, wy + 1)); wx--; } while ((ex < bmp.getWidth() - 1) && (bmp.getPixel(ex, ey) == targetColor)) { bmp.setPixel(ex, ey, replacementColor); if ((ey > 0) && (bmp.getPixel(ex, ey - 1) == targetColor)) q.add(new Point(ex, ey - 1)); if ((ey < bmp.getHeight() - 1) && (bmp.getPixel(ex, ey + 1) == targetColor)) q.add(new Point(ex, ey + 1)); e.x++; } } } } 

Cuando se ejecuta, la salida (después de añadir un tinte azul claro al fondo para ver las áreas transparentes de las imágenes) debería tener este aspecto, siendo las imágenes respectivamente Bitmap 2, Bitmap 2, Bitmap 1 y Finalmente la combinación de Bitmap 2 llenado y Bitmap 1:

Introduzca aquí la descripción de la imagen

Parece que hay un poco de "borrosidad" justo dentro del contorno, pero eso es probablemente un artefacto del relleno de inundación, o tal vez el Bitmap original 2. Jugar con ambos podría aclarar eso.

  • Cómo redimensionar un mapa de bits eficientemente y sin perder calidad en android
  • Cómo aumentar el tamaño de imagen de mapa de bits de acuerdo con el tamaño de pantalla del teléfono?
  • Dibujar líneas transparentes en el mapa de bits a través de la entrada táctil
  • Android - cómo evitar la memoria sobre la carga mediante mapas de bits?
  • Android: Dibuja varios mapas de bits en otro mapa de bits
  • Bitmap.compress devuelve false para la imagen dibujada
  • Android: Cómo centrar las imágenes de recorte sin escala
  • Uso de la clase EffectFactory en mapa de bits - Android
  • Android rotar mapa de bits sin hacer una copia
  • DrawBitmap: ¿Cómo se pueden establecer coordenadas y utilizar una matriz?
  • Widget de la aplicación Android con renderizado personalizado
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.