2009-07-13 5 views
3

Я пишу программу на C++ для преобразования BMP-изображения в JPEG.Нужна помощь по преобразованию 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. Кодировать коэффициент постоянного и переменного тока отдельно, используя кодировку huffman.
  7. Написать надлежащий заголовок и написать HUFFMAN закодированное значение в файл ...

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

  • Сгенерированный JPEG отображается неправильно.
  • Я сделал небольшой файл размером 8 * 8 24 бит (цветная глубина) bmp, заполненный значением цвета R = 10 B = 10 и G = 100 ... все 64 пикселя одного цвета.
  • Данные что я не клоню каждый шаг заключается в следующем ...
    • BMP размер заголовка 40
    • размер заголовка 40
    • шириной 8
    • высота 8
    • нет плоскостей 1
    • нет бит на пиксель 24
    • размера изображения 194
    • разрешения х пикселей на метр 2834
    • разрешения у пикселей на метр 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 постоянного тока кодирования: 00111110
  • У ас кодирование: 1010 (для переменного тока таблицы Хаффмана (яркости Y), значение EOB является 1010)
  • Similary Хаффман кодирование Cb и Cr компонентов заключается в следующем:
  • куб постоянный ток кодирование: 11000010
  • CB AC кодирование: 01 (для переменного тока раздражения Человек стол (цветности Cb, Cr) значение EOB является 01)
  • кр постоянного тока кодирования: 110101110
  • кр ас кодирование: 01
  • Конечный код Хаффмана, что я получаю:

    001111101010110000100111010111001 Длина 33

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

0011111010101100001001110101110011111111 Length 40. 

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

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

+2

Вам, похоже, нужна помощь при составлении сообщения и выборе соответствующих тегов. –

+0

Наконец-то отличный технический вопрос. Спасибо, Марк. К сожалению, у меня нет ответа, но я надеюсь, что кто-то это сделает. – caskey

+1

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

ответ

2

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

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

1) Цветовое преобразования 2) FDCT 3) Квантование 4) зигзага переупор 5) Хаффмана кодировать

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

a) Правильно ли вы обрабатываете предикторы постоянного тока? b) Правильно ли вы кодируете компоненты A/C w.r.t. пробеги нулей? c) Вы уважаете правило выходного потока о «заполненных нулях» и маркерах? d) Правильно ли ваша формула преобразования цветов? Включает ли он 0x80, который должен быть вычтен из каждого из компонентов? e) Вы кодируете блоки MCU в правильном порядке в зависимости от вашего выбора опции подвыборки?

-1

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