首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从位图图像的特定部分更改颜色

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

Stack Overflow用户
提问于 2013-08-05 23:57:34
回答 1查看 586关注 0票数 0

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

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

我首先想到的是FloodFill,正如许多线程所建议的那样,但是考虑到消息的接收速度非常快(每秒几个),我担心它会拖累性能,因为它似乎是非常消耗CPU的算法。

我也考虑过同一张图片的多个部分,每个部分都有不同的颜色,并在正确的时间显示正确的部分,但是汽车至少有10个不同的部分,每个部分可以被涂上4-6种颜色,所以我最终会得到几十个图像,这将是不切实际的,更不用说浪费内存了。

那么,有没有其他的方法呢?

EN

回答 1

Stack Overflow用户

发布于 2016-06-18 15:16:00

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

如果您不能使用着色器,那么您将不得不锁定位图并替换颜色。使用al_lock_bitmap锁定它,然后可以使用al_get_pixelal_put_pixel更改颜色。完成后再使用al_unlock_bitmap。您也可以避免使用al_get_pixel/al_put_pixel,而手动访问内存,这样会更快。如果使用ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE格式锁定位图,则内存布局如下:

代码语言:javascript
运行
复制
 `int w = al_get_bitmap_width(bitmap);     int h = al_get_bitmap_height(bitmap);     for (int y = 0; y < h; y++) {         unsigned char *p = locked_region->data + locked_region->pitch * y;         for (int x = 0; x < w; x++) {             unsigned char r = p[0];             unsigned char g = p[1];             unsigned char b = p[2];             unsigned char a = p[3];             /* change r, g, b, a here if they match */             p[0] = r;             p[1] = g;             p[2] = b;             p[3] = a;             p += 4;         }     }` 

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18062524

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档