(Наверно, это глупая идея. Но иногда даже самые глупые идеи приводят к неожиданным результатам.)
Текст шекспировской трагедии «Ромео и Джульетта» состоит примерно из 146 тысяч символов. Благодаря английскому алфавиту каждый символ можно описать одним байтом. Так что размер текстового файла в обычном Unicode составляет примерно 142 КБ.
В статье Adventures With Compression её автор JamesG размышляет о соревнованиях по сжатию текста и предлагает интересную мысль:
Закодировать текст в виде изображения и сжать это изображение. Мне понадобится алгоритм сжатия изображений без потерь. Использование RGB увеличит количество значений, связанных с каждым словом. Возможно, стоит преобразовать изображение в оттенки серого? А может, эту идею и не стоит исследовать.
Алгоритмы компрессии изображений обычно очень неплохо справляются с поиском паттернов в изображениях и с их сжатием. Поможет ли нам сжатие изображений, если мы преобразуем текст в картинку?
Английский язык и его пунктуация не особо сложны, так что пьеса содержит всего 77 уникальных символов. Значение ASCII каждого символа находится в интервале от 0 до 127. Давайте создадим изображение в оттенках серого, в котором каждый пиксель имеет тот же уровень серого, что и значение ASCII символа.
Вот как это выглядит после сжатия в PNG без потерь:
Размер снизился до 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.