Android 将两幅图像混合在一起,使用“倍增”和“不透明度百分比”

Android 将两幅图像混合在一起,使用“倍增”和“不透明度百分比”,android,blending,porter-duff,Android,Blending,Porter Duff,我正在尝试用Android混合两幅图像,使用一种类似乘法的混合模式 // Prepare ------------------------------- // Create source images Bitmap img1 = ... Bitmap img2 = ... // Create result image Bitmap result = ... Canvas canvas = new Canvas(); canvas.setBitmap(result); // Get prop

我正在尝试用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()
似乎不适用于此

有没有其他方法来设置新“层”的不透明度百分比


另外,我想有一些方法(使用
LightingColorFilter
)通过预乘法并将颜色偏移为白色来实现乘法,但乘法模式非常特殊。。我正试图找到一种方法,将不透明度/%的东西也应用到所有其他传输模式。

我不久前需要做类似的事情,我发现了很多启发。 (但恐怕这与您在“PS”中描述的内容有关)


,多亏了@1j01,我实现了与我们的iOS应用程序类似的照片过滤器。他们的做法类似于
源位图+掩码位图+混合模式+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
不是我的-找到它:(回答)

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

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 answer中的这些代码行,它非常适合混合位图

//将位图和可见性百分比作为整数值传递

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

瓦鲁·拉帕兹。但是,是的,这篇文章很棒,但它更多的是关于用不同的模式附加层,而不是有一种方法来更改每个模式的输入值的%。在从图像中读取像素后,它确实显示了对像素的一些直接操作,因此它可能是一种替代方法。我需要调查一下。现在,谢谢!回程机器链接:什么是混合方法???请分享完整的一个,否则没有用。@Mohsin如果我正确地记得这背后的问题,我认为这现在是在AndroidSDK中实现的。早在2015年,它就缺少了一些混合模式