[Перевод] Сжимаем текст в изображения PNG

abcc344ba2ef11091164e2e07cbad245.png

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

Текст шекспировской трагедии «Ромео и Джульетта» состоит примерно из 146 тысяч символов. Благодаря английскому алфавиту каждый символ можно описать одним байтом. Так что размер текстового файла в обычном Unicode составляет примерно 142 КБ.

В статье Adventures With Compression её автор JamesG размышляет о соревнованиях по сжатию текста и предлагает интересную мысль:

Закодировать текст в виде изображения и сжать это изображение. Мне понадобится алгоритм сжатия изображений без потерь. Использование RGB увеличит количество значений, связанных с каждым словом. Возможно, стоит преобразовать изображение в оттенки серого? А может, эту идею и не стоит исследовать.

Алгоритмы компрессии изображений обычно очень неплохо справляются с поиском паттернов в изображениях и с их сжатием. Поможет ли нам сжатие изображений, если мы преобразуем текст в картинку?

Английский язык и его пунктуация не особо сложны, так что пьеса содержит всего 77 уникальных символов. Значение ASCII каждого символа находится в интервале от 0 до 127. Давайте создадим изображение в оттенках серого, в котором каждый пиксель имеет тот же уровень серого, что и значение ASCII символа.

Вот, как это выглядит после сжатия в PNG без потерь:

Random grey noise.

Случайный серый шум.

Размер снизился до 55 КБ! Это примерно 40% от размера исходного файла. Это чуть меньше, чем ZIP, и примерно на 9 байтов больше, чем сжатие Brotli.

Файл можно считывать следующим кодом на Python:

from PIL import Image
image  = Image.open("ascii_grey.png")
pixels = list(image.getdata())
ascii  = "".join([chr(pixel) for pixel in pixels])
with open("rj.txt", "w") as file:
    file.write(ascii)

Но маловероятно, что даже при помощи самых современных алгоритмов сжатия изображений его можно сжать ещё сильнее — картинка похожа на случайный шум. Да, мы с вами знаем, что в ней хранятся данные. И специалист по статистике, вычислив энтропию, вероятно, определит, что файл содержит читаемые данные. Но алгоритмы сжатия изображений работают в другой сфере. Они ищут блоки одного цвета, предсказуемые градиенты или другие статистические признаки.

Но всё-таки у нас получилось! Сжатое без потерь изображение — довольно эффективный способ сжатия текста ASCII.

© Habrahabr.ru