Как создать изображение из буквенных байтов в Python?

#python-3.x #python-imaging-library #pixel #literals

#python-3.x #python-imaging-library #пиксель #литералы

Вопрос:

Кажется, я не могу найти решение для создания изображения из прямых пиксельных данных в Python. Моя текущая попытка выглядела так:

 imdata = b'xffx00x00x00xffx00xffx00xffx00x00x00xffx00x00x00xffx00xffx00xffx00x00x00xff'
imtest = Image.frombuffer('1', (5, 5), imdata, 'raw', '1', 0, 1)
blackDraw.bitmap((50, 50), imtest, fill = None)
 

Предназначенное изображение должно быть монохромным «X»:

 x___x
_x_x_
__x__
_x_x_
x___x
 

Однако при отображении (на самом деле, на экране электронной бумаги) это выглядит так:

 xxxxx
_____
_____
_____
xxxxx
 

Что я делаю не так? Как я могу создать изображение из прямых пиксельных данных?

Ответ №1:

Вы используете неправильный режим.

 imtest = PIL.Image.frombytes('L', (5, 5), imdata)
plt.imshow(imtest, 'gray')
 

Также вы могли бы сделать:

 import matplotlib.pyplot as plt
X = np.array([int(i) for i in imdata]).reshape(5,5)
plt.imshow(X, 'gray')
 

введите описание изображения здесь

Комментарии:

1. На самом деле мне нужно использовать режим «1», потому что изображение позже передается в библиотеку, рисуя изображение на электронной бумаге, и оно должно быть монохромным. Но в конце концов режим тоже оказался проблемой.

Ответ №2:

Я нашел проблему. Документация PIL кажется немного вводящей в заблуждение, потому что в ней говорится:

Режим

Режим изображения определяет тип и глубину пикселя в изображении. Текущая версия поддерживает следующие стандартные режимы: 1 (1-битные пиксели, черно-белые, хранятся как 8-битные пиксели)

Источник: http://www.pythonware.com/media/data/pil-handbook.pdf

Другие документы еще более понятны для хранения пикселей:

Режимы

Режим изображения — это строка, которая определяет тип и глубину пикселя в изображении. Каждый пиксель использует полный диапазон разрядности. Итак, 1-битный пиксель имеет диапазон 0-1, 8-битный пиксель имеет диапазон 0-255 и так далее. Текущая версия поддерживает следующие стандартные режимы:

1 (1-битные пиксели, черно-белые, хранятся с одним пикселем на байт)

Источник: https://pillow.readthedocs.io/en/stable/handbook/concepts.html#concept-modes

Однако кажется, что даже если пиксели хранятся по 1 байту на пиксель, они фактически считываются из байтов по 8 пикселей на байт.

 imdata = b'x82x44x28x10x28x44x82'
imtest = Image.frombytes('1', (7, 7), imdata, 'raw', '1', 0, 1)
blackDraw.bitmap((150,150), imtest, fill = None)
 

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