Pull to refresh
2915.61
RUVDS.com
VDS/VPS-хостинг. Скидка 15% по коду HABR15

Как спрятать фото в другом фото

Reading time3 min
Views23K
Original author: Aryan Ebrahimpour

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

Используя этот метод, можно прятать в своей художественной работе подпись или сохранять несколько снимков как один в целях экономии памяти на миниатюрных устройствах. Есть ещё один аналогичный подход, с помощью которого игровые ресурсы картриджей Pico-8 включаются в небольшой PNG самой игры*.

*Подробнее в статье «Steganography: decoding Pico-8 cartridges».

▍ Фотографии как матрицы


Чтобы иметь возможность управлять фотографиями и встраивать в них что-либо, сначала нужно разобраться с их возможным представлением и сохранением. Один из вариантов – это представить снимки в виде математических матриц, в которых каждая ячейка выражает пиксель, а её значение – цвет этого пикселя/ячейки.


Например, при такой матрице:


Мы получим такое фото:


Если фотографию и матрицу сопоставить, то можно заметить, чем ближе значение к 255, тем белее пиксель. При этом 0 означает чёрный, а всё между 0 и 255 оттенки серого.

▍ Фотографии как битовые матрицы


Итак, снимки в виде матриц мы представили. Теперь давайте немного поботаним и выразим значение каждой ячейки не в десятичном, а в двоичном виде (обещаю, дальше это пригодится).

Та же фотография с помощью этой матрицы теперь будет выражаться так:


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



Можете разглядеть какие-либо изменения? Предполагаю, что нет. Полученный вариант определённо выглядит так же, как оригинал (если только вы не обладатель сверхзрения), поскольку мы изменили лишь младшие биты, имеющие наименьшую значимость. С помощью этого элементарного приёма можно встраивать фотографии одну в другую, не вызывая подозрений в отношении оригинального снимка.

▍ Встраивание фото


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


Но насколько меньше? В видимой фотографии размером n * m есть nm/8 младших бит, то есть внутри неё можно разместить фото размером √nm/8 * √nm/8. Например, при размере видимого снимка 1000 * 1000px мы получаем:


Это означает, что можно скрыть в нём фотографию размером 353 * 353px.

▍ Цветные фото


В цветных снимках каждый пиксель представлен тремя матрицами: красной, зелёной и синей. Вместо этого можно рассматривать такие снимки как одну матрицу с кортежами из трёх значений в диапазоне от 0 до 255.


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

▍ PNG, JPEG и сжатие


Вы наверняка знаете, что некоторые форматы фото (например, JPEG) сильно сжимают исходное изображение, используя различные математические техники (например, вейвлет Хаара). Что же происходит со встраиваемым фото в таком случае? Оно с наибольшей вероятностью уничтожается, и при попытке извлечения мы увидим лишь шум. Но есть и другие форматы, например, PNG, которые сохраняют фотографию. Так что можно использовать рассмотренный трюк с ними.

▍ Реализация


Я реализовал этот метод давно, когда ещё учился на бакалавра, и соответствующий код лежит здесь. Это десктопное приложение, в котором для работы с битами фотографий используется Emgu CV.

Tags:
Hubs:
Total votes 51: ↑39 and ↓12+51
Comments35

Articles

Information

Website
ruvds.com
Registered
Founded
Employees
11–30 employees
Location
Россия
Representative
ruvds