2011-10-12 8 views
8

Estoy tratando de combinar dos imágenes junto con Android, usando un modo de fusión tipo Multiplicar.Mezcla de dos imágenes junto con multiplicar y% de opacidad

// Prepare ------------------------------- 

// Create source images 
Bitmap img1 = ... 
Bitmap img2 = ... 

// Create result image 
Bitmap result = ... 
Canvas canvas = new Canvas(); 
canvas.setBitmap(result); 

// Get proper display reference 
BitmapDrawable drawable = new BitmapDrawable(getResources(), result); 
ImageView imageView = (ImageView)findViewById(R.id.imageBlend1); 
imageView.setImageDrawable(drawable); 


// Apply ------------------------------- 

// Draw base 
canvas.drawBitmap(img1, 0, 0, null); 

// Draw overlay 
Paint paint = new Paint(); 
paint.setXfermode(new PorterDuffXfermode(Mode.MULTIPLY)); 
paint.setShader(new BitmapShader(img2, TileMode.CLAMP, TileMode.CLAMP)); 

canvas.drawRect(0, 0, img2.getWidth(), img2.getHeight(), paint); 

Esto funciona, pero no tienen control sobre la "cantidad" de multiplicar lo que se hace - es siempre una transferencia completa se multiplican. Idealmente, una multiplicación del 0% sería la misma que la imagen base (img1) sin ningún cambio, pero el resultado sería un 100% de multiplicación con el código anterior.

paint.setAlpha() parece que no funciona para esto.

¿Alguna otra forma de establecer el% de opacidad de la nueva "capa"?

P.S. Hay algunos métodos para hacer que la multiplicación funcione con esto, supongo (utilizando un LightingColorFilter) multiplicando previamente y desplazando el color a blanco, pero es muy específico del modo múltiple. Estoy tratando de encontrar una manera de aplicar la opacidad. % de los demás modos de transferencia también.

Respuesta

2

Tenía que hacer algo así hace un tiempo, y encontré this post about Color Channels mucho esclarecedor. (Pero me temo que esto está relacionado con lo que describió en su "PS")

+1

Valeu rapaz. Pero sí, el artículo es excelente, pero se trata más bien de unir capas con diferentes modos en lugar de tener una forma de cambiar el% de los valores de entrada para cada modo. Muestra cierta manipulación directa de los píxeles después de leerlos de la imagen, por lo que tal vez sea una alternativa. Tendré que investigar eso. Por ahora, gracias! – zeh

+1

Enlace NO encontrado, hermano. ¡Por favor actualice! –

2

Estaba implementando filtros de fotos similares a lo que hace nuestra aplicación para iOS. Lo hacen algo así como source bitmap + mask bitmap + blend mode + alpha value. Para lograr un comportamiento idéntico acabo de aumentar el alfa de la máscara. Esto es lo que mi código, finalmente, se ve:

public static Bitmap blend(Bitmap back, Bitmap front, BlendMethod method, float alpha) { 
    if (alpha != 1.0F) { 
     front = makeTransparent(front, Math.round(alpha * 255)); 
    } 

    Bitmap.Config config = back.getConfig(); 
    int width = back.getWidth(); 
    int height = back.getHeight(); 

    if (width != front.getWidth() || height != front.getHeight()) { 
     Log.e(TAG, "Arrays must be of identical size! Do bitmap scaling prior to blending."); 
     return null; 
    } 

    int[] frontArr = new int[height * width], backArr = new int[height * width], resultArr; 

    back.getPixels(backArr, 0, width, 0, 0, width, height); 
    front.getPixels(frontArr, 0, width, 0, 0, width, height); 

    resultArr = jniBlend(frontArr, backArr, alpha, method.toInt()); 
    return Bitmap.createBitmap(resultArr, width, height, config); 
} 

public static Bitmap blend(Bitmap back, Bitmap front, BlendMethod method) { 
    return blend(back, front, method, 1F); 
} 

public static Bitmap makeTransparent(Bitmap src, int value) { 
    int width = src.getWidth(); 
    int height = src.getHeight(); 
    Bitmap transBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
    Canvas canvas = new Canvas(transBitmap); 
    canvas.drawARGB(0, 0, 0, 0); 
    // config paint 
    final Paint paint = new Paint(); 
    paint.setAlpha(value); 
    canvas.drawBitmap(src, 0, 0, paint); 
    return transBitmap; 
} 

Tenga en cuenta que jniBlend es un método que escribí en mi propia, se comporta como modos de PorterDuff en Java.

Método makeTransparent no es mía - encontró que here: (respuesta de Ruban)

0

El código no es completa. es solo para darle una idea para que pueda usar la secuencia de comandos de procesamiento para combinar una imagen

public Bitmap blend(Bitmap image) 
{ 
    final float BLUR_RADIUS = 25f; 
    Bitmap outbitmap = Bitmap.createBitmap(image); 
    final RenderScript renderScript = RenderScript.create(this); 

    Allocation tmpin = Allocation.createFromBitmap(renderScript,image); 
    Allocation tmpout = Allocation.createFromBitmap(renderScript,outbitmap); 
    ScriptIntrinsicBlend blend = ScriptIntrinsicBlend.create(renderScript, 
    Element.U8_4(renderScript)); 

    blend.forEachMultiply(tmpin,tmpout); 
    return outbitmap; 
} 
Cuestiones relacionadas