如何正确地采取截图与Xlib的? [英] How do take a screenshot correctly with xlib?

查看:838
本文介绍了如何正确地采取截图与Xlib的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图捕捉屏幕的图像在抓屏使用。因此,我需要一个快速的解决方案,而不能依靠shell程序,如进口或XWD。

这是code到目前为止,我已经写了,但它失败,给了我一个垃圾形象,这似乎只是显示多个图像的片段奇数颜色扔在一起。

这是什么,我做错了任何想法?

 的#include< X11 / Xlib.h>
#包括LT&; X11 / X.h>#包括LT&;&cstdio GT;
#包括LT&;&CImg.h GT;
使用命名空间cimg_library;诠释的main()
{
   显示*显示= XOpenDisplay(NULL);
   窗根= DefaultRootWindow(显示);   XWindowAttributes GWA;   XGetWindowAttributes(显示器,根,和放大器; GWA);
   INT宽度= gwa.width;
   INT高度= gwa.height;
   XImage *图像= XGetImage(显示器,根,0,0,宽度,高度,AllPlanes,ZPixmap);   无符号字符*阵列=新的无符号的char [宽*高* 3]。   无符号长red_mask =图像 - > red_mask;
   无符号长green_mask =图像 - > green_mask;
   无符号长blue_mask =图像 - > blue_mask;   对于(INT X = 0; X<宽度; X ++)
      对于(INT Y = 0; Y<高度; Y ++)
      {
         无符号长像素= XGetPixel(图像,X,Y);         unsigned char型蓝色=像素和放大器; blue_mask;
         unsigned char型绿色=(像素&安培; green_mask)GT;> 8;
         unsigned char型红色=(像素&安培; red_mask)GT;> 16;         数组[(X +宽* Y)* 3] =红色;
         数组[(X +宽* Y)* 3 + 1] =绿色;
         数组[(X +宽* Y)* 3 + 2] =蓝色;
      }   CIMG< unsigned char型> PIC(数组,宽度,高度,1,3);
   pic.save_png(blah.png);   的printf(%LD%LD%LD \\ N,red_mask>> 16,green_mask>> 8,blue_mask);   返回0;
}


解决方案

您是弄错的方式阵列在内存布局,因为你可以通过声明查出 IMG 循环之前,并添加此的printf 你内心的循环:

 的printf(%LD%LD%U%U%U \\ N,X,Y,pic.offset(X,Y​​,0),pic.offset(X, Y,1),pic.offset(X,Y​​,2));

这收益率(1920×1200我的屏幕上):

  0 0 0 2304000 4608000
0 1 1920 2305920 4609920
0 2 3840 2307840 4611840

和等等,表明红/绿/蓝子图像被保持为合,而不是一个单一的象素被彼此相邻的三个颜色成分

在内置CIMG访问将让您的code的工作:

 照片(X,Y,0)=红色;
     PIC(X,Y,1)=绿色;
     PIC(X,Y,2)=蓝色;

I am trying to capture an image of the screen for use in screencasting. Thus I need a fast solution, and cannot rely on shell programs such as import or xwd.

This is the code I have written so far, but it fails and gives me a junk image, which just seems to show fragments of several images with odd colors tossed together.

Any ideas on what I am doing wrong?

#include <X11/Xlib.h>
#include <X11/X.h>

#include <cstdio>
#include <CImg.h>
using namespace cimg_library;

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

   XWindowAttributes gwa;

   XGetWindowAttributes(display, root, &gwa);
   int width = gwa.width;
   int height = gwa.height;


   XImage *image = XGetImage(display,root, 0,0 , width,height,AllPlanes, ZPixmap);

   unsigned char *array = new unsigned char[width * height * 3];

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

   for (int x = 0; x < width; x++)
      for (int y = 0; y < height ; y++)
      {
         unsigned long pixel = XGetPixel(image,x,y);

         unsigned char blue = pixel & blue_mask;
         unsigned char green = (pixel & green_mask) >> 8;
         unsigned char red = (pixel & red_mask) >> 16;

         array[(x + width * y) * 3] = red;
         array[(x + width * y) * 3+1] = green;
         array[(x + width * y) * 3+2] = blue;
      }

   CImg<unsigned char> pic(array,width,height,1,3);
   pic.save_png("blah.png");

   printf("%ld %ld %ld\n",red_mask>> 16, green_mask>>8, blue_mask);

   return 0;
}

解决方案

You are mistaken about the way array is laid out in memory, as you can find out by declaring img before the loop and adding this printf to your inner loop:

printf("%ld %ld %u %u %u\n",x,y,pic.offset(x,y,0),pic.offset(x,y,1),pic.offset(x,y,2));

This yields (on my 1920x1200 screen):

0 0 0 2304000 4608000
0 1 1920 2305920 4609920
0 2 3840 2307840 4611840

and so on, indicating that the red/green/blue subimages are kept "together" instead of the three color components of a single pixel being adjacent to each other.

The builtin CImg accessors will make your code work:

     pic(x,y,0) = red;
     pic(x,y,1) = green;
     pic(x,y,2) = blue;

这篇关于如何正确地采取截图与Xlib的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆