Android 位图遮罩颜色、移除颜色
我正在创建位图,接下来我在其上绘制第二个纯色位图。 现在我想更改第一个位图,因此我在其上绘制的纯色将是透明的。
或者简单地说,我想从位图中删除一种颜色的所有像素。 我尝试了所有滤色器和 xfermode,但没有成功,除了逐像素去除颜色之外,还有其他可能性吗?
I am creating bitmap, next i am drawing second solid color bitmap on top of it.
And now i want to change first bitmap, so solid color that i drawed on it will be transparent.
Or simply, i want to remove all pixels of one color from bitmap.
I havie tried every colorfilter, and xfermode with no luck, is there any other possibility to remove color other that doing it pixel by pixel?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这适用于从位图中删除某种颜色。主要部分是AvoidXfermode的使用。如果尝试将一种颜色更改为另一种颜色,它也应该有效。
我应该补充一点,这回答了从位图中删除颜色的问题标题。正如OP所说,使用PorterDuff Xfermode可能可以更好地解决具体问题。
This works for removing a certain color from a bitmap. The main part is the use of AvoidXfermode. It should also work if trying to change one color to another color.
I should add that this answers the question title of removing a color from a bitmap. The specific question is probably better solved using PorterDuff Xfermode like the OP said.
user487252 的解决方案在 API 级别 16 (Jelly Bean) 之前一直有效,之后
AvoidXfermode
似乎根本不起作用。在我的特定用例中,我已将 PDF 页面(通过 APV PDFView)渲染为像素数组
int[]
,我将其传递到Bitmap.createBitmap( int[] ,int,int,Bitmap.Config)
。此页面包含绘制在白色背景上的线条艺术,我需要删除背景,同时保留抗锯齿功能。我找不到完全符合我要求的 Porter-Duff 模式,因此我最终对像素进行了扭曲和迭代,然后将它们一一转换。结果出人意料地简单且高性能:
这非常适合绘制线条艺术,因为任何颜色都可以用于线条而不会失去抗锯齿功能。我在这里使用红色通道,但您可以通过移位
16
位而不是8
使用绿色通道,或者通过移位24
使用蓝色通道。user487252's solution works like a charm up until API level 16 (Jelly Bean), after which
AvoidXfermode
does not seem to work at all.In my particular use case, I have rendered a page of a PDF (via APV PDFView) into a pixel array
int[]
that I am going to pass intoBitmap.createBitmap( int[], int, int, Bitmap.Config )
. This page contains line art drawn onto a white background, and I need to remove the background while preserving the anti-aliasing.I couldn't find a Porter-Duff mode that did exactly what I wanted, so I ended up buckling and iterating through the pixels and transforming them one by one. The result was surprisingly simple and performant:
This is perfect for drawing line art, since any color can be used for the lines without losing the anti-aliasing. I'm using the red channel here, but you can use green by shifting
16
bits instead of8
, or blue by shifting24
.逐个像素并不是一个坏的选择。只是不要在循环内调用 setPixel 。使用 getPixels 填充 argb int 数组,如果不需要保留原始值,则就地修改它,然后在最后调用 setPixels。如果内存是一个问题,您可以逐行执行此操作,或者您可以一次完成整个操作。您不需要为覆盖颜色填充整个位图,因为您只需进行简单的替换(如果当前像素为 color1,则设置为 color2)。
Pixel by pixel is not a bad option. Just don't call setPixel inside your loop. Fill an array of argb ints with getPixels, modify it in place if you don't need to preserve the original, and then call setPixels at the end. You can do this row-by-row if memory is a concern, or you can just do the whole thing in one shot. You don't need to fill a whole bitmap for your overlay color since you'd just be doing a simple replace (if current pixel is color1, set to color2).