2012-11-26 136 views
4

在Photoshop有几个混合模式,如:PNG混合模式

  • 颜色加深
  • 乘法
  • 变暗
  • 变浅
  • 叠加

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

例如,对于模式颜色加深“着眼于每个通道中的颜色信息,并基色变暗通过增大两者之间的对比,以反映混合色。与白色混合后不产生变化”

这是我的代码:

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

是否有可能适用,例如,颜色加深混合模式,而不是简单地在这个小画上面的其他图像的图像(如?。代码)

+0

你的意思是你想要写您的图像滤镜效果? – Raptor

+0

它不完全是过滤效果,它是两层混合在一起的某种方式。 – alwx

回答

3

也不难

我使用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, 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); 
} 

小的话,以提高性能:我做了单个像素的公式后,它会是很好的保存在某种缓存值更快地访问它没有公式下一次。

+1

它的工作!当然,还有一些类似于ChannelBlend_ColorBurn声明的拼写错误,但仍然非常感谢你!你几乎救了我的应用程序!我终于可以沟ImageMagick了,谢谢! –