1

我需要能够在 OSX 下的 python 脚本中截取屏幕截图(如果将其放在标题和标签中不够清晰,则为 vnc 会话)。远程系统已经在运行我用于其他目的的 vnc 服务器,并且最终将涵盖所有常见的桌面操作系统,因此我更愿意继续使用 vnc 而不是其他一些解决方案。

我的测试服务器上没有打开 vnc 窗口,因为它运行 headless。我尝试过使用vncdotool,但我不希望不得不掏空,并且尝试模仿控制流会导致问题,因为 Twisted 不允许您重新启动反应器,但是如果您让它运行它会阻塞主线程,并且尝试在单独的线程或进程中运行反应器似乎存在问题......

有没有人有任何想法?

4

5 回答 5

1

阅读您的评论后,您似乎真正想做的是为运行您的 Flash 游戏的远程 Web 浏览器截屏。

...而且您正在使用 selenium 来测试那些远程 Web 浏览器。

...你为什么不让 selenium 为你截屏?

http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/TakesScreenshot.html

于 2012-06-26T12:05:18.680 回答
1

基于 tangentStorm 的建议,使用 selenium 截取屏幕截图。尝试这样做。打开src/Selenium2Library/keywords/_screenshot.py并查看第 24-30 行。

     background leaking when the page layout is somehow broken.
     """
     path, link = self._get_screenshot_paths(filename)
     self._current_browser().save_screenshot(path)

     # Image is shown on its own row and thus prev row is closed on purpose
     self._html('</td></tr><tr><td colspan="3"><a href="%s">'

删除该行self._current_browser().save_screenshot(path)并直接在其位置添加

if hasattr(self._current_browser(), 'get_screenshot_as_file'):
    self._current_browser().get_screenshot_as_file(path)
else:
    self._current_browser().save_screenshot(path)

所以总的来说它应该是这样的:

    background leaking when the page layout is somehow broken.
    """
    path, link = self._get_screenshot_paths(filename)
if hasattr(self._current_browser(), 'get_screenshot_as_file'):
    self._current_browser().get_screenshot_as_file(path)
else:
    self._current_browser().save_screenshot(path)
    # Image is shown on its own row and thus prev row is closed on purpose
    self._html('</td></tr><tr><td colspan="3"><a href="%s">'

然后尝试使用 selenium 截取屏幕截图。

参考:修复

于 2012-06-27T15:44:39.287 回答
0

也许您可以说服机器人框架或 Selenium 向CaptureScreenEggplant Drive 发送 Sensetalk 命令。

TestPlant 论坛中的截图帖子提到了这个命令。

于 2012-06-27T01:00:03.703 回答
0

根据您的代码,您可能可以使用deferToThread来运行调用screencapture并返回文件路径或pil.Image实例(或任何您需要的)。

使用http://twistedmatrix.com/documents/current/core/howto/gendefer.html#auto5上的示例,它可能看起来像......

from subprocess import call
import tempfile
from twisted.internet import reactor, threads
import Image ## pip install pil


## Blocking code that takes the screenshot and saves to file
def take_screenshot():
    tmp_file_path = tempfile.mktemp(suffix='.png')
    # os.system('screencapture %s' % tmp_file_path)
    retcode = call(['screencapture', tmp_file_path])
    if retcode < 0:
        img = Image.open(tmp_file_path)
        return img
    else:
        return None


## Callback fired by the deferToThread
def do_something_with_screenshot(img):
    print img.filename, img.format, img.size, img.mode
    reactor.stop() ## just here for this example


def run():
    # get our Deferred which will be called with the largeFibonnaciNumber result
    d = threads.deferToThread(take_screenshot)
    # add our callback to print it out
    d.addCallback(do_something_with_screenshot)


if __name__ == '__main__':
    run()
    reactor.run()
于 2012-06-24T11:20:28.483 回答
0

我不知道有任何库在 OSX 的 python 中执行此操作。

但是,至少还有其他三种方法可以获取屏幕截图:

  1. 使用 jython 的java.awt.Robot类。(除了扭曲可能不会在 jython 上运行。)
  2. 将Apple 的ScreenSnapshot示例移植到Cython并将其编译为 python 模块。(当然,您可以在 C 中做同样的事情,但 Cython 使它更有趣。)
  3. 如果您可以将您的服务器移动到 win32,或者只是通过并行在您的 mac 上运行 win32,那么您可以使用 python 图像库的ImageGrab模块。

但是,我认为向操作系统发起攻击仍然是最简单的答案。与其试图让它在一个进程中运行,不如让两个进程运行:你的主要扭曲进程,以及其他一些使用线程或其他的服务器。

然后,当您想截屏时,只需来回传递消息。您可以使用简单的套接字连接来做到这一点(只需在您的扭曲服务器中编写另一个处理程序,并让屏幕截图服务器作为客户端连接)......

如果是我,我可能会使用像RabbitMQ这样的 AMQP 服务器来处理消息传递,但这对你正在做的事情来说可能是多余的。

于 2012-06-23T02:08:29.437 回答