![]() |
AW: JPEG CompressionQuality ermitteln
Wenn du mit TStatus GPStatus meinst jo..
Delphi-Quellcode:
Status =(
Ok, GenericError, InvalidParameter, OutOfMemory, ObjectBusy, InsufficientBuffer, NotImplemented, Win32Error, WrongState, Aborted, FileNotFound, ValueOverflow, AccessDenied, UnknownImageFormat, FontFamilyNotFound, FontStyleNotFound, NotTrueTypeFont, UnsupportedGdiplusVersion, GdiplusNotInitialized, PropertyNotFound, PropertyNotSupported ); TStatus = Status;
Delphi-Quellcode:
gruss
cStatus : Array[TStatus] of String =(
'Ok', 'GenericError', 'InvalidParameter', 'OutOfMemory', 'ObjectBusy', 'InsufficientBuffer', 'NotImplemented', 'Win32Error', 'WrongState', 'Aborted', 'FileNotFound', 'ValueOverflow', 'AccessDenied', 'UnknownImageFormat', 'FontFamilyNotFound', 'FontStyleNotFound', 'NotTrueTypeFont', 'UnsupportedGdiplusVersion', 'GdiplusNotInitialized', 'PropertyNotFound', 'PropertyNotSupported' ); |
AW: JPEG CompressionQuality ermitteln
Danke Euch allen für die tatkräftige Hilfe!
Zitat:
Delphi-Quellcode:
,
Winapi.GDIPAPI
Delphi-Quellcode:
noch
Winapi.GDIPOBJ
Delphi-Quellcode:
?
Winapi.GDIPUTIL
Ich habe das jetzt mal umgestellt und es klappt (jedenfalls bei mir) tatsächlich:
Delphi-Quellcode:
Eine Frage habe ich trotzdem noch: Wohin verschwindet
Function CalcCompressionQuality(Const Image: GPIMAGE;
Const MustFit: Boolean = False): TJPEGQualityRange; Var aMS : TMemoryStream; aFormat, aEncoder : TGUID; aSA : Winapi.ActiveX.IStream; aSize : Int64; lQ, hQ, Piv, oldPiv : Integer; aEncParams : Winapi.GDIPAPI.TEncoderParameters; Begin Result:= 100; // im Zeifel: beste Qualität! If (GdipGetImageRawFormat(Image, @aFormat) = Status.Ok) And (aFormat = ImageFormatJPEG) And // nur bei JPEG ausführen (GetEncoderClsid('image/jpeg', aEncoder) > -1) Then Begin aMS:= TMemoryStream.Create; // TMemoryStream erzeugen aSA:= TStreamAdapter.Create(aMS, soOwned); // aMS wird selbst aufgeräumt If (GdipSaveImageToStream(Image, aSA, @aEncoder, nil) = Status.Ok) Then Begin aSize:= aMS.Size; // Originalgröße ermitteln lQ:= Low( Result); // untere Grenze hQ:= High(Result); // obere Grenze Piv:= (hQ - lQ) Div 2; // in der Mitte anfangen Repeat aMS.Clear; // Stream leeren FillChar(aEncParams, SizeOf(aEncParams), 0); aEncParams.Count:= 1; With aEncParams.Parameter[0] Do Begin Guid:= EncoderQuality; // um diese Einstellung geht es NumberOfValues:= 1; Type_:= EncoderParameterValueTypeLong; Value:= @Piv // CompressionQuality setzen End; oldPiv:= Piv; // altes Pivot-Element merken If (GdipSaveImageToStream(Image, aSA, @aEncoder, @aEncParams) = Status.Ok) Then Begin If (aMS.Size > aSize) Then // Ergebnis ist zu groß Begin hQ:= Piv; // obere Grenze = aktueller Wert Piv:= Piv - ((hQ - lQ) Div 2); // neuen Wert berechnen End Else Begin // Ergebnis kleiner oder gleich lQ:= Piv; // untere Grenze = aktueller Wert Piv:= Piv + ((hQ - lQ) Div 2); // neuen Wert berechnen End; End Else Break; // bei Fehlern abbrechen Until (Piv = oldPiv); // noch näher geht es nicht aSA:= nil; // sicherheitshalber (http://www.delphipraxis.net/1384246-post23.html) If (MustFit) And // auf keinen Fall größer !!! (aMS.Size > aSize) Then // immer noch zu groß Result:= Pred(Piv) // => eine Nummer kleiner Else Result:= Piv; // aMS.Size = aSize => exakten Wert übergeben End; End; End;
Delphi-Quellcode:
?
Winapi.ActiveX.IStream
Dieser Stream kümmert sich um den ihm zugewiesenen
Delphi-Quellcode:
, so dass ich den nicht freigeben darf/muss. Aber trotz fehlender Freigabe von
TMemoryStream
Delphi-Quellcode:
bringt mir mein Programm bei
Winapi.ActiveX.IStream
Delphi-Quellcode:
am Ende keine Meldung.
ReportMemoryLeaksOnShutdown:= True;
Das wäre mir wichtig, weil mein Programm genauso lang läuft wieder Rechner und damit am Tag im Maximum mehrere hundert Bilder verarbeiten muss. Dass es am Ende des Programms automatisch aufgeräumt wird, reicht mir also leider nicht, wenn mir zwischendurch die Puste/der Speicher aus geht.
Delphi-Quellcode:
ruft auch nur
Winapi.GDIPOBJ.TGPImage.Free
Delphi-Quellcode:
auf...
GdipDisposeImage();
|
AW: JPEG CompressionQuality ermitteln
Zitat:
Der Aufruf ist einfach. bsp.
Delphi-Quellcode:
var
Result: GPStatus; .... Result := GdipSaveImageToFile(img, FullName, @encoderCLSID, nil); lblStatus.Caption := 'Status = ' + (cStatus[Result]); Zitat:
Ein IStream := nil sollte ausreichen. GdipDisposeImage gibt den Speicher frei vom geladenen GDI+ Image. Auch das ist vollkommen ausreichend. gruss |
AW: JPEG CompressionQuality ermitteln
Zitat:
Zitat:
:shock: Öh...das ist jetzt schon bissel fremdschämen mit euch. :oops: In meinen Beispielcode habe ich dreimal folgende Zeile verwendet:
Delphi-Quellcode:
OutputDebugString(PWideChar(Winapi.GDIPUTIL.GetStatus(Status)));
Ich will das Wichtigste nochmal herausstellen:
Delphi-Quellcode:
Winapi.GDIPUTIL.GetStatus(Status);
Ich will ja jetzt nicht kritisch gucken, aber die Unit Winapi.GDIPUTIL ist gerade mal knapp 389 Zeilen lang. Das hättest du durch leichtes durch scrollen aber auch selber finden können. |
AW: JPEG CompressionQuality ermitteln
Zitat:
Auch einfach mal in TStreamAdapter.Destroy einen Haltepunkt setzen und den Call Stack nachvollziehen. |
AW: JPEG CompressionQuality ermitteln
Zitat:
Und selbst ohne diese: JPEG betreibt sog. 4:2:2 Color Subsampling. Das heisst, das Bild wird zunächst von RGB zu YCrCb umgewandelt, und die C-Komponenten nachher in Breite und Höhe halbiert. (Das geht ganz gut, da das Menschliche Auge Farbunterschiede eh nicht so gut auflösen kann wie Helligkeitsunterschiede.) Der Standard lässt prinzipiell auch anderes Subsampling zu (4:4:4, 4:1:1, etc.), aber als Standardwert wird praktisch überall 4:2:2 verwendet. Zumindest dort, wo man es nicht genau wüsste dass man etwas anderes nutzt. D.h. Rundungsfehler treten eh schon bei der Farbraumumwandlung auf, und dann eben noch "Fehler" durch das vierteln der Farbinformation. Noch bevor überhaupt transformiert wird oder der "CompressionQuality"-Wert in den Ablauf einfließt. (Ja, ich habe schon mal einen JPEG Kompressor komplett zu Fuß gebaut.) |
AW: JPEG CompressionQuality ermitteln
Zitat:
gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:59 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