将autopy位图转换为Pillow图像

3

我正在使用Autopy和Pillow开发Python屏幕脚本工具。

是否有可能将位图对象转换为Pillow图像对象?

我的当前解决方案是将位图对象保存为图像文件,然后使用路径创建Pillow图像对象。由于硬盘I/O的原因,这种方法非常缓慢。

我的当前(非常缓慢)解决方案:

from PIL import Image
import autopy

bitmap_object = autopy.bitmap.capture_screen()
bitmap_object.save('some/path.png') # VERY SLOW!
img = Image.open('some/path.png')

问题: 是否可以在不将位图对象保存到硬盘的情况下实现上述功能?


尝试使用PIL中的ImageGrab,它与autopy.bitmap.capture_screen()执行相同的操作。链接在此 - Vasilis G.
@TarunLalwani ~3 MB - Vingtoft
你可以尝试使用 PyPy 而不是 Python 运行它,看看是否有帮助?不确定 PyPy 是否支持 PIL 和 autopy,但你可以试一试。 - Tarun Lalwani
你尝试过使用 img = PIL.Image.fromArray(bitmap, mode=xx) 吗?这对于我来说可以处理numpy数组。我看到Autopy.bitmap有一个to_string()方法,不确定它是否可以获取原始数据。 - bivouac0
@bivouac0,“to_string”方法没有关于其生成格式的文档。我很乐意提供帮助,但似乎无法安装“autopy”,pip一直返回错误。 - Mark Ransom
显示剩余3条评论
2个回答

2

在查看源代码后,似乎没有直接访问原始位图的方法。但是,您可以获得编码副本。

首先,获取其编码表示。

bitmap_encoded = bitmap_object.to_string()

这段文本被编码为“b”,后面跟着宽度、逗号、高度、逗号和zlib压缩的原始字节的base64编码。解析编码数据:

import base64
import zlib

# b3840,1080,eNrsf...H1ooKAs=
#      ^    ^
first_comma = bitmap_encoded.find(',')
second_comma = bitmap_encoded.find(',', first_comma + 1)

# b3840,1080,eNrsf...H1ooKAs=
#  ^  ^
width = int(bitmap_encoded[1:first_comma])

# b3840,1080,eNrsf...H1ooKAs=
#       ^  ^
height = int(bitmap_encoded[first_comma+1:second_comma])

# b3840,1080,eNrsf...H1ooKAs=
#            ^
bitmap_bytes = zlib.decompress(base64.b64decode(bitmap_encoded[second_comma+1:]))

当我在我的计算机上测试时,红色和蓝色通道是反过来的,因此我假设autopy中的位图采用RGB编码,而不是BMP文件通常使用的BGR编码,这也是PIL所期望的。最后,使用PIL加载图像:

img = PIL.Image.frombytes('RGB', (width, height), bitmap_bytes, 'raw', 'BGR', 0, 1)

如果要正常加载图像而不交换红色和蓝色通道,请执行以下操作:

img = PIL.Image.frombytes('RGB', (width, height), bitmap_bytes)

你有尝试直接迭代对象吗?(例如... for x in bitmap_object)我看到有一个Bitmap_iternext,我认为可以用来获取原始数组,尽管我没有安装这个库来测试它。 - bivouac0
@bivouac0 我试过了,但它并不是很有用。它似乎只产生点。即 iter(bitmap_object).next() == (1, 0)list(bitmap_object) == [(1, 0), (2, 0), ..., (3838, 1079), (3839, 1079)] - Uyghur Lives Matter
非常棒的解决方案,完美运作,正是我所期望的。谢谢! - Vingtoft

0

看起来现在有一个autopy的解决方案

import autopy
import PIL.Image

bmp = autopy.bitmap.capture_screen()
width, height = int(round(bmp.width * bmp.scale)), int(round(bmp.height * bmp.scale))
img = PIL.Image.frombytes('RGB', (width, height), bytes(bmp))

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