将两个图像混合在一起,使用乘法和不透明度

我试图将两个图像与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()似乎不适用于此。

任何其他方式来设置新的“图层”的不透明度?

PS有一些方法来做乘法工作,我猜(使用LightingColorFilter )通过预乘和偏移的颜色为白色,但它是非常具体的multiplymode ..我试图find一种方法来应用不透明度/%对所有其他传输模式也是如此。

Related of "将两个图像混合在一起,使用乘法和不透明度"

我需要做一些这样的事情,而我发现这篇关于色彩频道的文章有很多启发。 (但恐怕这与你在“PS”中描述的相关)

我正在实现类似于我们的iOS应用程序的照片滤镜。 他们做的东西就像source bitmap + mask bitmap + blend mode + alpha value 。 为了达到相同的行为,我只是增加了面具的阿尔法。 这是我的代码最终看起来:

 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不是我的 – 在这里find它:(从Ruban回答)

代码不完整。 这只是给你一个想法,以便您可以使用渲染脚本来混合图像

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