@drunkstudent

Как кодируются картинки?

При скачивании файла из сети (в данном случае картинки) мы имеем дело с массивом байтов. Как определить какого расширения данная картинка (png, jpg, bmp и др)? Есть ли какая-то служебная информация? Как конвертировать из одного формата в другой?
P.S. Да, знаю, можно найти спецификацию любого формата и вычитать там, но хотелось бы сначала понять основы, а потом ковыряться в спецификациях
  • Вопрос задан
  • 1569 просмотров
Решения вопроса 1
copist
@copist
Empower people to give
Есть такое понятие - сигнатура. Набор байтов которые встречаются только в этом типе файлов.
У PNG тоже есть сигнатура. www.libpng.org/pub/png/spec/1.2/PNG-Structure.html

The first eight bytes of a PNG file always contain the following (decimal) values:
137 80 78 71 13 10 26 10


Еще можно посмотреть исходники утилиты identify из пакета ImageMagick www.imagemagick.org/script/identify.php
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
В общем случае конечно в протоколе передачи данных должен быть способ указания на то, как передаваемые данные интерпретировать. Например, в HTTP используются заголовки в ответе для указания типа содержимого (Content-Type) и кодирования на уровне HTTP, например, сжатия, если таковое присутствует. При получении данных клиент (например, браузер) должен раскодировать содержимое в исходный вид (например, распаковать, если сервер сжал отправляемый ресурс) и далее работать с ним на основе указанного Content-Type. Невозможно на 100% определить заранее, что картинка того или иного формата, но, как правильно подметил Павел Волынцев, у большинства форматов есть сигнатура, по которой с вероятностью 99.9..% можно сказать, что прилетела PNG-шка или JPEG. В любом случае, правильно реализованная читалка (декордер) графических форматов должна быть готова к тому, что картинка может быть повреждена и должна выдавать ошибку, если разобрать картинку согласно предполагаемому формату невозможно.
Сами форматы растровых изображений (вектор не рассматриваем сейчас) как раз таки и различаются прежде всего: а) особенностями представления пиксельной карты (матрицы пискелей): как кодируется цвет, индексный или компонентный, сколько всего может быть различных значений цвета у пиксела, есть ли сжатие, какие алгоритмы сжатия применяются - без потерь (PNG) или с потерями (JPEG); б) служебной информацией: это может быть как базовая необходимая информация, например размеры картинки и размер одного пикселя в байтах (читай - сколько байт выделяется на цвет одного пиксела), так и дополнительная, например EXIF, где можно указать и автора, и режим съемки и много чего еще; в) доп. фичами, которые и делают каждый формат особенным: поддержка анимации (GIF, MNG), поддержка сжатия с потерями (JPEG), поддержка слоев в картинках (фотошоповский PSD), поддержка "многостраничных" картинок (TIF) и так далее.
Конвертирование собственно сводится к:
1) определению исходного формата картинки;
2) чтению исходного формата с целью перевести его в удобное развернутое представление в памяти, удобное для программиста с точки зрения дальнейших операций (расжать, прочитать служебную инфу и т.д.)
3) записи полученного представления в памяти в новый формат, что опять таки подразумевает запись необходимых сигнатур и служебной инфы в соответствии со спецификацией формата, плюс преобразование изображения алгоритмами сжатия, если нужно (например, эффективность jpeg для фотоизображений достигается использованием довольно сложного и хитрого алгоритма кодирования, учитывающего восприятие цвета человеком, в том время как PNG сжимает почти как обычный архиватор, который никак не интерпретирует сжимаемые данные).
Надеюсь дальше понятно куда копать.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы