2017-01-22 21 views
7

Я работаю над программой, которая берет строку, превращает каждый символ строки в цвет, затем рисует цвета слева направо, сверху вниз по изображению. Затем изображение можно декодировать с использованием той же самой программы, чтобы вернуть исходное сообщение. В качестве примера, вот clojure.core, кодируется как изображение:Кодирование строки в качестве изображения вызывает сжатие

Clojure.core encoded as an image

Я написал это только как игрушка, но я заметил одно интересное свойство изображений производит: они меньше, чем первоначальные сообщения были как текст. Для clojure.core это 259kb как текст, но только 88.9kb как изображение (выше) (оба значения - «размер на диске»). Чтобы данные не терялись, я декодировал изображение и получил исходное сообщение.

Как это возможно? Я думаю, что изображение (png) будет иметь заголовки и другую дополнительную информацию, которая раздувала бы размер.

Всего clojure.core содержит 265486 символов (согласно Notepad ++), что означает, что каждый символ в основном занимает байты.

От работы с классом BufferedImage (Java) кажется, что цвета хранятся в виде 4-байтовых целых чисел, поэтому каждый пиксель не должен иметь ~ 4x памяти?

Вот как это закодировано:

  1. Первый символ строки выталкивается

  2. Это переведенный в цвет, получив это значение ASCII, умножив его на большом количестве (так его лучше всего охватывает диапазон возможных цветов), затем это число преобразуется в 3-значный номер базы 256 ([123 100 200]).

  3. Каждая цифра рассматривается как красный, зеленый и синий каналы, которые даются BufferedImagesetRGB.

  4. Индикатор position продвинутый, следующий символ вызывается, и процесс повторяется до тех пор, пока не будет закодировано все сообщение.

Алгоритм немного запутанный прямо сейчас. @ Thumbnail предложил намного лучший способ обзора кода, но я еще не реализовал его. Поскольку результаты одинаковы, это не должно меняться для вопроса.

+2

Несмотря на то, что ответ был несколько очевиден, мне все еще нравилось читать о ваших выводах. Это всегда забавно, когда это происходит. –

ответ

7

Portable Network Graphics (PNG) - это формат растровой графики, который поддерживает сжатие данных без потерь (от https://en.wikipedia.org/wiki/Portable_Network_Graphics), iow. данные изображения сжимаются при сохранении как .png-файла.

+0

Дох. Ну, это очевидно в ретроспективе. Благодарю. – Carcigenicate

+0

Возможно, стоит упомянуть, что PNG использует сжатие Zlib/Deflate (и что вы, вероятно, получите лучшие результаты, используя Deflate непосредственно в текстовом файле). – haraldK

+0

@haraldK, который был бы моим ожиданием. В дополнение к deflate, png делает предварительный проход, который помогает сжатию «реальных» изображений (где пиксель, по статистике, очень похож на соседние пиксели). Вы могли бы, вероятно, воспользоваться этим, выбирая цвета, близкие друг к другу (таким образом, улучшая сжатие png).Несмелесообразно, возможно, сделать меньшие размерные изображения, кодируя более одного символа на пиксель (изображения truecolor + alpha png используют 64 бита на пиксель) - это, скорее всего, не сжимается, хотя. – thebjorn