반응형
xlib으로 스크린샷을 제대로 찍는 방법은?
스크린캐스팅에 사용할 화면 이미지를 캡쳐하려고 합니다.따라서 빠른 해결책이 필요하며, import나 xwd와 같은 shell 프로그램에 의존할 수 없습니다.
이것이 지금까지 제가 작성한 코드인데 실패해서 이상한 색을 가진 여러 이미지의 조각을 보여주는 것처럼 보이는 정크 이미지가 됩니다.
내가 무엇을 잘못하고 있는지에 대한 아이디어가 있습니까?
#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;
}
당신은 길을 잘못 알고 있습니다.array
메모리에 저장되어 있습니다. 선언을 통해 알 수 있듯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));
결과(1920x1200 화면에서):
0 0 0 2304000 4608000
0 1 1920 2305920 4609920
0 2 3840 2307840 4611840
단일 픽셀의 세 가지 색상 구성 요소가 서로 인접하는 대신 빨간색/녹색/파란색 하위 이미지가 "함께" 유지된다는 것을 나타내는 등입니다.
내장된 CImg 액셀러레이터를 통해 코드가 작동합니다.
pic(x,y,0) = red;
pic(x,y,1) = green;
pic(x,y,2) = blue;
libpng를 사용할 수 있습니다.
int code = 0;
FILE *fp;
png_structp png_ptr;
png_infop png_info_ptr;
png_bytep png_row;
// Open file
fp = fopen ("test.png", "wb");
if (fp == NULL){
fprintf (stderr, "Could not open file for writing\n");
code = 1;
}
// Initialize write structure
png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL){
fprintf (stderr, "Could not allocate write struct\n");
code = 1;
}
// Initialize info structure
png_info_ptr = png_create_info_struct (png_ptr);
if (png_info_ptr == NULL){
fprintf (stderr, "Could not allocate info struct\n");
code = 1;
}
// Setup Exception handling
if (setjmp (png_jmpbuf (png_ptr))){
fprintf(stderr, "Error during png creation\n");
code = 1;
}
png_init_io (png_ptr, fp);
// Write header (8 bit colour depth)
png_set_IHDR (png_ptr, png_info_ptr, width, height,
8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
// Set title
char *title = "Screenshot";
if (title != NULL){
png_text title_text;
title_text.compression = PNG_TEXT_COMPRESSION_NONE;
title_text.key = "Title";
title_text.text = title;
png_set_text (png_ptr, png_info_ptr, &title_text, 1);
}
png_write_info (png_ptr, png_info_ptr);
// Allocate memory for one row (3 bytes per pixel - RGB)
png_row = (png_bytep) malloc (3 * width * sizeof (png_byte));
// Write image data
int x, y;
for (y = 0; y < height; y++){
for (x = 0; x < width; x++){
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;
png_byte *ptr = &(png_row[x*3]);
ptr[0] = red;
ptr[1] = green;
ptr[2] = blue;
}
png_write_row (png_ptr, png_row);
}
// End write
png_write_end (png_ptr, NULL);
// Free
fclose (fp);
if (png_info_ptr != NULL) png_free_data (png_ptr, png_info_ptr, PNG_FREE_ALL, -1);
if (png_ptr != NULL) png_destroy_write_struct (&png_ptr, (png_infopp)NULL);
if (png_row != NULL) free (png_row);
이미지는 R1R2R3R4R5R6로 메모리에 저장되어야 합니다...G1G2G3G4G5G6...B1B2B3B4B5B6. cimg 스토리지
언급URL : https://stackoverflow.com/questions/8249669/how-do-take-a-screenshot-correctly-with-xlib
반응형
'source' 카테고리의 다른 글
"while true"는 파이썬에서 무엇을 의미합니까? (0) | 2023.10.08 |
---|---|
두 jQuery 결과를 결합하는 방법 (0) | 2023.10.08 |
jQuery로 전화번호 서식 지정하는 방법 (0) | 2023.10.08 |
다른 조건이 있는 경우 도커 파일(외부 인수 포함) (0) | 2023.10.08 |
Oracle Session이란? (0) | 2023.10.08 |