0

I would like to perform screenshots (or screen captures) the fastest possible.

Googling this question brings many answeers but my concern is more specific :

I am not interested in the image itself, I would like to grab in near real time the screen brightness, not the hardware one, but the image one, given that, for example, the firefox white google page gives a brighter image than a dark xterm (when both are maximzed).

To make me as clear as possible, here is one way I already managed to implement with X11 and CImg library :

Here is the header :

#include <CImg.h>
using namespace cimg_library;

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>

and the core part which extract an X11 image and make a loop on very pixel :

Display *display = XOpenDisplay(NULL);
Window root = DefaultRootWindow(display);

Screen* screen = DefaultScreenOfDisplay(display);

const int W = WidthOfScreen(screen);
const int H = HeightOfScreen(screen);

XImage *image = XGetImage(display, root, 0, 0, W, H, AllPlanes, ZPixmap);

unsigned long red_count(0), green_count(0), blue_count(0), count(0);

const unsigned long red_mask = image->red_mask;
const unsigned long green_mask = image->green_mask;
const unsigned long blue_mask = image->blue_mask;

CImg<unsigned char> screenshot(W, H, 1, 3, 0);

for (int x = 0; x < W; x += pixel_stride)
  for (int y = 0; y < H; y += pixel_stride)
    {
      unsigned long pixel = XGetPixel(image, x, y);

      screenshot(x, y, 0) = (pixel & red_mask) >> 16;
      screenshot(x, y, 1) = (pixel & green_mask) >> 8;
      screenshot(x, y, 2) = pixel & blue_mask;

      red_count += (int) screenshot(x, y, 0);
      green_count += (int) screenshot(x, y, 1);
      blue_count += (int) screenshot(x, y, 2);

      count++;
   }

As I said, I do not keep the image itself, I just try to compute an average luminance value with respective values of red, green and blue pixels.

XFree(image);

const double luminance_relative = (red_luminance * double(red_count) +
                                  green_luminance * double(green_count) +
                                  blue_luminance * double(blue_count))
    / (double(255) * double(count));

The underlying idea is to adjust the hardware screen brightness depending on the image luminance. In short, the whiter is the screenshot, the more the brightness can be reduced and conversely.

I want to do that because I have sensitive eyes, it usually hurts my eyes when I switch from xterm to firefox.

To do so, the hardware brightness must be adjusted in a very short time, the screenshot, that is to say, the loop on pixels must be as fast as possible.

I began to implement it with X11 methods, but I wonder if there could be faster access methods ? Which comes to the question : what is the fastest way/library to get a screenshot ?

Thanks in advance for your help.

Regards

deb2014
  • 89
  • 7
  • 1
    What OS exactly? Linux, I assume? – alexis Jan 23 '17 at 20:13
  • I have not benchmarked screenshotting itself, but based on other image processing tests I have done, I would be very surprised if OpenCV does not calculate the average brightness 4-20x faster than CImg. Have you measured the screen grab time using C++ hi-res chrono routines and the corresponding processing time? Does your machine have GPU that OpenCV can make use of? – Mark Setchell Jan 23 '17 at 21:12
  • alexis : Linux; Mark : GPU = intel GMA (module linux is i915). The cpu time is measured with clock_t begin = clock(); – deb2014 Jan 24 '17 at 12:51
  • I found this page which uses openGL and openCV, it seems quite close to what I want : ( https://varuagdiary.blogspot.fr/2012/1/opengl-screenshot-using-opencv.html). I also found this page : (https://stackoverflow.com/questions/9097756/converting-data-from-glreadpixels-to-opencvmat) which mentions GL_LUMINANCE, which seems to match exactly what I am looking about. But I just do not know how to make a program based on this on Linux. – deb2014 Jan 24 '17 at 13:44

0 Answers0