user2062604
user2062604

Reputation: 275

Why is my cairo_surface_t drawing semi-transparent?

I am trying to draw a png image, the contents of which I have in memory in an ARGB32 format, using C++ Cairo and Gtk on Ubuntu.

First, I create a GtkDrawingArea, then on its expose-event I draw a solid blue background with a red line from top left to bottom right, then I create a surface and try to draw it onto the drawing area. Here's my expose-event callback:

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;
}

The drawing area and the image are both 244x278 pixels. The image is an image of Smokey the Bear's head and is transparent around his head:

enter image description here

And I expect the final result to look like this:

enter image description here

But it ends up looking like this:

enter image description here

I did not add the code that shows how I got the data buffer pCairoBuf because I figured it would only cloud the issue, but perhaps I'm wrong? I figured that there's something else I'm doing wrong having to do with cairo surfaces, etc. that would explain the difference between what I'm expecting and what I'm getting.

Thanks in advance for any help!

Upvotes: 3

Views: 997

Answers (2)

user2062604
user2062604

Reputation: 275

I figured it out. When I was filling in the ARGB32 data in the buffer that I pass to cairo_image_surface_create_for_data(), I was filling in the bytes in that order, A, R, G, B. As an experiment I reversed the order and filled in the bytes B, G, R, A, and it worked perfectly.

Upvotes: 0

mrtimdog
mrtimdog

Reputation: 497

As a guess, not having used any of those libraries, I'd say your alpha channel's uniform across your image and the rendering's applying this also to the parts of the image you'd like non-transparent. Try only applying the alpha channel to those pixels which you'd like to be transparent.

Upvotes: 1

Related Questions