Преобразование растрового изображения с автопией в изображение подушки
Я разрабатываю скребок для экрана на 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))