Objective C 中的部分屏幕截图

Posted

技术标签:

【中文标题】Objective C 中的部分屏幕截图【英文标题】:Partial screen capture in Objective C 【发布时间】:2013-02-07 22:57:43 【问题描述】:

我一直试图弄清楚如何在目标 C 中创建一个 OS X 例程:

在后台运行(单独的线程)和

重复(定时或在满足某些条件时)捕获指定窗口/屏幕的几个定义子集(即没有用户交互)和

将图像保存到指定路径。

类似于“cmd-shift-4 + mouseDown-drag 的预编程循环”的输出。

Mac 开发人员库中的 SonofGrab 和 ScreenSnapshot 似乎都没有表明如何做到这一点,但我怀疑 CGImageRef 是一种/the(?) 解决方法。

    有人知道怎么做吗?

    除了 CGImageRef 还有其他可能的方法来解决这个问题吗?例如可以通过命令行工具和 NSTask 来完成吗?

    如果是这样,不同方法在速度和复杂性方面的优缺点是什么?

【问题讨论】:

【参考方案1】:

假设您具有执行屏幕抓取所需的逻辑(您可以在 SonOfGrab 中看到),您只需使用调度队列或计时器来完成这项工作。

void MyTakeScreengrab();

dispatch_queue_t  queue    = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,  0);

dispatch_source_t timerSrc = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0,0,queue);

dispatch_source_set_timer(timerSrc, 
      dispatch_time(DISPATCH_TIME_NOW,0) /* start on */,
      SECONDS_PER_GRAB * NSEC_PER_SEC /* interval */, 
      NSEC_PER_SEC /* leeway */);

dispatch_source_set_event_handler_f(timerSrc, MyTakeScreengrab);

dispatch_resume(timerSrc);

您也可以使用 NSTimer。

-(void)setup 
    _timer = [[NSTimer scheduledTimerWithTimeInterval: (NSTimerInterval)SECONDS_PER_GRAB 
            target: self 
            selector: @selector(takeScreegrabOnBGThread:) 
            userInfo: @ @"folderPath" : MyFolderPath(), 
                         @"imageSettings" : MYCGImageSettings()   
            repeats: YES];
    [_timer fire];


-(void)takeScreengrabOnBGThread:(id)userInfo 
    [self performSelectorInBackground:@selector(takeScreengrabBlocking:) 
            withObject:userInfo];


-(void)takeScreengrabBlocking:(id)userInfo 

    MyTakeScreengab(userInfo);

要使用终端执行此操作,您要查找的命令是screencapture(1)

【讨论】:

谢谢,我可以使用它。但是,最大的问题是您如何获得 AXPosition x=193.00 y=365.00; 的屏幕截图。 AXSize w=492.00 h=63.00?据我所知,SonOfGrab 只为您提供完整的屏幕截图(cmd-shift-3)或“windowshot”(cmd-shift-4 + 空格键)。 如果你想要屏幕的一部分,你只需使用CGDisplayCreateImageForRect() 如果您不惜一切代价避免使用CGImageRefs(使用它们!!),您可以使用screengrab(1) 创建整个屏幕的抓取,使用NSImage 打开它API,然后使用位图图形上下文对其进行裁剪。糟糕。 似乎 CGDisplayCreateImageForRect() 可能是要走的路。我不想抓住比我需要的更多的屏幕。它只会减慢速度。是否可以相对于特定窗口而不是屏幕来设置 (x,y)? 要抓取一个窗口,您将使用CGWindowListCreateImage() -- 这仍然需要屏幕坐标,但要将 NSWindow 相对坐标转换为屏幕坐标,您只需使用 -[NSWindow convertRectToScreen:]

以上是关于Objective C 中的部分屏幕截图的主要内容,如果未能解决你的问题,请参考以下文章

C ++ wxWidgets遍历桌面屏幕截图中的像素

如果 App 在后台,iOS 会检测屏幕截图

屏幕上部分显示的视图的屏幕截图

Mac:屏幕截图选择实现? (能够选择屏幕的一部分)

自动截取程序窗口的屏幕截图

Selenium - 页面可见部分的屏幕截图