Сохранить 1-битное двоичное изображение в Python - PullRequest
0 голосов
/ 10 мая 2018

У меня есть двоичное изображение в Python, и я хочу сохранить его на моем компьютере. Мне нужно, чтобы это было 1-битное изображение PNG, когда-то сохраненное на моем компьютере. Как я могу это сделать? Я пробовал и с PIL, и с cv2, но я не могу сохранить его с глубиной 1 бит.

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Если вы не загружаете png или что-то еще, формат ведет себя довольно разумно, просто напишите его. Тогда ваш код не нуждается в PIL или какой-либо головной боли при различных операциях импорта и импорта при импорте и т. Д.

import struct
import zlib
from math import ceil


def write_png_1bit(buf, width, height, stride=None):
    if stride is None:
        stride = int(ceil(width / 8))
    raw_data = b"".join(
        b'\x00' + buf[span:span + stride] for span in range(0, (height - 1) * stride, stride))

    def png_pack(png_tag, data):
        chunk_head = png_tag + data
        return struct.pack("!I", len(data)) + chunk_head + struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head))

    return b"".join([
        b'\x89PNG\r\n\x1a\n',
        png_pack(b'IHDR', struct.pack("!2I5B", width, height, 1, 0, 0, 0, 0)),
        png_pack(b'IDAT', zlib.compress(raw_data, 9)),
        png_pack(b'IEND', b'')])

Адаптировано из: http://code.activestate.com/recipes/577443-write-a-png-image-in-native-python/ (MIT)

, прочитав спецификацию png: https://www.w3.org/TR/PNG-Chunks.html

Имейте в виду, что 1-битные данные из buf должны записываться слева направо, как спецификация png, в обычном режиме без чередования (который мы объявили). И избыточные данные дополняют последний бит, если он существует, и шаг - это количество байтов, необходимое для кодирования строки сканирования. Кроме того, если вы хотите, чтобы эти 1 бит имели цвета палитры, вам нужно написать блок PLTE и переключить тип на 3, а не на 0. И т. Д.

0 голосов
/ 10 мая 2018

Использование:

cv2.imwrite(<image_name>, img, [cv2.IMWRITE_PNG_BILEVEL, 1])

(при этом по-прежнему будет использоваться сжатие, поэтому на практике оно, скорее всего, будет иметь размер менее 1 бита на пиксель)

...