微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

android – PNG混合模式

在Photoshop中有几种混合模式,例如:

>颜色烧伤
>乘以
>变暗
>减轻
>叠加

(更多信息:http://help.adobe.com/en_US/photoshop/cs/using/WSfd1234e1c4b69f30ea53e41001031ab64-77eba.html)

例如,对于模式Color Burn“查看每个通道中的颜色信息,并通过增加两者之间的对比度来使基色变暗以反映混合颜色.与白色混合不会产生任何变化”.

这是我的代码

Bitmap blendBitmap = BitmapFactory.decodeStream(ctx.getAssets().open(filename));
Canvas canvas = new Canvas(srcBitmap);
canvas.drawBitmap(blendBitmap,null); // ?
p.recycle();
p = null;

是否可以应用Color Burn混合模式而不是简单地将图像绘制在其他图像上方(如此小代码中)?

解决方法

这并不困难.

我使用NDK(因为性能)来处理像素.混合模式的这些信息非常有用:How does photoshop blend two images together?

我的最终解决方案是:

#define ChannelBlend_ColorBurn(A,B)  ((uint8_t) ((B == 0) ? B : max(0,(255 - ((255 -  
#define ChannelBlend_Alpha(A,B,O)    ((uint8_t) (O * A + (1 - O) * B))
#define ChannelBlend_AlphaF(A,F,O) (ChannelBlend_Alpha(F(A,B),A,O))

typedef struct {
    uint8_t red;
    uint8_t green;
    uint8_t blue;
    uint8_t alpha;
} rgba;

// Blend
JNIEXPORT void 
JNICALL Java_com_package_Filter_jniBlend(jnienv* env,jobject obj,jobject bitmapA,jobject bitmapB,jobject bitmapOut,jint mode) {

    // Properties
    AndroidBitmapInfo   infoA;
    void*               pixelsA;
    AndroidBitmapInfo   infoB;
    void*               pixelsB;
    AndroidBitmapInfo   infoOut;
    void*               pixelsOut;

    int ret;

    // Get image info
    if ((ret = AndroidBitmap_getInfo(env,bitmapA,&infoA)) < 0 ||
        (ret = AndroidBitmap_getInfo(env,bitmapB,&infoB)) < 0 ||
        (ret = AndroidBitmap_getInfo(env,bitmapOut,&infoOut)) < 0) {
        return;
    }
    // Check image
    if (infoA.format != ANDROID_BITMAP_FORMAT_RGBA_8888 ||
        infoB.format != ANDROID_BITMAP_FORMAT_RGBA_8888 ||
        infoOut.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
        return;
    }
    // Lock all images
    if ((ret = AndroidBitmap_lockPixels(env,&pixelsA)) < 0 ||
        (ret = AndroidBitmap_lockPixels(env,&pixelsB)) < 0 ||
        (ret = AndroidBitmap_lockPixels(env,&pixelsOut)) < 0) {
        LOGE("Error! %d",ret);
    }

    int h = infoA.height;
    int w = infoA.width;
    int wh = w * h;

    int n;
    rgba* inputA = (rgba*) pixelsA;
    rgba* inputB = (rgba*) pixelsB;
    rgba* output = (rgba*) pixelsOut;

    rgba pA,pB;

    int x,y;
    for (y = 0; y < h; y++) {
        for (x = 0; x < w; x++) {
            n = y * w + x;

            pA = inputA[n];
            pB = inputB[n];

            float alpha = (float) pB.alpha / 255.0;

            output[n].red = ChannelBlend_AlphaF(pA.red,pB.red,ChannelBlend_ColorBurn,alpha);
            output[n].green = ChannelBlend_AlphaF(pA.green,pB.green,alpha);
            output[n].blue = ChannelBlend_AlphaF(pA.blue,pB.blue,alpha);
        }
    }

    // Unlocks everything
    AndroidBitmap_unlockPixels(env,bitmapA);
    AndroidBitmap_unlockPixels(env,bitmapB);
    AndroidBitmap_unlockPixels(env,bitmapOut);
}

提高性能的小注意事项:在我为单个像素制作公式后,最好将值存储在某种缓存中,以便在下次没有公式的情况下更快地访问它.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐