![]() |
JPEG dekomprimieren mit TurboJPEG
Hallo,
ich bin gerade dabei mich mit TurboJPEG zu beschäftigen, um die Komprimierung/Dekomprimierung von JPEGs zu beschleunigen. Das Komprimieren klappt einwandfrei, nur beim Dekomprimieren komme ich nicht weiter. Das JPEG wird (glaube ich) korrekt dekomprimiert und steht in einam TBytes-Array bereit. Nur wie bekomme ich dieses Array nun in eine TBitmap-Instanz? Da stehe ich auf dem Schlauch. Ich habe es mit Scanline versucht, es wird auch etwas erzeugt, nur leider nicht das ursprüngliche Bild. :( Mein aktueller Code dazu:
Delphi-Quellcode:
Es wäre schön, wenn mir jemand einen Lösungsansatz zeigen könnte.
procedure TfrmTurboJPEG.btnCreateBitmapClick(Sender: TObject);
var JH: TJHandle; jpegStream: TMemoryStream; i, Width, Height, Res: Integer; SubSampling: TJPF; OutBuf: TBytes; Bitmap: TBitmap; begin if Assigned(imgJPEG.Picture.Graphic) then begin JH := Rk.Vcl.Imaging.TurboJPEG.InitDecompress; jpegStream := TMemoryStream.Create; Bitmap := TBitmap.Create; try imgJPEG.Picture.Graphic.SaveToStream(jpegStream); Res := Rk.Vcl.Imaging.TurboJPEG.DecompressHeader2(JH, jpegStream.Memory, jpegStream.Size, @Width, @Height, @SubSampling); CheckError(JH, Res); SetLength(OutBuf, Width * Height * 4); Res := Rk.Vcl.Imaging.TurboJPEG.Decompress2(JH, jpegStream.Memory, jpegStream.Size, @OutBuf[0], Width, 0, Height, TJPF_RGBA, 0); CheckError(JH, Res); Bitmap.PixelFormat := pf32Bit; Bitmap.SetSize(Width, Height); for i := 0 to Height - 1 do Move(OutBuf[Width*i], Bitmap.Scanline[i]^, 4 * Width); imgBitmapDecompressed.Picture.Assign(Bitmap); finally Rk.Vcl.Imaging.TurboJPEG.Destroy(JH); jpegStream.Free; Bitmap.Free; end; end; end; Danke und viele Grüße Robert |
AW: JPEG dekomprimieren mit TurboJPEG
Zitat:
Da Du nicht schreibst, wieso Du glaubst, dass das dekomprimierte Bild im Buffer korrekt ist und auch nicht, was an dem erzeugten Bild falsch ist, kann ich dazu nicht mehr sagen. Ach ja: TBitmap speichert die Pixel nicht als RGBA sondern als GBRA, wenn ich das richtig im Kopf habe. D.h. die Farben dürften falsch sein. |
AW: JPEG dekomprimieren mit TurboJPEG
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Thomas,
vielen Dank für deine Antwort. Das mit dem Buffer habe ich so eigenartig geschrieben, weil ich die Daten darin ja nicht interpretieren kann. Ich kann nur feststellen, dass die Methode fehlerfrei zurückkehrt und den Buffer füllt. Das ursprüngliche Bild kann ich im Ergebnis nicht wiedererkennen (nicht nur Farben falsch oder auf den Kopf gestellt). Ich habe mal einen Screenshot gemacht. Die erste Grafik zeigt das ursprüngliche Bitmap. Die zweite Grafik das mit tjCompress2 erzeugte JPEG. Die dritte Grafik ist der mit tjDeceompress2 erzeugte Buffer, den ich mit der o.g. Function mit Scanline in die Bitmap-Instanz lade. Viele Grüße Robert |
AW: JPEG dekomprimieren mit TurboJPEG
Oh, wie in guten alten Zeiten als ich angefangen habe Bitmaps selber zu lesen.
Da die Farben weitestgehend passen würde ich sagen dass deine gelesenen Zeilen zu kurz sind. Mal mit einem vielfachen von 8 oder 16 probiert und nicht mit der echten Breite des Bildes? |
AW: JPEG dekomprimieren mit TurboJPEG
Schaue dir mal Vcl.Graphics.TWICImage.RequireBitmap an.
So könntest du es mal versuchen. Hier im Editor mal so runtergetippt:
Delphi-Quellcode:
procedure TfrmTurboJPEG.btnCreateBitmapClick(Sender: TObject);
var JH: TJHandle; jpegStream: TMemoryStream; i, Width, Height, Res: Integer; SubSampling: TJPF; OutBuf: TBytes; Bitmap: TBitmap; BitmapInfo: TBitmapInfo; begin if Assigned(imgJPEG.Picture.Graphic) then begin JH := Rk.Vcl.Imaging.TurboJPEG.InitDecompress; try jpegStream := TMemoryStream.Create; try imgJPEG.Picture.Graphic.SaveToStream(jpegStream); Width := 0; Height := 0; Res := Rk.Vcl.Imaging.TurboJPEG.DecompressHeader2(JH, jpegStream.Memory, jpegStream.Size, @Width, @Height, @SubSampling); CheckError(JH, Res); SetLength(OutBuf, Width * Height * 4); Res := Rk.Vcl.Imaging.TurboJPEG.Decompress2(JH, jpegStream.Memory, jpegStream.Size, @OutBuf[0], Width, 0, Height, TJPF_RGBA, 0); CheckError(JH, Res); finally jpegStream.Free; end; finally Rk.Vcl.Imaging.TurboJPEG.Destroy(JH); end; FillChar(BitmapInfo, SizeOf(BitmapInfo), 0); BitmapInfo.bmiHeader.biSize := SizeOf(BitmapInfo); BitmapInfo.bmiHeader.biWidth := Width; BitmapInfo.bmiHeader.biHeight := -Height; BitmapInfo.bmiHeader.biPlanes := 1; BitmapInfo.bmiHeader.biBitCount := 32; Bitmap := TBitmap.Create; try Bitmap.PixelFormat := pf32Bit; Bitmap.SetSize(Width, Height); SetDIBits(0, Bitmap.Handle, 0, Height, @OutBuf[0], BitmapInfo, DIB_RGB_COLORS); Bitmap.AlphaFormat := afDefined; imgBitmapDecompressed.Picture.Assign(Bitmap); finally Bitmap.Free; end; end; end; |
AW: JPEG dekomprimieren mit TurboJPEG
Der eigentliche Fehler im ursprünglichen Code liegt in der Adressberechnung:
Delphi-Quellcode:
Move(OutBuf[4 * Width * i], Bitmap.Scanline[i]^, 4 * Width);
|
AW: JPEG dekomprimieren mit TurboJPEG
Hallo,
vielen Dank für eure Hilfe. Blup, dein Hinweis auf meinen Fehler war die Lösung. Ich hatte den Move die ganze Zeit in Verdacht, aber den Wald vor lauter Bäumen nicht gesehen und einen ganzen Tag damit vertan :cry:. Viele Grüße Robert |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:05 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz