用 Cairo 绘制 CV_8UC1 矩阵图像的最佳方法是什么?

问题描述 投票:0回答:1

我有一个格式为 CV_8UC1 的矩阵图像,即单色图像数据的每个像素一个字节。我需要使用 Cairo 绘制这个矩阵图像,即绘制到 Gtk 绘图区域。速度至关重要,因为该图像会快速更新,我需要非常快地重绘。

使用 Cairo 绘制此矩阵图像的最佳/最快方法是什么?我尝试将其转换为开罗表面,但找不到可以将其转换为开罗表面可接受的 OpenCV 格式。

例如,如果我将矩阵图像转换为 CV_32S,然后创建格式类型为 CAIRO_FORMAT_RGB24 的表面,它将运行,但图像非常蓝色,表明数据存储类型之间存在不匹配。

c opencv image-processing gtk cairo
1个回答
0
投票

我有一个格式为 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 单色图像;一次为白色,一次为红色)

enter image description here

速度至关重要,因为该图像会快速更新,我需要非常快地重绘。

那么数据从哪里来呢?例如,您可以使用

cairo_surface_create_similar_image()
。这会在共享内存中分配图像数据(您可以使用
cairo_image_surface_get_data()
进行修改)。这将(有时)允许 cairo 避免将图像数据复制到显示服务器。

我想到的另一件事是:数据多久更改一次?如果只是有时发生变化,请务必重复使用相同的 cairo 表面。 如果 cairo 必须将图像数据上传到某个地方,它可以保存上传以供以后重复使用(这在 cairo 代码库中内部称为“附加快照”)。

但基本上:我想我对这部分问题的了解还不够多,无法说出任何有用的信息。

© www.soinside.com 2019 - 2024. All rights reserved.