JPEG расчет максимального размера - PullRequest
10 голосов
/ 29 апреля 2010

Я должен сказать, что я мало знаю о том, как работают форматы файлов. У меня вопрос, скажем, у меня есть файл JPEG размером 200 на 200 пикселей, как можно рассчитать, какой максимальный размер этого файла может быть выражен в мегабайтах / байтах?

Я думаю, что рассуждения, которые привели к этому вопросу, помогут кому-нибудь ответить мне. У меня есть Java-апплет для загрузки изображений, которые люди рисуют с его помощью, на мой сервер. Мне нужно знать, какой максимальный размер может достичь этот файл. Это всегда будет 200x200.

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

Ответы [ 5 ]

24 голосов
/ 04 мая 2010

Есть много способов сделать «патологический» файл JPEG / JFIF необычно большого размера.

На крайнем конце спектра нет ограничений по размеру, поскольку стандарт не ограничивает некоторые типы маркеров, появляющихся более одного раза - например, файл JFIF, заполненный многими ГБ маркеров DRI (определить интервал перезапуска) и затем MCU 8x8 пикселей в конце, технически действителен.

Если мы ограничимся «нормальным» использованием маркера, мы найдем верхний предел следующим образом:

Некоторый фон -

  1. JPEG кодирует пиксели в виде MCU (группы) из блоков пикселей 8x8 (блоков DCT), по одному блоку DCT для каждого компонента (Y, Cb, Cr).

  2. Чтобы получить лучшее сжатие (и наименьший размер), используется схема подвыборки цветности 4: 2: 0, где 75% информации о цветности опущено. Чтобы получить наилучшее качество (и самый большой размер), файл имеет 2/3 цветности, 1/3 яркости.

  3. Символы битового потока Хаффмана используются для кодирования компонентов DCT, из которых до 65 на блок DCT (64 AC + 1 DC).

  4. Символы Хаффмана могут находиться в диапазоне от 1 до 16 бит и выбираются кодером как можно меньшего размера; Однако можно указать длину символа.

  5. Окончательное кодирование битового потока Хаффмана должно быть выполнено так, чтобы маркеры могли быть однозначно идентифицированы. Т.е. любое вхождение байта 0xff на выходе должно быть заменено двумя байтами - 0xff, 0x00.

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

Во-первых, нам нужны максимально длинные символы Хаффмана. На первый взгляд, определение символа Хаффмана с максимальной длиной (16 бит) из всех 1 будет занимать большую часть пробела, однако libjpeg отказывается обрабатывать символ Хаффмана, который является всеми 1, это, похоже, не исключается стандартом, так как это по-прежнему уникальный символ, так как размер уже известен как 16 бит в отличие от других символов переменной длины, и действительно некоторые декодеры могут его обрабатывать (JPEGSnoop).

Итак, мы определяем таблицу Хаффмана, которая устанавливает последние два символа следующим образом:

11111111_1111110  -> (0,0) (EOB - end of block value)
11111111_11111110 -> (0,15)

Такая таблица Хаффмана будет отображаться в файле JPEG как:

0xFF, 0xC4 ; DHT - define huffman table
0x00, 35 ; length
0x00 ; DC 0
1,1,1,1,1,1,1,1,1,1, 1, 1, 1, 1, 1, 1 ; histogram
1,2,3,4,5,6,7,8,9,10,11,12,13,14,0,15 ; symbols

Теперь для кодирования блока DCT максимальной длины:

1 x DC of 31 bits  ( 11111111 11111110 11111111 1111111 )
64 x AC of 31 bits ( 11111111 11111110 11111111 1111111 )
= 2015 bits

Поскольку MCU будет 3 блоками DCT (по одному для каждого компонента), размер MCU будет 6045 бит.

Большинство этих байтов будут 0xff, которые заменяются на 0xff, 0x00 в выходном потоке в соответствии со стандартом, чтобы отличать поток битов от допустимых маркеров.

Выполните это отображение, и полный DCT будет представлен 8 повторами следующего шаблона байтов:

0xff,0x00,0xfe,0xff,0x00,0xff,0x00
0xff,0x00,0xfd,0xff,0x00,0xff,0x00
0xff,0x00,0xfb,0xff,0x00,0xff,0x00
0xff,0x00,0xf7,0xff,0x00,0xff,0x00
0xff,0x00,0xef,0xff,0x00,0xff,0x00
0xff,0x00,0xdf,0xff,0x00,0xff,0x00
0xff,0x00,0xbf,0xff,0x00,0xff,0x00
0xff,0x00,0x7f,0xff,0x00

, что составляет 8 * 54 = 432 байта

Сложив все это, мы имеем: 3 компонента * (432 байта на компонент) = 1296 байт на 8x8 пикселей

для сегментов SOI / DHT / DQT / SOS для настройки свойств изображения и таблиц Хаффмана требуется заголовок из 339 байт, для завершения изображения требуется 2-байтовый маркер EOI.

Поскольку изображение размером 200x200 будет размером 25x25 микроконтроллеров, у нас есть окончательный размер:

339 + (25 * 25 * 1296) + 2 = 810341 байт

, который работает чуть более 20,25 байта на пиксель, в 6 раз больше, чем несжатый BMP / TGA.

11 голосов
/ 29 апреля 2010

Как правило, ни один JPEG не будет больше 32-битного растрового изображения эквивалентного размера. 32-битное растровое изображение будет иметь 4 байта на пиксель в изображении, поэтому умножьте размеры вместе (200x200 = 40000), затем умножьте это на 4 байта (40000x4 = 160000), и у вас будет верхняя граница в байтах - для ваш пример, 160000 байт - это примерно 156 КБ.

3 голосов
/ 29 апреля 2010

Максимально возможный размер JPEG может быть где-то около width * height * 12 bits.

JPEG преобразует изображения в другое цветовое пространство (YCbCr), которое использует меньше битов (12, если быть точным) для представления одного цвета. Хотя на самом деле изображение будет намного меньше, чем можно предположить по приведенной выше формуле.

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

Короче говоря: вершины 60 КБ, но, скорее всего, намного меньше.

0 голосов
/ 29 апреля 2010

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

Однако, согласно википедии, максимум составляет примерно 9 бит на пиксель.

То есть 200 * 200 * 9 = 360000 бит = 45 кБ

http://en.wikipedia.org/wiki/JPEG#Effects_of_JPEG_compression

0 голосов
/ 29 апреля 2010

Я не уверен, что это было бы так полезно, но я полагаю, что абсолютный максимум, который он мог бы быть:

width * height * 4 (size of int) Возможно, вам также следует добавить метаданные, возможно, в килобайтах ... но я сомневаюсь, что изображение ДАЛЕЕ достигнет этого (поскольку в этом и заключается весь смысл сжатия JPEG)

...