§1.6. Изображения

Если сильно увеличить какое-нибудь изображение, мы увидим, что оно складывается из отдельных точек, называемых пикселями.

Каждый пиксель имеет цвет: именно этими цветами и задаётся изображение. Таким образом, чтобы сохранить изображение, достаточно сохранить информацию о его ширине и высоте, а также цвета всех пикселей по порядку.

Ранние компьютеры могли отображать лишь довольно ограниченное количество цветов: сначала только 2 (чёрный и белый или, например, чёрный и зелёный); потом 16; потом 256. Как и при кодировании текста, каждому цвету из такого ограниченного набора сопоставляется число. Если для символов текста такое сопоставление называется кодировкой, то у изображений это — палитра. Палитра может быть как жёстко задана операционной системой, так и определена индивидуально для конкретного изображения.

Экраны компьютеров, телевизоров и подобных устройств на самом деле могут отображать лишь три цвета: красный, зелёный и синий. Смешивая их, экран может отобразить практически любой цвет, воспринять который способен человеческий глаз: например, красный и зелёный цвета складываются в жёлтый. У современых мониторов каждому пикселю соответствует свой красный, свой зелёный и свой синий элемент, который может работать с той или иной яркостью.

Для реалистичной передачи на экране изображений, для которых недостаточно цветового разнообразия 256-цветной палитры (вроде фотографии выше) палитру не используют. Вместо этого кодируют числами интенсивность красной, зелёной и синей составляющей каждого пикселя (говорят про красный, зелёный и синий каналы). Наиболее распространено кодирование числами от 0 (темнота) до 255 (максимальная яркость). Таким образом, любой цвет можно представить тремя числами: например, оранжевый цвет, используемый в этой книге, записывается как 255, 122, 0.

Иногда удобно эти три числа записать в шестнадцатеричной системе счисления: каждый канал принимает шестнадцатеричные значения от 00 до FF, и три числа можно писать подряд без разделителей. Обычно к такой записи слева приписывают символ #. Скажем, голубой цвет (64, 128, 255) можно записать просто как #4080FF.

ЦветRGB-числаHEX-представление
Чёрный0, 0, 0#000000
Белый255, 255, 255#FFFFFF
Серый128, 128, 128#808080
Светло-серый200, 200, 200#C8C8C8
Красный255, 0, 0#FF0000
Жёлтый255, 255, 0#FFFF00
Зелёный0, 255, 0#00FF00
Серо-зелёный128, 192, 128#80C080
Синий0, 0, 255#0000FF
Розовый255, 0, 255#FF00FF
Серо-буро-малиновый115, 81, 132#735184

Сжатие

В простейшем формате изображений — BMP — записываются подряд цвета всех пикселей. Файлы формата BMP обычно имеют достаточно большой размер. Зачастую информация в файле избыточна: в рисунках обычно есть много повторяющихся цветов, а в фотографиях цвета можно передавать не очень точно, что никак не повлияет на их эстетические качества.

Размер файла оптимизируют сжатием. Для рисунков и иной графики применяют сжатие без потерь, для фотографий — сжатие с потерями.

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

Мы можем использовать избыточность данных изображения для другого. В самом деле, если возможных градаций яркости 256, можно незаметно для восприятия немного изменить кодирующие изображение числа.

Пусть у нас есть некая информация, представленная в виде нулей и единиц, которую мы хотим внедрить в изображение. Мы можем изменять цвета так, чтобы в тех позициях, где в нашей информации ноль, числа стали чётными, а где единицы — нечётными. Такой вид стеганографического кодирования называется LSB (англ. least significant bit — наименее значимый бит). Для удобства можно изменять значения лишь одного канала, например, зелёного.

Утилита stegsolve позволяет просматривать отдельные срезы изображения, в том числе наименьший значимый бит каждого цветового канала. Откроем в ней (через меню File → Open) изображение. Будем листать срезы с помощью кнопки > внизу. Название текущего среза указано в верхней части окна. На последнем срезе зелёного канала (Green plane 0) мы увидим скрытое изображение.

Выводы

  1. Изображения состоят из пикселей. Каждый пиксель имеет цвет, который хранится в виде трёх чисел или номера цвета в палитре.

  2. Изображения могут быть сжаты с потерями (формат JPEG) и без потерь (формат PNG).

  3. Увидеть информацию, сокрытую в незначимых частях изображения, можно утилитой stegsolve.

§1.7. Звук и спектр ⟶