user487252's solution funciona como un encanto hasta el nivel API 16 (Jelly Bean), después de lo cual AvoidXfermode
no parece funcionar en absoluto.
En mi caso de uso particular, he renderizado una página de un PDF (a través de APV PDFView) en una matriz de píxeles int[]
que voy a pasar al Bitmap.createBitmap(int[], int, int, Bitmap.Config)
. Esta página contiene dibujos lineales dibujados sobre un fondo blanco, y necesito eliminar el fondo conservando el anti-aliasing.
No pude encontrar un modo Porter-Duff que hiciera exactamente lo que quería, así que terminé abrochando e iterando a través de los píxeles y transformándolos uno por uno. El resultado fue sorprendentemente simple y performant:
int [] pixels = ...;
for(int i = 0; i < pixels.length; i++) {
// Invert the red channel as an alpha bitmask for the desired color.
pixels[i] = ~(pixels[i] << 8 & 0xFF000000) & Color.BLACK;
}
Bitmap bitmap = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
Esto es perfecto para la línea arte dibujo, puesto que cualquier color puede ser utilizado para las líneas sin perder el anti-aliasing. Estoy usando el canal rojo aquí, pero puede usar verde cambiando 16
bits en lugar de 8
, o azul cambiando 24
.
Gracias, pero finalmente descubrí cómo hacerlo con porterduff, xfermode (xor) lo hizo, pero se aplicó a otro mapa de bits, primero fusioné la máscara y la fuente e intenté dibujarlo en el lienzo con filtro de color, pero finalmente pensé que debería usar xfermode al dibujar la máscara en el código fuente, no en el lienzo :) – ZZZ