Фотословарь. Декодирование JPEG для чайников

28.05.2019

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

Как это работает

Бит (англ. binary digit) - двоичное число, принимающее значения 1 или 0.

В BMP-файлах каждая точка (пиксель) кодируется с помощью 24 бит, по 8 бит на каждый из каналов (красный, зелёный и синий).

Таким образом, компьютер чётко различает 16 777 216 различных цветов, в то время как обычный человек не сможет отличить, к примеру, красный #FC130F от красного #FF141C. Он просто скажет, что это красный.

Это позволяет незаметно для глаза манипулировать цветом любого изображения.

Пиксель (англ. pixel, pel - сокращение от pix element) - минимальная точка на изображении.

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

Меняя 2 младших бита в каждом канале, мы получим по 6 свободных бит в каждом пикселе.

Таким образом, чтобы спрятать файл в изображении необходимо:

Байт (англ. byte) - единица цифровой информации
  • придумать разметку для кодируемых данных (к примеру, каждые первые 4 байта выделить под размер полезных данных, а остальные байты - под сами данные);
  • разбить всю последовательность на группы битов;
  • последовательно заменить младшие биты каждого цветового канала каждого пикселя на новые.

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

Давайте применим эту теорию на практике. Для этого нам понадобится программа bmpCoder. Скачиваем её и запускаем (программа портативная и установка не требуется).

Перед нами появится вот такое окно.

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

Шифрование файлов в изображениях с помощью bmpCoder

Теперь попробуем что-нибудь зашифровать. Для этого сначала, с помощью стандартного окна проводника Windows, указываем путь к картинке-контейнеру в формате BMP.

Для примера, возьмём картинку с "Антошкой", которую мы использовали в одной из предыдущих статей .

После её загрузки, справа появится квадратная превьюшка картинки, а индикатор покажет, что мы можем добавить в неё файл размером до 126 кБ (при том, что сама картинка в формате BMP весит 518 кБ).

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

Теперь лишь осталось нажать кнопку "Кодировать" и в появившемся окошке указать, куда и под каким именем будет сохранено новое BMP-изображение, содержащее в себе зашифрованный файл.

Буквально через секунду в указанной папке появится новая картинка, практически идентичная исходной, но с "секретом".

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

Расшифровка закодированного файла

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

Готово! Если не было допущено никаких ошибок в именах файлов, то в указанном нами месте появится расшифрованный файлик с "паролями".

Выводы

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

Вы наверняка неоднократно сталкивались в интернете с таким видом проверки, как капча . Это мини-тест, который требует расшифровки текста с картинки онлайн. Смысл теста в том, что его может пройти только живой человек. Однако проверка, робот вы или нет, иногда оказывается сложной даже для человека. Как же расшифровывать текст без проблем?

    • Расшифровка капч без программ - легкая задача для обычного пеользователя

Расшифровка капч без программ - легкая задача для обычного пеользователя

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

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

Расшифровка символов с картинки капчи - задача в основном достаточно простая и требует лишь внимательности пользователя. Учитывайте язык написания символов и наличие прописных и заглавных букв и расшифровка капчи не будет казаться проблемной.

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

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

Намного проще загрузить картинку на специальный сайт и получить готовый текст, который можно скопировать и вставить в Word.

Бесплатная расшифровка текста с картинки

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

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

Работают все сервисы по распознаванию практически одинаково. Чтобы показать вам пример, мы подготовили изображение с текстом:

Теперь нужно найти систему, которая обрабатывает картинки и выдает тексты с них. Через Яндекс находим первый попавшийся сайт Img2txt.com . Через форму загрузки выбираем картинку:

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

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

Сервисы распознавания текста с картинок

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

  1. Ocrconvert.com - бесплатный сервис расшифровки текста с картинок, в котором можно сразу загрузить 5 файлов (до 5 Мб.). После распознавания выдается ссылка на файл в формате TXT (для обычного блокнота).
  2. I2ocr.com - в отличие от первого сервиса, этот поддерживает больше форматов (TIF, JPEG, PNG, BMP, GIF, PBM, PGM, PPM). Также, можно загружать картинки на 10 Мб. сразу, результат выдается в формате doc (под Word).
  3. Newocr.com - самый крупный ресурс, поддерживающий любые форматы изображений. Только здесь можно указать область картинки, с которой требуется распознать текст. Доступно 58 языков, регистрация не требуется.
  4. Onlineocr.net - чуть меньше языков поддерживает этот сервис (32). Зато здесь сразу добавляется до 15 картинок (не больше 4 Мб.) для распознавания текста. Регистрироваться и платить не нужно, результат можно скачать в разных форматах.
  5. Free-ocr.com - пользуйтесь без регистрации, распознает текст по одной странице, не больше 10 штук в час. Изображение должны быть менее 2 Мб. и с разрешением меньше 5000 пикселей.

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

Расшифровать или распознать текст с картинки онлайн дело пары минут. Независимо от целей, пользуйтесь этими сервисами, у каждого есть свои плюсы и минусы. Самое главное, что вы получите текстовый контент с графических элементов.

Уже многие психологи подтвердили, что наши рисунки могут многое рассказать о нашей личности, характере и настроении. Неслучайно и в психологии, и в психиатрии многие методы диагностики связаны именно с рисунками. Особенное внимание уделяется детским рисункам. При анализе личности взрослого человека, можно использовать рисунки, которые он делает между делом — все мы часто водим карандашом по бумаге во время телефонных разговоров, совещаний, лекций или длительного ожидания. Из этой статьи вы узнаете, о чем могут рассказать наши рисунки.

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

  • Прежде всего, в рисунках мы выражаем то, что думаем. Поскольку этот способ диалога с внешним миром является косвенным, в отличие, например, от речи, рисунки в меньшей степени контролируются нашим сознанием. Если, отвечая на вопросы, мы пропускаем свои слова через некие внутренние фильтры, то, выражая нечто через рисунок, мы ощущаем себя свободнее и демонстрируем себя настоящих. Например, так можно объяснить расположение рисунков и их содержание.
  • Наши мышечные движения находят прямое отражение в рисунках. Характер движений руки отразится на линиях и размерах изображения. Вы наверняка замечали, что наши движения зависят как от сиюминутных эмоций, так и от темперамента и характера. Даже в процессе обычного общения очень много информации о человеке мы получаем невербально: наблюдая, как он жестикулирует, и как изменяется его мимика. Движения руки, о которых легко можно судить по рисунку, также могут дать нам представление о характере и настроении человека.

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

Особое место занимает в психологии анализ детского рисунка. Расшифровывать их во многом проще, чем рисунки взрослых, потому что детские рисунки отличаются большим разнообразием и широкой цветовой гаммой. Если вы хотите научиться интерпретировать взрослые или детские рисунки, обращать внимание следует не только на содержание изображения. Расположение объекта на листе, его цвет и характер линий имеют не меньшее значение.

О чем говорит расположение рисунка?

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

  • Рисунок, расположенный ближе к верхнему краю листа, свидетельствует о высокой самооценке и целеустремленности. Для такого типа людей основной жизненный приоритет — самореализация и стремление к успеху. Такие люди любят соревновательный процесс, стремятся быть лучшими в любом деле. Нередко они также достаточно азартны и обладают лидерскими качествами.
  • Соответственно, рисунок, расположенный в нижней части листа, говорит о том, что у человека достаточно низкая самооценка, он не ощущает себя востребованным и не заинтересован бороться за первенство.
  • Изображения слева говорят о консервативности и ностальгии. Этот человек погружен в свои воспоминания, и прошлое служит для него ориентиром.
  • Если человек рисует что-либо справа, это, наоборот, означает его устремленность в будущее. Это значит, что человек ожидает позитивных перемен, а текущее положение дел его не устраивает. Стоит отметить, что данные правила анализа специфичны для каждой культуры. Например, движения слева направо характерно для нашей письменности, поэтому из рисунков можно сделать выводы по аналогии.

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

О чем говорит размер рисунка?

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

  • Крупные рисунки свидетельствуют о высокой самооценке. Если рисунок чрезмерно большой и смотрится неестественно, это может говорить о высокомерии и тщеславии, глубинной причиной которых, напротив, является неуверенность в своих силах.
  • Об особенной неуверенности свидетельствуют рисунки, стремящиеся занять все место на листе. Это связано с психологическим механизмом компенсации: если человек не может утвердиться на своем месте в жизни, мысленно он стремится забрать все самое лучшее, занять как можно больше пространства. Обычно такие люди — экстраверты, которые по тем или иным причинам не могут в достаточной мере реализовать себя в обществе. Это находит отражение в рисунках.
  • Интроверты обычно рисуют небольшие изображения и оставляют много пустого пространства вокруг. Необоснованно маленькие рисунки психологи интерпретируют как зажатость, скованность, страх и тревогу. Такие люди эмоционально закрыты, испытывают дискомфорт во внешнем мире, стесняются себя или не доверяют окружению.

Цвет рисунков в психологии

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

  • Зеленый цвет может свидетельствовать о независимости, самодостаточности и упрямстве. Этот цвет используют дети, желающие самоутвердиться.
  • Желтые рисунки говорят о том, что человек ощущает себя комфортно.
  • Синий означает обеспокоенность и погруженность в себя. Синие рисунки делают в моменты обдумывания прошлого или в попытках решить какую-либо проблему.
  • Фиолетовый цвет указывает на развитую фантазию.
  • Красный цвет свидетельствует о потребности выплеснуть накопившуюся энергию. Этот цвет часто используют гиперактивные дети. Также красный может служить сигналом скрытой агрессии.
  • Серый свидетельствует о скуке и нехватке позитивных эмоций.
  • Коричневый цвет обозначает подсознательный протест. Ребенок, часто использующий коричневую краску, недоволен какой-либо ситуацией, ощущает обеспокоенность и дискомфорт.
  • Черный ассоциируется с подавленным состоянием. Такие рисунки свидетельствуют о том, что ребенок сильно сконцентрирован на своей проблеме, и ему не хватает позитивных переживаний.
  • В случайных рисунках взрослых плотно заштрихованные фигуры могут означать закрытость, ощущение себя в рамках. Нередко такие рисунки свидетельствуют о творческом кризисе человека.
  • Если человек никогда не заштриховывает свои изображения, это говорит о его готовности воспринимать новое и принимать перемены.

О чем говорят линии на рисунке?

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

  • Сплошные линии указывают на эмоциональную стабильность, гибкость и уверенность. Такие люди обычно спокойные, и уверены, что справятся со всеми возникающими трудностями.
  • Прерывистые линии, напротив, обозначают неуверенность и нестабильность.
  • Жирные линии могут свидетельствовать о желании человека выделиться и утвердиться. Такими линиями мы можем стараться компенсировать внутреннюю неуверенность, желание быть замеченными и оцененными.
  • Намеренно тонкие линии, когда человек почти не нажимает на карандаш и едва касается бумаги, говорят о желании избежать внимания и общения, о потребности уединения. Подобные линии также могут возникать, если человек испытывает стыд и чувство вины.

  • Строго геометрические рисунки, где все углы прямые, а все линии перпендикулярны или параллельны друг другу, могут означать скрытую агрессию. Также подобные линии говорят о консервативности и трудностях с адаптацией к новому.
  • Явно выраженную агрессию и враждебность можно определить по обилию острых углов на рисунке.
  • Округлые линии и мягкие изгибы говорят о мягкости и гибкости человека. Обычно такие рисунки присущи женщинам чаще, чем мужчинам.
  • Узкие и миниатюрные фигуры говорят о закрепощенности, стремлении придерживаться правил и не выходить за рамки.
  • Крупные объемные фигуры свидетельствуют о том, что человек имеет широкий кругозор и эмоционально открыт.

О чем говорят нарисованные предметы?

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

  • Живые объекты, к которым относятся животные или люди, свидетельствуют о нехватке общения, потребности в социальном контакте. Также подобные изображения могут указывать на сложную проблему в жизни человека, которую он боится решать в одиночку.
  • Пустые пейзажи, изображающие природу без людей, указывают на трудности в коммуникации и понимании чужих чувств или мыслей.
  • Повторение стандартных простых орнаментов, например, цветов, облаков, деревьев или звездочек, говорит об эмоциональной закрытости и попытке скрыть свои истинные переживания.
  • Сюжетные рисунки, изображающие людей или животных в движении, выдают активную и деятельную натуру.

Психология рисунка взрослого человека

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

  • Волнистые линии и спирали могут говорить о том, что человек находится в сложной ситуации и пытается преодолеть кризис. Такие рисунки указывают на безвыходность и появляются, если человек запутался в чем-либо.
  • Сетка говорит о том, что человек чувствует себя в неприятном, уязвимом положении.
  • Часто люди между делом рисуют солнце или цветочки. К сожалению, значение таких рисунков совсем не так очевидно, как кажется. Рисунки цветов в психологи, как и рисунки солнца, чаще всего выражают грусть и потребность во внимании и общении.
  • Радость может выражаться в рисунках с сердцами.
  • Повторяющиеся орнаменты свидетельствуют о скуке.
  • Если человек рисует людей, это значит, что он хочет переложить на кого-то ответственность и избежать работы. Также это может означать потребность в помощи и поддержке.
  • Рисунок дома в психологии означает усталость, враждебность человека по отношению к окружающему миру и желание расслабиться в благоприятной для этого среде.
  • Шахматы обычно рисуют люди, попавшие в неоднозначную и сложную ситуацию, когда они не знают, какое решение принять.
  • Пчелиные соты, нарисованные взрослым человеком, говорят о гармонии и спокойствии.
  • Если человек рисует геометрические фигуры, это может говорить о твердости его убеждений и уверенности в принятом решении.

Психология детского рисунка

Наиболее часто встречающиеся рисунки вы сможете интерпретировать самостоятельно — в любом рисунке всегда есть несколько основных критериев, по которым можно судить о темпераменте и эмоциональном состоянии ребенка. Что означают детские рисунки в психологии?

  • Пейзажи с лесом, лужайкой или улицей без людей у детей могут сигнализировать об одиночестве и проблемах в общении. Если ребенок рисует безлюдные пейзажи, скорее всего, у него не ладятся отношения со сверстниками.
  • Рисунок дома также, как и у взрослых, говорит об усталости и потребности в уюте и отдыхе в окружении близких людей.
  • О внутреннем напряжении, страхе и дискомфорте могут свидетельствовать рисунки чудовищ. Часто подобные изображения отражают популярные детские страхи.
  • Внимание стоит обратить на рисунок семьи. Рисунок семьи в психологии у детей хорошо демонстрирует то, какой им видится их семья. Если семья изображена в полном составе и в ярких красках, значит, дела идут хорошо и ребенку комфортно. Если ребенок кого-то не изобразил, стоит задуматься — возможно, этого человека не хватает в жизни ребенка, он уделяет ребенку мало внимания. Черные и коричневые краски в изображении семьи говорят о проблемах и негативе, который ощущает ребенок. Также у маленьких детей самая крупная фигура будет означать главу семьи в детском понимании.
  • Рисунок дерева в психологии означает стремление к познанию и развитию. Однако важное значение имеет и то, как именно нарисовано дерево. В детской психологии есть тесты по рисункам — один из таких тестов заключается в том, что ребенку предлагается нарисовать дерево. По наличию или отсутствию корней можно судить о том, насколько глубоко ребенок привык мыслить. Кривизна ствола или ствол необычной формы говорит о стрессе, неудовлетворенности и дискомфорте. Крону дерева вы легко сможете оценить по линиям, из которых она состоит — округлые ли линии или с заостренными углами, тонкие или жирные, сплошные или прерывистые.
  • Рисунки животных в психологии считаются хорошим знаком — они свидетельствуют о спокойствии и радости ребенка.
  • Интерпретации рисунка человека в психологии уделяют особе место — особенно это интересно в работе с детьми. Если ребенок рисует другого человека, это часто обозначает нехватку общения. Стоит обращать внимание также на то, нарисован ли конкретный человек или некий собирательный образ. Если человек нарисован в темных красках и неестественно крупным, возможно, у ребенка присутствует страх людей.
  • Если ребенок рисует себя, это говорит о потребности в самопознании и самовыражении. Детские рисунки часто не слишком пропорциональны, по мелким деталям изображения тоже можно многое сказать. Например, большие уши говорят о дерзости и желании выделяться, короткие ноги указывают на низкую самооценку, а длинные руки свидетельствуют о том, что ребенок всегда готов пробовать новое.

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

Видео: «О чем говорят наши рисунки?»

  • Tutorial

UPD. Был вынужден убрать моноширинное форматирование. В один прекрасный день хабрапарсер перестал воспринимать форматирование внутри тегов pre и code. Весь текст превратился в кашу. Администрация хабра не смогла мне помочь. Теперь неровно, но хотя бы читабельно.

Вам когда-нибудь хотелось узнать как устроен jpg-файл? Сейчас разберемся! Прогревайте ваш любимый компилятор и hex-редактор, будем декодировать это:

Специально взял рисунок поменьше. Это знакомый, но сильно пережатый favicon Гугла:

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

Даже не зная, как происходит кодирование, мы уже можем кое-что извлечь из файла.
- маркер начала. Он всегда находится в начале всех jpg-файлов.
Следом идут байты . Это маркер, означающий начало секции с комментарием. Следующие 2 байта - длина секции (включая эти 2 байта). Значит в следующих двух - сам комментарий. Это коды символов ":" и ")", т.е. обычного смайлика. Вы можете увидеть его в первой строке правой части hex-редактора.

Немного теории

Очень кратко по шагам:
Давайте подумаем, в каком порядке могут быть закодированы эти данные. Допустим, сначала полностью, для всего изображения, закодирован канал Y, затем Cb, потом Cr. Все помнят загрузку картинок на диал-апе. Если бы они кодировались именно так, нам бы пришлось ждать загрузки всего изображения, прежде чем оно появится на экране. Так же будет неприятно, если потерятся конец файла. Вероятно, существуют и другие весомые причины. Поэтому закодированные данные располагаются поочередно, небольшими частями.

Напоминаю, что каждый блок Y ij , Cb ij , Cr ij - это матрица коэффициентов ДКП, закодированная кодами Хаффмана. В файле они располагаются в таком порядке: Y 00 Y 10 Y 01 Y 11 Cb 00 Cr 00 Y 20

Чтение файла

После того, как мы извлекли комментарий, будет легко понять, что:
  • Файл поделен на секторы, предваряемые маркерами.
  • Маркеры имеют длину 2 байта, причем первый байт .
  • Почти все секторы хранят свою длину в следующих 2 байта после маркера.
Для удобства подсветим маркеры:
FF D8 FF FE 00 04 3A 29 FF DB 00 43 00 A0 6E 78



FF FF FF FF FF FF FF FF FF FF FF FF FF FF DB 00
43 01 AA B4 B4 F0 D2 F0 FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF C0 00 11 08 00 10 00 10 03 01 22 00 02
11 01 03 11 01 FF C4 00 15 00 01 01 00 00 00 00
00 00 00 00 00 00 00 00 00 00 03 02 FF C4 00 1A
10 01 00 02 03 01 00 00 00 00 00 00 00 00 00 00
00 01 00 12 02 11 31 21 FF C4 00 15 01 01 01 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF
C4 00 16 11 01 01 01 00 00 00 00 00 00 00 00 00
00 00 00 00 11 00 01 FF DA 00 0C 03 01 00 02 11
03 11 00 3F 00 AE E7 61 F2 1B D5 22 85 5D 04 3C
82 C8 48 B1 DC BF FF D9

Маркер : DQT - таблица квантования.

FF DB 00 43 00 A0 6E 78
8C 78 64 A0 8C 82 8C B4 AA A0 BE F0 FF FF F0 DC
DC F0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF

Заголовок секции всегда занимает 3 байта. В нашем случае это . Заголовок состоит из:
Длина: 0x43 = 67 байт
Длина значений в таблице: 0 (0 - 1 байт, 1 - 2 байта)
[_0] Идентификатор таблицы: 0
Оставшимися 64-мя байтами нужно заполнить таблицу 8x8.



Приглядитесь, в каком порядке заполнены значения таблицы. Этот порядок называется zigzag order:

Маркер : SOF0 - Baseline DCT

Этот маркер называется SOF0, и означает, что изображение закодировано базовым методом. Он очень распространен. Но в интернете не менее популярен знакомый вам progressive-метод, когда сначала загружается изображение с низким разрешением, а потом и нормальная картинка. Это позволяет понять что там изображено, не дожидаясь полной загрузки. Спецификация определяет еще несколько, как мне кажется, не очень распространенных методов.

FF C0 00 11 08 00 10 00 10 03 01 22 00 02
11 01 03 11 01

Длина: 17 байт.
Precision: 8 бит. В базовом методе всегда 8. Как я понял, это разрядность значений каналов.
Высота рисунка: 0x10 = 16
Ширина рисунка: 0x10 = 16
Количество компонентов: 3. Чаще всего это Y, Cb, Cr.

1-й компонент:
Идентификатор: 1
Горизонтальное прореживание (H 1): 2
[_2] Вертикальное прореживание (V 1): 2
Идентификатор таблицы квантования: 0

2-й компонент:
Идентификатор: 2
Горизонтальное прореживание (H 2): 1
[_1] Вертикальное прореживание (V 2): 1

3-й компонент:
Идентификатор: 3
Горизонтальное прореживание (H 3): 1
[_1] Вертикальное прореживание (V 3): 1
Идентификатор таблицы квантования: 1

Теперь посмотрите, как определить насколько прорежено изображение. Находим H max =2 и V max =2 . Канал i будет прорежен в H max /H i раз по горизонтали и V max /V i раз по вертикали.

Маркер : DHT (таблица Хаффмана)

Эта секция хранит коды и значения полученные кодированием Хаффмана .

FF C4 00 15 00 01 01 00 00 00 00
00 00 00 00 00 00 00 00 00 00 03 02

длина: 21 байт.
класс: 0 (0 - таблица DC коэффициэнтов, 1 - таблица AC коэффициэнтов).
[_0] идентификатор таблицы: 0
Длина кода Хаффмана: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Количество кодов:
Количество кодов означает количество кодов такой длины. Обратите внимание, что секция хранит только длины кодов, а не сами коды. Мы должны найти коды сами. Итак, у нас есть один код длины 1 и один - длины 2. Итого 2 кода, больше кодов в этой таблице нет.
С каждым кодом сопоставлено значение, в файле они перечислены следом. Значения однобайтовые, поэтому читаем 2 байта.
- значение 1-го кода.
- значение 2-го кода.

Построение дерева кодов Хаффмана

Мы должны построить бинарное дерево по таблице, которую мы получили в секции DHT. А уже по этому дереву мы узнаем каждый код. Значения добавляем в том порядке, в каком указаны в таблице. Алгоритм прост: в каком бы узле мы ни находились, всегда пытаемся добавить значение в левую ветвь. А если она занята, то в правую. А если и там нет места, то возвращаемся на уровень выше, и пробуем оттуда. Остановиться нужно на уровне равном длине кода. Левым ветвям соответствует значение 0 , правым - 1 .
Замечание:
Не нужно каждый раз начинать с вершины. Добавили значение - вернитесь на уровень выше. Правая ветвь существует? Если да, идите опять вверх. Если нет - создайте правую ветвь и перейдите туда. Затем, с этого места, начинайте поиск для добавления следующего значения.

Деревья для всех таблиц этого примера:


UPD (спасибо ): В узлах первого дерева (DC, id =0) должны быть значения 0x03 и 0x02

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

Маркер : SOS (Start of Scan)

Байт в маркере означает - «ДА! Наконец-то то мы перешли непосредственно к разбору секции закодированного изображения!». Однако секция символично называется SOS.

  FF DA 00 0C 03 01 00 02 11
03 11 00 3F 00

Длина заголовочной части (а не всей секции): 12 байт.
Количество компонентов сканирования. У нас 3, по одному на Y, Cb, Cr.

1-й компонент:
Номер компонента изображения: 1 (Y)
Идентификатор таблицы Хаффмана для DC коэффициэнтов: 0
[_0] Идентификатор таблицы Хаффмана для AC коэффициэнтов: 0

2-й компонент:
Номер компонента изображения: 2 (Cb)

[_1]

3-й компонент:
Номер компонента изображения: 3 (Cr)
Идентификатор таблицы Хаффмана для DC коэффициэнтов: 1
[_1] Идентификатор таблицы Хаффмана для AC коэффициэнтов: 1

Данные компоненты циклически чередуются.

На этом заголовочная часть заканчивается, отсюда и до конца (маркера ) закодированные данные.


0

Нахождение DC-коэффициента.
1. Читаем последовательность битов (если встретим 2 байта , то это не маркер, а просто байт ) . После каждого бита сдвигаемся по дереву Хаффмана (с соответствующим идентификатором) по ветви 0 или 1, в зависимости от прочитанного бита. Останавливаемся, если оказались в конечном узле.
10 1011101110011101100001111100100

2. Берем значение узла. Если оно равно 0, то коэффициент равен 0, записываем в таблицу и переходим к чтению других коэффициентов. В нашем случае - 02. Это значение - длина коэффициента в битах. Т. е. читаем следующие 2 бита, это и будет коэффициент.
10 10 11101110011101100001111100100

3. Если первая цифра значения в двоичном представлении - 1, то оставляем как есть: DC_coef = значение. Иначе преобразуем: DC_coef = значение-2 длина значения +1 . Записываем коэффициент в таблицу в начало зигзага - левый верхний угол.

Нахождение AC-коэффициентов.
1. Аналогичен п. 1, нахождения DC коэффициента. Продолжаем читать последовательность:
10 10 1110 1110011101100001111100100

2. Берем значение узла. Если оно равно 0, это означает, что оставшиеся значения матрицы нужно заполнить нулями. Дальше закодирована уже следующая матрица. Первые несколько дочитавших до этого места и написавших об этом мне в личку, получат плюс в карму. В нашем случае значение узла: 0x31.
Первый полубайт: 0x3 - именно столько нулей мы должны добавить в матрицу. Это 3 нулевых коэффициэнта.
Второй полубайт: 0x1 - длина коэффициэнта в битах. Читаем следующий бит.
10 10 1110 1 110011101100001111100100

3. Аналогичен п. 3 нахождения DC-коэффициента.

Как вы уже поняли, читать AC-коэффициенты нужно пока не наткнемся на нулевое значение кода, либо пока не заполнится матрица.
В нашем случае мы получим:
10 10 1110 1 1100 11 101 10 0 0 0 1 11110 0 100
и матрицу:





Вы заметили, что значения заполнены в том же зигзагообразном порядке?
Причина использования такого порядка простая - так как чем больше значения v и u, тем меньшей значимостью обладает коэффициент S vu в дискретно-косинусном преобразовании. Поэтому, при высоких степенях сжатия малозначащие коэффициенты обнуляют, тем самым уменьшая размер файла.

[-4 1 1 1 0 0 0 0] [ 5 -1 1 0 0 0 0 0]
[ 0 0 1 0 0 0 0 0] [-1 -2 -1 0 0 0 0 0]
[ 0 -1 0 0 0 0 0 0] [ 0 -1 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [-1 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]

[-4 2 2 1 0 0 0 0]
[-1 0 -1 0 0 0 0 0]
[-1 -1 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]

Ой, я забыл сказать, что закодированные DC-коэффициенты - это не сами DC-коэффициенты, а их разности между коэффициентами предыдущей таблицы (того же канала)! Нужно поправить матрицы:
DC для 2-ой: 2 + (-4) = -2
DC для 3-ой: -2 + 5 = 3
DC для 4-ой: 3 + (-4) = -1

[-2 1 1 1 0 0 0 0] [ 3 -1 1 0 0 0 0 0] [-1 2 2 1 0 0 0 0]
………

Теперь порядок. Это правило действует до конца файла.

… и по матрице для Cb и Cr:

[-1 0 0 0 0 0 0 0]
[ 1 1 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]

Так как тут только по одной матрице, DC-коэфициенты можно не трогать.

Вычисления

Квантование

Вы помните, что матрица проходит этап квантования? Элементы матрицы нужно почленно перемножить с элементами матрицы квантования. Осталось выбрать нужную. Сначала мы просканировали первый компонент, его компонента изображения = 1. Компонент изображения с таким идентификатором использует матрицу квантования 0 (у нас она первая из двух). Итак, после перемножения:


[ 0 120 280 0 0 0 0 0]
[ 0 -130 -160 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]

Аналогично получаем еще 3 матрицы Y-канала…

[-320 110 100 160 0 0 0 0] [ 480 -110 100 0 0 0 0 0]
[ 0 0 140 0 0 0 0 0] [-120 -240 -140 0 0 0 0 0]
[ 0 -130 0 0 0 0 0 0] [ 0 -130 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [-140 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]

[-160 220 200 160 0 0 0 0]
[-120 0 -140 0 0 0 0 0]
[-140 -130 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]

… и по матрице для Cb и Cr.

[-170 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 180 210 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]

Обратное дискретно-косинусное преобразование

Формула не должна доставить сложностей*. S vu - наша полученная матрица коэффициентов. u - столбец, v - строка. s yx - непосредственно значения каналов.

*Вообще говоря, это не совсем правда. Когда я смог декодировать и отобразить на экране рисунок 16x16, я взял изображение размером 600x600 (кстати, это была обложка любимого альбома Mind.In.A.Box - Lost Alone). Получилось не сразу - всплыли различные баги. Вскоре я мог любоваться корректно загруженной картинкой. Только очень огорчала скорость загрузки. До сих пор помню, она занимала 7 секунд. Но это и неудивительно, если бездумно пользоваться приведенной формулой, то для вычисления одного канала одного пикселя потребуется нахождения 128 косинусов, 768 умножений, и сколько-то там сложений. Только вдумайтесь - почти тысяча непростых операций только на один канал одного пиксела! К счастью, тут есть простор для отимизации (после долгих экспериментов уменьшил время загрузки до предела точности таймера 15мс, и после этого сменил изображение на фотографию в 25 раз большей площадью. Возможно, напишу об этом отдельной статьей).

Напишу результат вычисления только первой матрицы канала Y (значения округлены):


[ 87 72 50 36 37 55 79 95]
[-10 5 31 56 71 73 68 62]
[-87 -50 6 56 79 72 48 29]

И 2-х оставшихся:
Cb Cr
[ 60 52 38 20 0 -18 -32 -40] [ 19 27 41 60 80 99 113 120]
[ 48 41 29 13 -3 -19 -31 -37] [ 0 6 18 34 51 66 78 85]
[ 25 20 12 2 -9 -19 -27 -32] [-27 -22 -14 -4 7 17 25 30]
[ -4 -6 -9 -13 -17 -20 -23 -25] [-43 -41 -38 -34 -30 -27 -24 -22]
[ -37 -35 -33 -29 -25 -21 -18 -17] [-35 -36 -39 -43 -47 -51 -53 -55]
[ -67 -63 -55 -44 -33 -22 -14 -10] [ -5 -9 -17 -28 -39 -50 -58 -62]
[ -90 -84 -71 -56 -39 -23 -11 -4] [ 32 26 14 -1 -18 -34 -46 -53]
[-102 -95 -81 -62 -42 -23 -9 -1] [ 58 50 36 18 -2 -20 -34 -42]

  1. О, пойду-ка поем!
  2. Да я вообще не въезжаю, о чем речь.
  3. Раз значение цветов YCbCr получены, осталось преобразовать в RGB, типа так: YCbCrToRGB(Y ij , Cb ij , Cr ij) , Y ij , Cb ij , Cr ij - наши полученные матрицы.
  4. 4 матрицы Y, и по одной Cb и Cr, так как мы прореживали каналы и 4 пикселям Y соответствует по одному Cb и Cr. Поэтому вычислять так: YCbCrToRGB(Y ij , Cb , Cr )
Если вы выбрали 1 и 4, то я рад за вас. Либо вы все правильно поняли, либо скоро будете получать удовольствие от еды.

YCbCr в RGB

R = Y + 1.402 * Cr
G = Y - 0.34414 * Cb - 0.71414 * Cr
B = Y + 1.772 * Cb
Не забудьте прибавить по 128. Если значения выйдут за пределы интервала , то присвоить граничные значения. Формула простая, но тоже отжирает долю процессорного времени.

Вот полученные таблицы для каналов R, G, B для левого верхнего квадрата 8x8 нашего примера:
255 248 194 148 169 215 255 255
255 238 172 115 130 178 255 255
255 208 127 59 64 112 208 255
255 223 143 74 77 120 211 255
237 192 133 83 85 118 184 222
177 161 146 132 145 162 201 217
56 73 101 126 144 147 147 141
0 17 76 126 153 146 127 108

231 185 117 72 67 113 171 217
229 175 95 39 28 76 139 189
254 192 100 31 15 63 131 185
255 207 115 46 28 71 134 185
255 241 175 125 112 145 193 230
226 210 187 173 172 189 209 225
149 166 191 216 229 232 225 220
72 110 166 216 238 231 206 186

255 255 249 203 178 224 255 255
255 255 226 170 140 187 224 255
255 255 192 123 91 138 184 238
255 255 208 139 103 146 188 239
255 255 202 152 128 161 194 232
255 244 215 200 188 205 210 227
108 125 148 172 182 184 172 167
31 69 122 172 191 183 153 134

Конец

Вообще я не специалист по JPEG, поэтому вряд ли смогу ответить на все вопросы. Просто когда я писал свой декодер, мне часто приходилось сталкиваться с различными непонятными проблемами. И когда изображение выводилось некорректно, я не знал где допустил ошибку. Может неправильно проинтерпретировал биты, а может неправильно использовал ДКП. Очень не хватало пошагового примера, поэтому, надеюсь, эта статья поможет при написании декодера. Думаю, она покрывает описание базового метода, но все-равно нельзя обойтись только ей. Предлагаю вам ссылки, которые помогли мне:
Похожие статьи