Android编辑位图通道

15

使用extractAlpha()方法可以访问给定位图的 alpha 通道,但我还没有找到任何设置位图 alpha 通道的方法。

在 Android 中,如何将多个灰度图像重新组合为通道并生成位图?

3个回答

24

重新将分离的通道合并回ARGB图像是完全可能的。您只需要灰度通道图像和带有所需Alpha通道的图像 - 请注意,这不是一个不透明的灰度图像,而是一个具有所需Alpha通道的图像。然后,使用适当的PorterDuffXfermode将每个通道与Paint绘制到一个空白的、填充为黑色的位图上。

// have your 3 channel grayscales and 1 alpha bitmap loaded by this point

Paint redPaint = new Paint();
redPaint.setXfermode(new PorterDuffXfermode(Mode.LIGHTEN));
redPaint.setShader(new BitmapShader(redChanImg, TileMode.CLAMP, TileMode.CLAMP));
redPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, Mode.DARKEN));

Paint greenPaint = new Paint();
greenPaint.setXfermode(new PorterDuffXfermode(Mode.LIGHTEN));
greenPaint.setShader(new BitmapShader(greenChanImg, TileMode.CLAMP, TileMode.CLAMP));
greenPaint.setColorFilter(new PorterDuffColorFilter(Color.GREEN, Mode.DARKEN));

Paint bluePaint = new Paint();
bluePaint.setXfermode(new PorterDuffXfermode(Mode.LIGHTEN));
bluePaint.setShader(new BitmapShader(blueChanImg, TileMode.CLAMP, TileMode.CLAMP));
bluePaint.setColorFilter(new PorterDuffColorFilter(Color.BLUE, Mode.DARKEN));

Paint alphaPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
alphaPaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));

c.setBitmap(resultImage);
c.drawRect(0, 0, width, height, redPaint);
c.drawRect(0, 0, width, height, greenPaint);
c.drawRect(0, 0, width, height, bluePaint);
c.drawBitmap(alphaImg, 0, 0, alphaPaint);

//save off resultImage, display it, etc...

使用上述代码和以下4幅图像(分别为红色、绿色、蓝色和alpha):

alt textalt textalt textalt text

我们得到以下结果:


alt text


请注意:红色椭圆是一个不透明的椭圆,位于透明背景上-颜色对于这个问题并不重要,但alpha值很重要。


啊!这正是我需要的。有点复杂,但看起来好像可以工作。 - Kleptine

0

当直接访问像素(字节)时,操作位图是一件相当简单的事情。在Android中,您可以通过以下方法实现:

ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos); 
byte[] b = bos.toByteArray();  

现在您可以进行任何您喜欢的图像操作、转换或组合。

我希望这正是您所寻找的。


不完全正确。我已经拥有了一个完全可编辑的位图,可以应用滤镜、变换等操作。但是我无法弄清如何单独编辑通道,而不是一次性编辑整个图像。 - Kleptine

0

你尝试过使用画布吗?以下代码看起来像是一个hack,但也许它会起作用。我自己没有测试过。

    Bitmap bitmap;
    int color = bitmap.getPixel(1, 123);
    Rect rect = new Rect(1,123,2,124);
    Canvas c = new Canvas(bitmap);
    c.clipRect(rect);
    c.drawARGB(50, Color.red(color), Color.green(color), Color.blue(color));


或者使用缓冲区,并直接从/写入颜色到位图中。bitmap.copyPixelsToBuffer(缓冲区dst) - Phyrum Tea
这对于简单操作肯定有效,但是逐像素访问太慢了,因为我需要实时完成。 - Kleptine
我明白了,您想使用灰度图像作为其他图像的 alpha 通道。我没有看到现成的方法。您可能需要直接访问缓冲区并自己在位级别上完成操作。 - Phyrum Tea
你看过Android源代码吗?可能有一种硬件加速的方法可以做到这一点。 - Phyrum Tea

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接