Android PNG混合模式

Android PNG混合模式,android,image-processing,android-image,Android,Image Processing,Android Image,在Photoshop中有两种混合模式,例如: 色斑 倍增 变暗 减轻 覆盖层 (更多信息请参见此处:) 例如,对于模式Color Burn“查看每个通道中的颜色信息,并通过增加两者之间的对比度使基色变暗以反映混合色。与白色混合不会产生任何变化” 这是我的代码: Bitmap blendBitmap = BitmapFactory.decodeStream(ctx.getAssets().open(filename)); Canvas canvas = new Canvas(srcBitmap

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

  • 色斑
  • 倍增
  • 变暗
  • 减轻
  • 覆盖层
(更多信息请参见此处:)

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

这是我的代码:

Bitmap blendBitmap = BitmapFactory.decodeStream(ctx.getAssets().open(filename));
Canvas canvas = new Canvas(srcBitmap);
canvas.drawBitmap(blendBitmap, 0, 0, null); // ?
p.recycle();
p = null;
例如,是否可以应用颜色燃烧混合模式,而不是简单地将图像绘制在其他图像的上方(如在这段小代码中)?

这并不困难

我使用NDK(因为性能)处理像素。混合模式的这些信息非常有用:

我的最终解决办法是:

#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, B, 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, bitmapA, &pixelsA)) < 0 ||
        (ret = AndroidBitmap_lockPixels(env, bitmapB, &pixelsB)) < 0 ||
        (ret = AndroidBitmap_lockPixels(env, bitmapOut, &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, ChannelBlend_ColorBurn, alpha);
            output[n].blue = ChannelBlend_AlphaF(pA.blue, pB.blue, ChannelBlend_ColorBurn, alpha);
        }
    }

    // Unlocks everything
    AndroidBitmap_unlockPixels(env, bitmapA);
    AndroidBitmap_unlockPixels(env, bitmapB);
    AndroidBitmap_unlockPixels(env, bitmapOut);
}
#定义ChannelBlend\u ColorBurn(A,B)((uint8\u t)((B==0)?B:max(0,(255-((255-)
#定义信道混合α(A,B,O)((uint8_t)(O*A+(1-O)*B))
#定义ChannelBlend_AlphaF(A,B,F,O)(ChannelBlend_Alpha(F(A,B,A,O))
类型定义结构{
uint8_t红色;
uint8_t绿色;
uint8_t蓝;
uint8_tα;
}rgba;
//调和
JNIEXPORT无效
JNICALL Java_com_package_Filter_jniBlend(JNIEnv*env、jobject obj、jobject bitmappa、,
jobject位图B、jobject位图输出、jint模式){
//性质
AndroidBitmapInfo infoA;
void*pixelsA;
AndroidBitmapInfo信息数据库;
void*pixelsB;
AndroidBitmapInfo信息输出;
void*pixelsOut;
int ret;
//获取图像信息
如果((ret=AndroidBitmap_getInfo(env、bitmapA和infoA))<0||
(ret=AndroidBitmap_getInfo(env、bitmap和infoB))<0||
(ret=AndroidBitmap_getInfo(env、位图输出和infoOut))<0){
返回;
}
//检查图像
如果(infoA.format!=ANDROID_位图_格式_RGBA_8888||
infoB.format!=ANDROID_位图_格式_RGBA_8888||
infoOut.format!=ANDROID_位图_格式_RGBA_8888){
返回;
}
//锁定所有图像
如果((ret=AndroidBitmap_lockPixels(env、位图和像素))<0||
(ret=AndroidBitmap_lockPixels(env、bitmapB和pixelsB))<0||
(ret=AndroidBitmap_lockPixels(环境、位图输出和像素输出))<0){
LOGE(“错误!%d”,ret);
}
int h=信息高度;
int w=信息宽度;
int-wh=w*h;
int n;
rgba*输入=(rgba*)像素;
rgba*输入B=(rgba*)像素SB;
rgba*输出=(rgba*)像素输出;
rgba-pA,pB;
int x,y;
对于(y=0;y

提高性能的小贴士:在我为单像素创建公式后,最好将值存储在某种缓存中,以便下次在没有公式的情况下更快地访问它。

你的意思是想在图像上写一个过滤效果吗?这不完全是过滤效果,而是两层相互混合的某种方式。它起作用了!当然,有一些拼写错误,比如ChannelBlend_ColorBurn的声明,但是,非常感谢!你实际上保存了我的应用程序!我终于可以抛弃ImageMagick了,谢谢!