1

Gtk windows support transparency using Cairo. I tried to get a screenshot with the code here. But it prints pure black for windows that use transparency. How can I make a screenshot (PNG) which caputures the alpha channel too?

EDIT: I tried with alpha pixbuf, but the output is still with no alpha. Here's my code (sing Gtk#, but it's pretty identical to C):

static void GetScreenshot(Gtk.Window win) {
    var pixbuf = new Gdk.Pixbuf(Gdk.Colorspace.Rgb, true, 8, 500, 500);
    var pix = pixbuf.GetFromDrawable(win.GdkWindow, win.Colormap, 0, 0, 0, 0, 500, 500);    

    pix.Save("/home/blez/Desktop/screenshot.png", "png");
} 

Here's the output: enter image description here

EDIT: I did it with Cairo surface. Here's the code I used:

static void GetScreenshot(Gtk.Window win) {
    var src_context = Gdk.CairoHelper.Create(win.GdkWindow);
    var src_surface = src_context.Target;
    var dst_surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, win.Allocation.Width, win.Allocation.Height);
    var dst_context = new Cairo.Context(dst_surface);
    dst_context.SetSourceSurface(src_surface, 0, 0);
    dst_context.Paint();
    dst_surface.WriteToPng("screenshot.png");   
}
Community
  • 1
  • 1
blez
  • 4,939
  • 5
  • 50
  • 82

2 Answers2

2

In your example, the answer lies on the gdk_pixbuf_get_from_drawable call. The documentation explicitely says:

If the specified destination pixbuf dest is NULL, then this function will create an RGB pixbuf with 8 bits per channel and no alpha, with the same size specified by the width and height arguments. In this case, the dest_x and dest_y arguments must be specified as 0. If the specified destination pixbuf is not NULL and it contains alpha information, then the filled pixels will be set to full opacity (alpha = 255).

So I think that passing a pixbuf with an alpha channel as the first argument should be enough.

Another way to do it is to use the cairo API, which would work with GTK 2 and GTK 3.

liberforce
  • 11,189
  • 37
  • 48
0

...and how you want an alpha chanel in

var pixbuf = new Gdk.Pixbuf(Gdk.Colorspace.Rgb, true, 8, 500, 500);  ?

If it has transparency (real one) then is rgba. But you may still have problems with the window manager, if it is not composit but mimic this by blending images, will return black ( 0 ) instead of color/alpha value.

cox
  • 731
  • 5
  • 12