4 Stimmen

Benötige Hilfe bei der Konvertierung von BMP in JPEG

Ich schreibe ein C++-Programm, um ein BMP-Bild in ein JPEG zu konvertieren.

Hier ist der grundlegende Algorithmus, den ich zu befolgen versuche:

  1. RGB-Farbraum in Y,Cb,Cr. umwandeln.
  2. Cb und Cr um 2 verringern (d.h. für jeden quadratischen Block von 2*2 gibt es 4 verschiedene Y-Werte, aber 1 Cb- und 1 Cr-Wert)
  3. DCT auf Dateneinheiten von jeweils 8*8 Pixeln anwenden...
  4. Anschließend wird der DCT-Koeffizient mit Hilfe der Standard-Quantisierungstabelle für Cb und Cr quantisiert.
  5. Führen Sie eine Zickzack-Bestellung durch.
  6. Kodieren Sie den DC- und AC-Koeffizienten separat mit der Huffman-Kodierung.
  7. Korrekten Header schreiben und huffman-kodierten Wert in die Datei schreiben...

Ich habe mich vergewissert, dass ich die oben genannten Schritte korrekt ausführe, aber ich habe immer noch die folgenden Probleme:

  • Das erzeugte JPEG wird nicht korrekt angezeigt.
  • Ich habe eine kleine 8*8 24 Bit (Farbtiefe) bmp-Datei komplett mit Farbwert R=10 B=10 und G=100 gefüllt...alle 64 Pixel sind von der gleichen Farbe.
  • Die Daten, die ich bei jedem Schritt erhalte, sehen wie folgt aus...
    • BMP-Header-Größe von 40
    • Größe der Kopfzeile 40
    • Breite 8
    • Höhe 8
    • Anzahl der Flugzeuge 1
    • Anzahl der Bits pro Pixel 24
    • Bildgröße 194
    • x Auflösung Pixel pro Meter 2834
    • y Auflösung Pixel pro Meter 2834
    • Anzahl der Farben 0
    • Anzahl der künstlichen Farben 0
    • Die Y Cb Cr-Umwandlung von (R,B,G)=(10,10,100) ist (62,-29,-37)

Betrachten wir also zunächst die Komponente Y.

Der DCT-Koeffizient für die Y-Komponente ist :

 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

Nach der Quantisierung erhalte ich für die Y-Komponente die folgende Zickzack-Anordnung der einzelnen Dateneinheiten.

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

Die Huffman-Kodierung des obigen Zickzack-Arrays lautet nun :

  • Y Gleichstromkodierung: 00111110
  • Y ac-Kodierung: 1010 (für die ac-Huffman-Tabelle (Leuchtdichte Y) ist der EOB-Wert 1010)
  • Die Huffman-Kodierung der Cb- und Cr-Komponenten sieht wie folgt aus:
  • cb dc-codierung: 11000010
  • cb ac Kodierung: 01 (für ac huffman table(chrominance Cb,Cr) EOB Wert ist 01)
  • cr dc Kodierung: 110101110
  • cr ac Kodierung: 01
  • Der endgültige Huffman-Code, den ich erhalte, lautet

    00111110101011000010011101010111001 Länge 33

Um sie durch 8 teilbar zu machen, wird also 1 aufgefüllt.

0011111010101100001001110101110011111111 Length 40.

Hier ist jede einzelne 0 oder 1 eigentlich ein Bit, das so gespeichert werden muss, wie es in der JPEG-Datei steht, aber da wir nicht Bit für Bit in die Datei schreiben können, werden insgesamt 8 Bits genommen und in einen ganzzahligen Wert zur Basis 10 umgewandelt und in einem 1-Byte-Zeichen gespeichert.

Kann mir jemand Vorschläge machen, was ich falsch mache?

2voto

BitBank Punkte 8192

Um Ihr Problem zu lösen, sollten Sie sich zunächst das Buch von Pennebaker/Mitchel über den JPEG-Standard besorgen.

Die Reihenfolge der Operationen ist:

1) Farbraumkonvertierung 2) FDCT 3) Quantisieren 4) Zickzack-Reihenfolge 5) Huffman-Kodierung

Diese Vorgänge sind aufgrund der zahlreichen Vorschriften, die Sie beachten müssen, sehr komplex.

a) Behandeln Sie die DC-Prädiktoren richtig? b) Kodieren Sie die A/C-Komponenten richtig im Hinblick auf die Nullen? c) Halten Sie die Ausgabestrom-Regel für "aufgefüllte Nullen" und Marker ein? d) Ist Ihre Farbraumkonvertierungsformel korrekt? Beinhaltet sie die 0x80, die von jeder der Komponenten abgezogen werden muss? e) Kodieren Sie die MCU-Blöcke in der richtigen Reihenfolge entsprechend der von Ihnen gewählten Subsampling-Option?

-2voto

Michael Aaron Safyan Punkte 90663

Erfinden Sie das Rad nicht neu. Verwenden Sie ImageMagick, Magick++ oder CImg, um dies zu erreichen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X