Android 更改位图图像特定部分的颜色

Android 更改位图图像特定部分的颜色,android,colors,bitmap,Android,Colors,Bitmap,我正在编写一个Android应用程序,它必须根据接收到的事件绘制加载位图图像的确定部分 我需要绘制(或更改当前颜色)位图图像的单个部分,而不更改图像的其余部分 比如说,我有一辆车,它由许多部分组成:车门、车窗、车轮等。 每次事件(从网络接收)到达时,我都需要使用事件数据指定的颜色更改该特定部分的颜色。 实现这一目标的最佳技术是什么 我首先想到了FloodFill,正如在SO中的许多线程中所建议的那样,但是由于消息接收速度非常快(每秒几次),我担心这会降低性能,因为它似乎是非常CPU密集型的算法

我正在编写一个Android应用程序,它必须根据接收到的事件绘制加载位图图像的确定部分

我需要绘制(或更改当前颜色)位图图像的单个部分,而不更改图像的其余部分

比如说,我有一辆车,它由许多部分组成:车门、车窗、车轮等。 每次事件(从网络接收)到达时,我都需要使用事件数据指定的颜色更改该特定部分的颜色。 实现这一目标的最佳技术是什么

我首先想到了FloodFill,正如在SO中的许多线程中所建议的那样,但是由于消息接收速度非常快(每秒几次),我担心这会降低性能,因为它似乎是非常CPU密集型的算法

我还考虑过将同一个图像分成多个部分,每个部分用不同的颜色,并在正确的时间显示正确的部分,但汽车至少有10个不同的零件,每个零件都可以涂上4-6种颜色,因此我最终会得到几十个图像,这将是不切实际的处理,更不用说浪费记忆了


那么,还有其他方法吗?

最快的方法是使用着色器。为此,您需要使用OpenGL ES 2(一些Androids仅支持ES 1)。您需要一个与要更改的图像大小相同的临时位图。把它作为目标。在着色器中,从采样器中检索绑定到要更改的图像的像素。如果它在您想要更改的颜色的小公差范围内,请将gl_FragColor设置为新颜色,否则只需将gl_FragColor设置为从采样器检索到的颜色。您需要使用
al\u set\u shader\u float\u vector
将所需颜色和新颜色作为vec4s传递到着色器中。最快的方法是保留2个位图,并在它们之间交换,作为每次颜色变化时使用的“主位图”

如果不能使用着色器,则必须锁定位图并替换颜色。使用
al_lock_bitmap
将其锁定,然后可以使用
al_get_pixel
al_put_pixel
更改颜色。完成后,单击“解锁”位图。您还可以避免使用al_get_pixel/al_put_pixel并手动访问内存,这样会更快。如果使用格式
ALLEGRO\u PIXEL\u format\u ABGR\u 8888\u LE
锁定位图,则内存布局如下:


int w=位图宽度(位图);
int h=位图高度(位图);
对于(int y=0;y数据+锁定的字符区域->基音*y;
对于(int x=0;x


建议您以创建图像时使用的格式锁定图像。这意味着选择一个像我提到的那样简单的循环,否则循环的内部部分会变得更复杂。像素格式的ABGR_8888部分描述了数据的布局。ABGR指示组件的顺序。如果要将一个像素读入单个存储单元(在本例中为int,但对short的作用相同),那么位模式将是
aaaaaaaaaaaaaabbbbgggggg rrrrrrrrr
。然而,当您一次读取一个字节时,大多数机器都是小端,这意味着小端优先。这就是为什么在我的示例代码中p[0]是红色的。8888部分显示每个组件的位数。

不能两全其美——如果你想获得令人眼花缭乱的速度,应该对它们进行预渲染。我看不出有什么真正的问题。由于不太了解实际的“零件”定义等,因此很难提供有意义的速度比较。零件本身并不复杂-这是一张风格化的图纸-我相信它们会画得很快。我担心的是零件x颜色组合的数量。我还考虑过为每个部分绘制单独的透明图像,用适当的颜色绘制它们,并在现有的完整图像上绘制,但不知道如何精确定位到正确的坐标。