How to get a PNG (alpha channel) screenshot of Gtk window?
Asked Answered
D

2

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");   
}
Defluxion answered 28/3, 2012 at 0:53 Comment(3)
kinda hard to see on your screenshot if the resulting image has alpha or not...Daltondaltonism
It has black pixels where the alpha are.Defluxion
Thanks for sharing your solution. Im in need of a simple way to get screenshots of screens (multi-monitors) I was wondeirng if you found this solution to do that?Custumal
D
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.

Daltondaltonism answered 28/3, 2012 at 8:1 Comment(0)
E
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.

Echovirus answered 7/6, 2012 at 23:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.