Skip to content

Instantly share code, notes, and snippets.

@brccabral
Last active October 21, 2023 02:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brccabral/4c988fc4fff3f6321d675e46935e3e74 to your computer and use it in GitHub Desktop.
Save brccabral/4c988fc4fff3f6321d675e46935e3e74 to your computer and use it in GitHub Desktop.
Screen Capture

Screen Capture

C++

Linux

Get the pixels from X11 display and open the image in OpenCV window. Wayland yet to find out.

apt install libopencv-dev

Compile with -lX11 pkg-config --cflags --libs opencv4

Python

Xlib provides better performance than pyautogui, PIL.ImageGrab or pyscreenshot.ImageGrab

pip install pillow
pip install python3-xlib
cmake_minimum_required(VERSION 3.21)
project(ScreenCapture)
include(GNUInstallDirs)
find_package(OpenCV CONFIG REQUIRED)
message("OpenCV_INCLUDE_DIRS ${OpenCV_INCLUDE_DIRS}")
message("OpenCV_LIBRARIES ${OpenCV_LIBRARIES}")
add_executable(${PROJECT_NAME} main.cpp)
target_include_directories(${PROJECT_NAME} PUBLIC ${OpenCV_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PUBLIC X11)
target_link_libraries(${PROJECT_NAME} PUBLIC ${OpenCV_LIBRARIES})
install(TARGETS ${PROJECT_NAME})
#include <opencv4/opencv2/opencv.hpp>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <cstdint>
#include <cstring>
#include <vector>
using namespace cv;
void ImageFromDisplay ( Display* display, std::vector<uint8_t>& Pixels, int& Width, int& Height, int& BitsPerPixel )
{
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 );
}
int main()
{
Display* display = XOpenDisplay ( nullptr );
if ( display == NULL )
{
std::cout << "Can't open display" << std::endl;
return 1;
}
int Width = 0;
int Height = 0;
int Bpp = 0;
std::vector<std::uint8_t> Pixels;
ImageFromDisplay ( display,Pixels, Width, Height, Bpp );
if ( Width && Height )
{
// Mat(Size(Height, Width), Bpp > 24 ? CV_8UC4 : CV_8UC3, &Pixels[0]);
Mat img = Mat ( Height, Width, Bpp > 24 ? CV_8UC4 : CV_8UC3, &Pixels[0] );
namedWindow ( "WindowTitle", WINDOW_AUTOSIZE );
imshow ( "Display window", img );
waitKey ( 0 );
}
XCloseDisplay ( display );
return 0;
}
from Xlib import display, X
from PIL import Image
W, H = 200, 200
dsp = display.Display()
try:
root = dsp.screen().root
raw = root.get_image(0, 0, W, H, X.ZPixmap, 0xFFFFFFFF)
image = Image.frombytes("RGB", (W, H), raw.data, "raw", "BGRX")
image.show()
finally:
dsp.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment