2011-01-12 49 views
5

我试图在两幅图像上应用混合滤镜(在这种情况下为HardLight)。基础Android库不支持HardLight,因此,我正在手动处理每个像素。第一轮运行正常,但速度不及恒星。从基本500x500图像和500x500滤镜生成500x500图像的过程时间过长。这段代码也用于生成缩略图(72x72),它也是应用程序核心的组成部分。我很乐意提供一些关于如何加快速度的建议和/或提示。在Android位图上优化每像素混合

如果通过假设任何一个图像都没有alpha值就可以获得巨大收益,那很好。 注意:BlendMode和alpha是在示例中没有使用的值(BlendMode将选择混合类型,在这种情况下,我硬编码HardLight)。

public Bitmap blendedBitmap(Bitmap source, Bitmap layer, BlendMode blendMode, float alpha) { 
    Bitmap base = source.copy(Config.ARGB_8888, true); 
    Bitmap blend = layer.copy(Config.ARGB_8888, false); 

    IntBuffer buffBase = IntBuffer.allocate(base.getWidth() * base.getHeight()); 
    base.copyPixelsToBuffer(buffBase); 
    buffBase.rewind(); 

    IntBuffer buffBlend = IntBuffer.allocate(blend.getWidth() * blend.getHeight()); 
    blend.copyPixelsToBuffer(buffBlend); 
    buffBlend.rewind(); 

    IntBuffer buffOut = IntBuffer.allocate(base.getWidth() * base.getHeight()); 
    buffOut.rewind(); 

    while (buffOut.position() < buffOut.limit()) { 
     int filterInt = buffBlend.get(); 
     int srcInt = buffBase.get(); 

     int redValueFilter = Color.red(filterInt); 
     int greenValueFilter = Color.green(filterInt); 
     int blueValueFilter = Color.blue(filterInt); 

     int redValueSrc = Color.red(srcInt); 
     int greenValueSrc = Color.green(srcInt); 
     int blueValueSrc = Color.blue(srcInt); 

     int redValueFinal = hardlight(redValueFilter, redValueSrc); 
     int greenValueFinal = hardlight(greenValueFilter, greenValueSrc); 
     int blueValueFinal = hardlight(blueValueFilter, blueValueSrc); 

     int pixel = Color.argb(255, redValueFinal, greenValueFinal, blueValueFinal); 

     buffOut.put(pixel); 
    } 

    buffOut.rewind(); 

    base.copyPixelsFromBuffer(buffOut); 
    blend.recycle(); 

    return base; 
} 

private int hardlight(int in1, int in2) { 
    float image = (float)in2; 
    float mask = (float)in1; 
    return ((int)((image < 128) ? (2 * mask * image/255):(255 - 2 * (255 - mask) * (255 - image)/255))); 

} 
+0

嗨,你能帮助我如何在这个函数中使用alpha吗? – 2012-02-21 00:16:59

回答

0

有一个这样的问题,回来(Link)。我不确定OP是否解决了他的问题。

在我的案例中,为了实现“photoshop混合”而做的是通过将透明阴影覆盖层应用于单一颜色。这只是我的平面设计师想出如何做阴影覆盖的问题。它工作得很好,我完全忽略了必须遍历位图像素的问题(我使用getPixels()和setPixels())。最难的部分是我的设计师,但是一旦他发现了这个问题,他就会生成一些非常漂亮的图像。

我基本上使用了阴影叠加的alpha蒙版(用于生成动态颜色)。我很乐意通过代码了解解决方案,祝您好运!

编辑:此外,我不熟悉BlendMode。你从未在你的方法中使用过它。这是什么,一个习俗班?

+0

不幸的是,这个解决方案在我的情况下不起作用。 – MarkPowell 2011-01-13 15:35:18

2

浮点操作通常比整数慢,但我无法专门针对Android进行任何说明。我不知道为什么你将输入转换为hardlight为浮点,当操作看起来像他们完美的整数工作?

通过将公式嵌入到循环中,而不是调用函数,您可能会获得加速。或者可能不是,但值得尝试和基准。

+0

尝试不同的事情,我可以通过使用int数组而不是缓冲区(使用`getPixels()`和`setPixels()`)获得大约40%的性能提升,并且不会将值转换为`hardlight`中的浮点数。除此之外,我认为您获得的最佳性能是将此计算转换为本机级别,也许会实现一个自定义Xfermode。 – 2011-01-12 19:28:58

+0

hmm,切换到getPixels()/ setPixels()除非我误解你的意思,否则我看到计算时间增加了一倍。 – MarkPowell 2011-01-14 14:10:56

1

此外,如果你可以牺牲3位/的最终图像质量/精确的像素, - 我们可以在功能上赢得约25%的性能增益强光(),通过与位运算符将其重写:

int hardlight(int image, int mask) { 
    return (((image < 128) ? 
      ((((mask << 1) * image) >> 8)): 
      (255^((((255^mask) << 1) * (255^image)) >> 8)))); 
}