§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) мы увидим скрытое изображение.
Выводы
Изображения состоят из пикселей. Каждый пиксель имеет цвет, который хранится в виде трёх чисел или номера цвета в палитре.
Изображения могут быть сжаты с потерями (формат JPEG) и без потерь (формат PNG).
Увидеть информацию, сокрытую в незначимых частях изображения, можно утилитой stegsolve.