Ich schreibe ein C++-Programm, um ein BMP-Bild in ein JPEG zu konvertieren.
Hier ist der grundlegende Algorithmus, den ich zu befolgen versuche:
- RGB-Farbraum in Y,Cb,Cr. umwandeln.
- 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)
- DCT auf Dateneinheiten von jeweils 8*8 Pixeln anwenden...
- Anschließend wird der DCT-Koeffizient mit Hilfe der Standard-Quantisierungstabelle für Cb und Cr quantisiert.
- Führen Sie eine Zickzack-Bestellung durch.
- Kodieren Sie den DC- und AC-Koeffizienten separat mit der Huffman-Kodierung.
- 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?