为什么我的 cairo_surface_t 绘图是半透明的?

Why is my cairo_surface_t drawing semi-transparent?

我正在尝试使用 C++ Cairo 和 Gtk 在 Ubuntu 上绘制一个 png 图像,其内容以 ARGB32 格式存储在内存中。

首先,我创建了一个 GtkDrawingArea,然后在它的公开事件中我从左上角到右下角绘制了一个带有红线的纯蓝色背景,然后我创建了一个表面并尝试将它绘制到绘图区域。这是我的公开事件回调:

unsigned char *pCairoBuf = ...

....

gboolean OnDrawingAreaExposeEvent(GtkWidget *pWidget, GdkEventExpose *pEvent, gpointer data)
{
    cairo_t *cr = gdk_cairo_create(pWidget->window);

    cairo_set_source_rgb(cr, 0.0, 0.0, 1.0);
    cairo_rectangle(cr, 0.0, 0.0, pEvent->area.width, pEvent->area.height);
    cairo_fill(cr);

    cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
    cairo_set_line_width(cr, 10.0);
    cairo_move_to(cr, 0.0, 0.0);
    cairo_line_to(cr, pEvent->area.width, pEvent->area.height);
    cairo_stroke(cr);

    // Use the existing buffer pCairoBuf that has (iRenderWidth * iRenderHeight * 4) bytes, 4 bytes per pixel for ARGB32 and zero row padding   
    cairo_surface_t *pSurface = cairo_image_surface_create_for_data(pCairoBuf, CAIRO_FORMAT_ARGB32, iRenderWidth, iRenderHeight, (iRenderWidth * 4));

    cairo_set_source_surface(cr, pSurface, 0.0, 0.0);
    cairo_paint(cr);

    cairo_destroy(cr);

    return TRUE;
}

绘图区域和图片都是244x278像素。该图像是 Smokey the Bear 的头部图像,头部周围是透明的:

我希望最终结果如下所示:

但它最终看起来像这样:

我没有添加显示我如何获得数据缓冲区 pCairoBuf 的代码,因为我认为它只会掩盖问题,但也许我错了?我认为我在处理开罗表面等方面做错了其他事情,这可以解释我所期望的和我得到的之间的区别。

在此先感谢您的帮助!

作为一个猜测,没有使用任何这些库,我会说你的 alpha 通道在你的图像上是统一的,并且渲染也将它应用到你想要不透明的图像部分。尝试仅将 alpha 通道应用于您希望透明的那些像素。

我明白了。当我在传递给 cairo_image_surface_create_for_data() 的缓冲区中填充 ARGB32 数据时,我按照 A、R、G、B 的顺序填充字节。作为实验,我颠倒了顺序并填充了字节 B、G、R、A,并且运行良好。