Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ fast screenshots in linux for use with opencv

I'm trying to find a fast way to take screenshots (as in 30 fps or over) for use with opencv in c++

All the information I've found online either involved windows.h or were too slow.

Could someone provide me with some code that achieves this or at least point me in the right direction so I can solve this my self?

like image 404
user237330 Avatar asked Jul 28 '14 03:07

user237330


1 Answers

You can use this to get the screenshot into a structure of raw pixels. Pass that to OpenCV along with the Width & Height & BitsPerPixel and you should be good.

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <cstdint>
#include <cstring>
#include <vector>

void ImageFromDisplay(std::vector<uint8_t>& Pixels, int& Width, int& Height, int& BitsPerPixel)
{
    Display* display = XOpenDisplay(nullptr);
    Window root = DefaultRootWindow(display);

    XWindowAttributes attributes = {0};
    XGetWindowAttributes(display, root, &attributes);

    Width = attributes.width;
    Height = attributes.height;

    XImage* img = XGetImage(display, root, 0, 0 , Width, Height, AllPlanes, ZPixmap);
    BitsPerPixel = img->bits_per_pixel;
    Pixels.resize(Width * Height * 4);

    memcpy(&Pixels[0], img->data, Pixels.size());

    XDestroyImage(img);
    XCloseDisplay(display);
}

Then to use it with OpenCV, you can do:

int main()
{
    int Width = 0;
    int Height = 0;
    int Bpp = 0;
    std::vector<std::uint8_t> Pixels;

    ImageFromDisplay(Pixels, Width, Height, Bpp);

    if (Width && Height)
    {
        Mat img = Mat(Height, Width, Bpp > 24 ? CV_8UC4 : CV_8UC3, &Pixels[0]); //Mat(Size(Height, Width), Bpp > 24 ? CV_8UC4 : CV_8UC3, &Pixels[0]); 

        namedWindow("WindowTitle", WINDOW_AUTOSIZE);
        imshow("Display window", img);

        waitKey(0);
    }
    return 0;
}
like image 107
Brandon Avatar answered Sep 24 '22 16:09

Brandon