使用Imagemagick API进行截图

3
我正在使用GCC 4.7.2、C89和ImageMagick-6.8.0-4。
我正在尝试使用ImageMagick API进行屏幕截图。我已经下载、编译和安装了头文件和库文件。
但是,在文档中,我找不到执行截图的API调用。我将链接和包含头文件以便从我的C程序中调用API。我只想知道我需要使用哪个函数来完成这个任务。
有人可以指点我吗?ImageMagick能够进行屏幕截图吗?

你在使用哪个操作系统/平台?“屏幕”是一个依赖于操作系统的概念,你需要相应的扩展。 - LSerni
3个回答

21

使用“x:”特殊文件格式

如果您想进行无风格的屏幕截图,可以通过在MagickReadImage中传递"x:root"作为源参数来调用ImageMagick的导入命令。 x:格式可通过传递pid或窗口标签来进行完整屏幕截图或单个窗口捕获。其他修饰符可以捕获区域和分页。

#include <wand/MagickWand.h>

int main(int argc, char **argv) 
{
    MagickWandGenesis();
    MagickWand *wand = NULL;
    wand = NewMagickWand();
    MagickReadImage(wand,"x:root"); // <-- Invoke ImportImageCommand
    MagickWriteImage(wand,"screen_shot.png");
    if(wand)wand = DestroyMagickWand(wand);
    MagickWandTerminus();
    return 0;
}

使用额外的 'magick' 库

除了 wand 库之外,magick/xwindow.h 还允许您通过使用 XImportImageXImportInfoXGetImportInfo 方法导入图像。您可以在 ImageMagick 的源文件 wand/import.c 中查看这些方法的工作方式。

直接使用 X 和像素迭代器

MagickWand 还包括 PixelWand;它可以在内存中迭代图像指针。需要付出更多的努力,但可获得更大的灵活性。

#include <stdio.h>
#include <wand/MagickWand.h>
#include <X11/Xlib.h>

int main(int argc, char **argv) {
    int x,y;
    unsigned long pixel;
    char hex[128];

    // X11 items
    Display *display = XOpenDisplay(NULL);
    Window root = DefaultRootWindow(display);
    XWindowAttributes attr;
    XGetWindowAttributes(display, root, &attr);

    // MagickWand items
    MagickWand *wand = NULL;
    PixelWand *pwand = NULL;
    PixelIterator *pitr = NULL;
    PixelWand **wand_pixels = NULL;

    // Set-up Wand
    MagickWandGenesis();
    pwand = NewPixelWand();
    PixelSetColor(pwand,"white"); // Set default;
    wand = NewMagickWand();
    MagickNewImage(wand,attr.width,attr.height,pwand);
    pitr = NewPixelIterator(wand);

    // Get image from display server
    XImage *image = XGetImage(display,root, 0,0 , 
                                attr.width, attr.height,
                                XAllPlanes(), ZPixmap);

    unsigned long nwands; // May also be size_t

    for (y=0; y < image->height; y++) {
        wand_pixels=PixelGetNextIteratorRow(pitr,&nwands);
            for ( x=0; x < image->width; x++) {
                pixel = XGetPixel(image,x,y);
                sprintf(hex, "#%02x%02x%02x",
                                pixel>>16,           // Red
                                (pixel&0x00ff00)>>8, // Green
                                pixel&0x0000ff       // Blue
                                );
                PixelSetColor(wand_pixels[x],hex);
            }
            (void) PixelSyncIterator(pitr);
    }

    // Write to disk
    MagickWriteImages(wand,"screen_test.png");

    // Clean-Up
    XDestroyImage(image);
    pitr=DestroyPixelIterator(pitr);
    wand=DestroyMagickWand(wand);
    MagickWandTerminus();
    XCloseDisplay(display);
    return 0;
}

实用提示

确保ImageMagick可以连接到您的显示系统。尝试一些import命令行来验证您的本地安装是否正常工作。这个问题是一个很好的例子。

import -display localhost:0.0 -window root test_out.png
import -display ::0 -window root test_out.png
import -display :0.0 -window root test_out.png
import -display :0 -window root test_out.png

非常感谢,这非常有用。但第一个版本很有趣,“emacs盲”,即当前窗口是emacs时,它就看不到它,而是拍摄下面的窗口,就像emacs是透明的一样!(我正在运行Plasma 5.17.5)。如果有人知道发生了什么事,我实际上很好奇。 - tobiasBora

2

命令行程序 import 是从ImageMagick中导入的,可以通过以下方式运行来截取屏幕截图:

import -window root screenshot.png

因此,输入图像可以指定为文件或作为窗口根目录。


抱歉,我犯了一个错误。我不是在使用命令行,而是要调用与我的C程序链接的API函数。我正在寻找截屏功能的函数调用。谢谢。 - ant2009

1
  • 类型:import fileName.fileType(例如:import screen.png)
  • 将出现十字光标:单击并拖动它到您想要捕获的屏幕部分(确保终端窗口不覆盖您想要捕获的内容)

  • 网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接