Преобразование растрового изображения с автопией в изображение подушки

Я разрабатываю скребок для экрана на Python, используя Autopy и Pillow.

Можно ли преобразовать растровый объект в объект изображения подушки?

Мое текущее решение - сохранить объект растрового изображения в виде файла изображения, а затем использовать путь для создания объекта изображения "Подушка". Этот подход действительно медленный из-за жесткого ввода-вывода.

Мое текущее (очень медленное) решение:

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')

Вопрос: Можно ли реализовать вышеуказанную функциональность без сохранения растрового объекта на жесткий диск?

1 ответ

После просмотра исходного кода создается впечатление, что нет прямого доступа к необработанному растровому изображению. Тем не менее, вы можете получить зашифрованную копию.

Сначала получите его закодированное представление.

bitmap_encoded = bitmap_object.to_string()

Это кодируется как "b", за которым следуют ширина, запятая, высота, запятая и кодировка base64 сжатых необработанных байтов zlib. Разобрать закодированные данные:

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, а не в типичной BGR-кодировке, которую используют BMP-файлы, чего и ожидает PIL. Наконец, загрузите изображение с PIL:

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

Чтобы загрузить изображение в обычном режиме без замены красного и синего каналов, выполните:

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

Похоже, теперь у этого есть решение от 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))
Другие вопросы по тегам