我有一个格式为 CV_8UC1 的矩阵图像,即单色图像数据的每个像素一个字节。我需要使用 Cairo 绘制这个矩阵图像,即绘制到 Gtk 绘图区域。速度至关重要,因为该图像会快速更新,我需要非常快地重绘。
使用 Cairo 绘制此矩阵图像的最佳/最快方法是什么?我尝试将其转换为开罗表面,但找不到可以将其转换为开罗表面可接受的 OpenCV 格式。
例如,如果我将矩阵图像转换为 CV_32S,然后创建格式类型为 CAIRO_FORMAT_RGB24 的表面,它将运行,但图像非常蓝色,表明数据存储类型之间存在不匹配。
我有一个格式为 CV_8UC1 的矩阵图像,即单色图像数据的每个像素一个字节。
这听起来很像
CAIRO_FORMAT_A8
,除了 cairo 将该一个字节解释为 alpha / 透明度,而不是单色颜色。
一定要看看
cairo_image_surface_get_stride()
。我认为 cairo 要求每行像素数据都与一个四字节地址对齐。
换句话说:如果图像数据的宽度为 5 像素,那么 cairo 期望每行以 3 字节的填充结束。
如果这些要求意味着您的图像数据不是 cairo 支持的格式,则意味着您必须复制数据以将其转换为支持的格式。
我需要使用 Cairo 绘制这个矩阵图像,即绘制到 Gtk 绘图区域。
将一些字节绘制到图像表面的快速示例:
#include <cairo.h>
static unsigned char image_data[] = {
// First row
0, 255,
// Padding
0, 0,
// Second row
64, 192,
// Padding
0, 0,
};
static cairo_surface_t *get_source(void) {
return cairo_image_surface_create_for_data(image_data, CAIRO_FORMAT_A8, 2, 2, 4);
}
static void draw(cairo_t *cr) {
cairo_surface_t *source = get_source();
// Fill everything black
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_paint(cr);
// Draw the image in white on top
cairo_set_source_rgb(cr, 1, 1, 1);
cairo_mask_surface(cr, source, 3, 3);
// Just because: Also draw it in red
cairo_set_source_rgb(cr, 1, 0, 0);
cairo_mask_surface(cr, source, 6, 6);
cairo_surface_destroy(source);
}
int main() {
cairo_surface_t *target = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 10, 10);
cairo_t *cr = cairo_create(target);
draw(cr);
cairo_destroy(cr);
cairo_surface_write_to_png(target, "output.png");
cairo_surface_destroy(target);
return 0;
}
输出(是的,这仅绘制 2x2 单色图像;一次为白色,一次为红色)
速度至关重要,因为该图像会快速更新,我需要非常快地重绘。
那么数据从哪里来呢?例如,您可以使用
cairo_surface_create_similar_image()
。这会在共享内存中分配图像数据(您可以使用 cairo_image_surface_get_data()
进行修改)。这将(有时)允许 cairo 避免将图像数据复制到显示服务器。
我想到的另一件事是:数据多久更改一次?如果只是有时发生变化,请务必重复使用相同的 cairo 表面。 如果 cairo 必须将图像数据上传到某个地方,它可以保存上传以供以后重复使用(这在 cairo 代码库中内部称为“附加快照”)。
但基本上:我想我对这部分问题的了解还不够多,无法说出任何有用的信息。