使用Xlib和Cairo库制作屏幕截图[失败] [英] Making a screenshot using Xlib and Cairo libs [fail]

查看:207
本文介绍了使用Xlib和Cairo库制作屏幕截图[失败]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Xlib Cairo 制作屏幕截图,但是我不确定这样做是否很好,大步向前"确实让我感到困惑

I'm trying to make a screenshot using Xlib and Cairo, however I'm not sure to do it the good way, "stride" is really confusing me.

这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <cairo.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

int main(int argc, char** argv) {

    int x, y;

    Display *disp;
    Window root;
    XWindowAttributes watts;
    XImage *image;
    cairo_surface_t *surface;
    unsigned int width;
    unsigned int height;
    int stride;

    disp = XOpenDisplay(NULL);
    root = DefaultRootWindow(disp);
    XGetWindowAttributes(disp, root, &watts);
    width = watts.width;
    height = watts.height;

    image = XGetImage(disp, root, watts.x, watts.y, width, height, AllPlanes, ZPixmap);
    stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, width);
    unsigned char *data = malloc(width * height * 3);

    for (y = 0; y < height; ++y)
        for (x = 0; x < width; ++x) {

            unsigned long pixel = XGetPixel(image, x, y);

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

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


    surface = cairo_image_surface_create_for_data(
            data,
            CAIRO_FORMAT_RGB24,
            width, height,
            stride);

    cairo_surface_write_to_png(
            surface,
            "test.png");


    cairo_surface_destroy(surface);
    free(data);

    return (EXIT_SUCCESS);
}

当我编译并运行程序时,一切似乎都可以正常工作.但是,这是生成的图像:

When I compile and run the program, everything seems to work just fine. However here's the resulting image :

一团糟吧? 我可能做错了什么?

推荐答案

TFM:

CAIRO_FORMAT_RGB24
    each pixel is a 32-bit quantity, with the upper 8 bits unused

TFM:

stride = cairo_format_stride_for_width (format, width);
data = malloc (stride * height);

因此,正确的索引计算是

Hence, the correct index calculation is

data[y * stride + x * 4 + 0] = blue;
data[y * stride + x * 4 + 1] = green;
data[y * stride + x * 4 + 2] = red;    /* yes, in this order */

此外,还从图像中获取了蒙版,并对移位进行了硬编码,这绝对没有意义.计算蒙版的偏移量.

Also, masks are taken from the image and shifts are hard-coded, which makes absolutely no sense. Calculate the shifts from the masks.

这篇关于使用Xlib和Cairo库制作屏幕截图[失败]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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