Нужна помощь в преобразовании BMP в JPEG - PullRequest
3 голосов
/ 13 июля 2009

Я пишу программу на C ++ для преобразования изображения BMP в JPEG.

Вот основной алгоритм, которому я пытаюсь следовать:

  1. Преобразование цветового пространства RGB в Y, Cb, Cr ..
  2. Уменьшить выборку Cb и Cr на 2 (это означает, что для каждого квадратного блока 2 * 2 есть 4 разных значения Y, но 1 Cb и 1 Cr значение
  3. Применить DCT к блокам данных каждого 8 * 8 пикселей ...
  4. Затем примените квантование к коэффициенту DCT, используя стандартную таблицу квантования Cb и Cr.
  5. Зигзагообразное упорядочение.
  6. Кодировать коэффициент постоянного и переменного тока отдельно, используя кодирование Хаффмана.
  7. Записать правильный заголовок и записать закодированное Хаффманом значение в файл ...

Я подтвердил, что правильно делаю все вышеописанное, но у меня все еще есть следующие проблемы:

  • Генерируемый JPEG-файл отображается неправильно.
  • Я создал небольшой 8 * 8 24-битный (глубина цвета) bmp-файл, полностью заполненный значением цвета R = 10 B = 10 и G = 100 ... все 64 пикселя одного цвета ..
  • Данные, которые я получаю на каждом этапе, выглядят следующим образом ...
    • Размер заголовка BMP 40
    • размер заголовка 40
    • ширина 8
    • высота 8
    • нет самолетов 1
    • количество бит на пиксель 24
    • размер изображения 194
    • x разрешение на пиксель на метр 2834
    • y разрешение на пиксель на метр 2834
    • Нет цветов 0
    • Нет бесцветных цветов 0
    • Преобразование Y Cb Cr (R, B, G) = (10,10 100) составляет (62, -29, -37)

Итак, давайте сначала рассмотрим компонент Y.

Коэффициент DCT для компонента Y:

 495 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

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

30 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

Теперь код Хаффмана вышеупомянутого массива зигзагообразного порядка:

  • Y dc код: 00111110
  • Y ac кодирование: 1010 (для таблицы Хаффмана переменного тока (яркость Y) значение EOB равно 1010)
  • Аналогичное кодирование Хаффмана компонентов Cb и Cr выглядит следующим образом:
  • cb dc кодирование: 11000010
  • cb ac кодирование: 01 (для таблицы Хаффмана ac (цветность Cb, Cr) значение EOB равно 01)
  • CR DC кодирование: 110101110
  • Cr AC кодирование: 01
  • Последний полученный мной код Хаффмана:

    001111101010110000100111010111001 Длина 33

так, чтобы сделать его делимым на 8, заполнение 1 сделано.

0011111010101100001001110101110011111111 Length 40.

Здесь каждый 0 или 1 на самом деле является битом, который необходимо сохранить, как он есть в файле JPEG, но, поскольку мы не можем записать бит в бит в файл, всего 8 бит берут и преобразуют в целое число значение в базе 10 и сохраняется в 1-байтовом символе.

Может кто-нибудь предложить какие-либо предложения о том, где я иду неправильно?

Ответы [ 2 ]

2 голосов
/ 20 июля 2009

Первое, что нужно сделать, чтобы решить вашу проблему, - это приобрести книгу Пеннебейкер / Митчел по стандарту JPEG.

Порядок операций:

1) преобразование цветового пространства 2) FDCT 3) квантовать 4) Зигзагообразный порядок 5) Хаффман кодирует

Эти операции имеют много сложностей из-за множества правил, которым вы должны следовать.

a) Правильно ли вы обрабатываете предикторы DC? б) Правильно ли вы кодируете компоненты системы кондиционирования? пробеги нулей? в) Соблюдаете ли вы правило потока вывода о "дополненных нулях" и маркерах? г) Правильна ли ваша формула преобразования цветового пространства? Включает ли он 0x80, который должен быть вычтен из каждого из компонентов? e) Кодируете ли вы блоки MCU в правильном порядке на основе выбранного вами варианта подвыборки?

0 голосов
/ 20 июля 2009

Не изобретай велосипед. Для этого используйте ImageMagick, Magick ++ или CImg.

...