我正在尝试使用类似Multiply的混合模式将两个图像与Android混合在一起。
// 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
),但它非常特定于乘法模式...我正试图找到一种方法将不透明度/%事物应用于所有其他传输模式。
答案 0 :(得分:3)
我不久前需要做类似的事情,我发现this post about Color Channels很有启发性。 (但我担心这与你在“PS”中描述的内容有关)
Link above in archive.org,感谢@ 1j01
答案 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模式。
答案 2 :(得分: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;
}
答案 3 :(得分:0)
我正在使用@Den Drobiazko 回答中的这些代码行,它非常适合混合位图
// 将您的位图和可见性百分比作为整数值传递
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
Log.e("test","value "+value);
final Paint paint = new Paint();
paint.setAlpha(value);
canvas.drawBitmap(src, 0, 0, paint);
return transBitmap;
}