首页 > 解决方案 > 如何使用 stbi_load 从 cairo_image_surface_create_for_data 渲染图像?

问题描述

我正在使用 Cairo 渲染图像,但我遇到的问题是画布总是用空白绘制(没有绘制图像)。请参考我下面的代码:

int width, height, channels;
unsigned char* data = stbi_load(imagePath.c_str(), &width, &height, &channels, STBI_rgb_alpha);
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
this->imageSource = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, stride);
free(data);

但是,如果我使用 Cairo 当前支持的功能渲染 png 文件,它运行良好,我的代码如下:

this->imageSource = cairo_image_surface_create_from_png(imagePath.c_str());

标签: c++linuxcairostb-image

解决方案


问题是我自己发现的。因为内存是空闲的,所以cairo的数据指针指向的是空数据。我通过使用 cairo 的其他 api (cairo_image_surface_create) 而不是 cairo_image_surface_create_for_data 解决了这个问题。请参阅下面的代码:

//define params
int width, height, channels;
//read image data from file using stb_image.h
unsigned char* data = stbi_load(imagePath.c_str(), &width, &height, &channels, STBI_rgb_alpha);
//create surface with image size and format is ARGB32
this->imageSource = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
//get pointer of cairo data
unsigned char * surface_data = cairo_image_surface_get_data(this->imageSource);
//copy current data to surface pointer
memcpy(surface_data, data, width * height * 4 * sizeof(unsigned char));
//mark as dirty to refresh surface
cairo_surface_mark_dirty(this->imageSource);
//free image data
free(data);

推荐阅读