2011-10-12 50 views
8

我試圖將兩個圖像與Android混合在一起,使用類似Multiply的混合模式。將兩個圖像與乘法和不透明度混合在一起

// 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); 

這是有效的,但我無法控制完成的乘法「數量」 - 它總是一個完整的乘法轉移。理想情況下,0%乘法與基本圖像(img1)相同,但沒有任何變化,但100%乘法將是我用上面的代碼得到的結果。

paint.setAlpha()似乎不適用於此。

任何其他方式來設置新的'層'的不透明度%?

P.S.有一些方法可以通過預乘和將顏色偏移到白色來實現乘法工作(我使用LightingColorFilter),但它對乘法模式非常具體。我試圖找到一種方法來應用不透明度/ %所有其他傳輸模式的東西。

回答

2

我需要做一些這樣的事情,而我發現this post about Color Channels很多啓發。 (但恐怕這與你在「PS」中描述的相關)

+1

Valeu rapaz。但是,這篇文章很棒,但更多的是關於使用不同模式附加圖層,而不是改變每種模式輸入值的百分比。在從圖像中讀取像素後,它確實顯示了一些像素的直接操作,所以也許是另一種選擇。我需要調查一下。現在,謝謝! – zeh

+1

未找到鏈接,兄弟。請更新! –

2

我正在實現類似於我們的iOS應用程序的照片濾鏡。他們這樣做就像source bitmap + mask bitmap + blend mode + alpha value。爲了達到相同的行爲,我只是增加了蒙版的alpha值。下面是我的代碼。但最終:

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

注意jniBlend一些方法,我對我自己寫的,它的行爲就像在Java中的股票PorterDuff模式。

方法makeTransparent不是我 - 發現它here:(回答來自Ruban

0

的代碼是不完整的。它只是給你一個想法,以便您可以使用渲染腳本來混合圖像

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; 
} 
相關問題