Android – Enmascarar un mapa de bits con otro mapa de bits
Tengo dos mapas de bits. Aquí está Bitmap 1:
- Bitmap setPixels perderá el canal alfa cuando el fondo sea negro
- Cambiar gradualmente el fondo de gradiente del widget
- Estiramiento Mapa de bits en una esquina específica
- Bitmap escalado que mantiene la proporción de aspecto
- llamada a Bitmap.compress no devuelve - y ninguna excepción
Y aquí está Bitmap 2:
Cuáles serán los resultados finales:
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.
- Cómo trabajar con Bitmap (Effects) en Android?
- La imagen se ha girado después de reducir el tamaño de la imagen de mapa de bits
- Android obtiene la posición del mapa de bits en ImageView
- Visualización de la imagen del perfil FB en vista de imagen circular en la aplicación
- Cómo tomar una captura de pantalla de SurfaceView con una vista previa de la cámara
- Data.getExtras (). Get ("data") resultado de la imagen de baja resolución en android
- Android Native crash en /system/lib/libskia.so (procesamiento de mapas de bits)
- Convertir archivo de mapa de bits inmutable a mutable Bitmap
¿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:
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 obtener la versión SDK de la aplicación y no del dispositivo?
- Cómo hacer Android Ver la lista de diseño de Android L Vista previa de diseño