用正片叠底和%不透明度混合两个图像



我正在尝试在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%的乘法将与基本图像(imag1)相同,没有任何变化,但100%的乘法将是我使用上面的代码得到的结果。

paint.setAlpha()似乎不起作用。

还有其他方法来设置新"图层"的%不透明度吗?

注:有一些方法,使乘法工作与此我猜(使用LightingColorFilter)通过预乘和抵消颜色为白色,但它是非常具体的多模式..我正试图找到一种方法来应用不透明度/%的东西到所有其他传输模式

不久前我需要做一些类似的事情,我发现这篇关于颜色通道的文章很有启发性。(但恐怕这与你在"PS"中描述的内容有关)

以上链接来自archive.org,感谢@1j01

我正在实现类似于我们的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中的stock PorterDuff模式。

方法makeTransparent不是我的-在这里找到的:(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;
}

我正在使用这些来自@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;
}

相关内容

最新更新