![]() |
httpCLI: Download PNG funktioniert nicht, JPG geht
Hallo zusammen,
ich nutze schon länger einen einfache Code, der mir ein JPG holt und in eine TJPegImage mit LoadFromStream einfügt. Jetzt gibt es aber auch PNG-Bilder und das Einfügen in ein TPNGObject geht nicht. Die heruntergeladene Grafik ist definitiv eine PNG. Ich habe das gleiche mal mit Indy (IdHttp) getestet, da geht es. Ich muss im dieser Applikation aber die httpCLI-Komponente von Overbyte verwenden, daher ist die einfachste Lösung (verwende Indy) leider nicht möglich :(. Zusammenfassend: - mit Indy kann ich JPG und PNG herunterladen und den geladenen MemoryStream mit LoadFromStream in einem TJPEGImage bzw. einem TPNGObject einfügen :-D. - mit httpCLI kann ich das nur mit einem JPG, beim selben PNG das mit Indy funktioniert, wird mir im Code mit httpCLI ein ungültiger Header gemeldet :?. Hier der Code mit httpCLI: (einige unnötige Zeilen (Protokollierung) rausgeworfen, so ist es übersichtlicher.)
Delphi-Quellcode:
Zum Vergleich der Code mit Indy, da geht's:
Procedure GetPicture(ImageURL:String; var image:TJPEGImage);
Var Data: TMemoryStream; png: TPNGObject; tbmp: TBitMap; SslHttpCli1: TSslHttpCli; SslContext1: TSslContext; begin if (ImageURL>'') then begin Data := TMemoryStream.Create; try SslHttpCli1 := TSslHttpCli.Create(nil); SslContext1 := TSslContext.Create(nil); SslContext1.SslCipherList := 'ALL:!ADH:RC4+RSA:+SSLv2:@STRENGTH'; SslContext1.SslECDHMethod := sslECDHNone; SslContext1.SslVerifyPeerModes := [SslVerifyMode_PEER]; SslContext1.SslVersionMethod := sslBestVer; SslHttpCli1.SslContext := SslContext1; SslHttpCli1.URL := ImageURL; SslHttpCli1.RcvdStream := Data; try SslHttpCli1.Get; Data.Position := 0; //stream-position auf 0 setzen if TypeToStr(GetImageType(Data)) ='Image/JPEG' then Image.LoadFromStream(Data) // <--- das funktioniert !!! else if TypeToStr(GetImageType(Data)) ='Image/PNG' then begin png := TPNGObject.Create; tbmp:=TBitMap.Create; try png.LoadFromStream(Data); // <--- das funktioniert nicht, Fehlermeldung wegen ungültigem Header, selbe URL mit idHTTP (Indy) funktioniert. tbmp.Assign(png); image.Assign(tbmp); finally tbmp.Free; png.Free; end; end else showMessage('unbekannter Grafiktyp'); except on E: Exception do begin MessageDlg(E.Message, mtWarning, [mbOK], 0); end; end; finally Data.Free; SslHttpCli1.Free; SslContext1.Free; end; end; end;
Delphi-Quellcode:
Hat jemand einen Tipp für mich, wo ich ansetzen kann, um die Ursache zu finden?
Procedure GetPicture(ImageURL:String; var image:TJPEGImage);
var MS: TMemoryStream; idHttp1:TIdHttp; sslIOHandler : TIdSSLIOHandlerSocketOpenSSL; png: TPNGObject; tbmp: TBitMap; begin // Bild laden if ImageURL <> '' then begin MS := TMemoryStream.Create; IdHttp1 := TIdHTTP.Create(nil); if (AnsiUpperCase(copy(ImageURL, 1, 5)) = 'HTTPS') then begin sslIOHandler := frmInternetLookup.IdSSLIOHandlerSocketOpenSSL1; //TIdSSLIOHandlerSocketOpenSSL.Create(nil); sslIOHandler.PassThrough:=true; sslIOHandler.OnStatusInfo := frmInternetLookup.IdSSLIOHandlerSocketOpenSSL1.OnStatusInfo; IdHttp1.IOHandler := sslIOHandler; end; SetProxyData(IdHttp1); try IdHttp1.Get(ImageURL, MS); MS.Position := 0; if IdHTTP1.Response.ContentType = 'image/jpeg' then Image.LoadFromStream(MS) // <--- hier funktioniert sowohl das... else if IdHTTP1.Response.ContentType = 'image/png' then begin png := TPNGObject.Create; tbmp := TBitmap.Create; try png.LoadFromStream(MS); // <--- und das geht hier auch, nur bei httpCLI nicht... tbmp.Assign(png); image.Assign(tbmp); finally tbmp.Free; png.Free; end; end; except // entfernt end; MS.Free; end; end; .. Ergänzung: das Image liegt unter ![]() Danke und Gruß, Siggi |
AW: httpCLI: Download PNG funktioniert nicht, JPG geht
Was macht GetImageType? Wird dadrin eventuell die Position im Stream verändert?
Dann eventuell
Delphi-Quellcode:
Ansonsten testweise:
try
/////////////// Data.Position := 0; // <-- an den Anfang des Streams gehen. /////////////// png.LoadFromStream(Data); // <--- das funktioniert nicht, Fehlermeldung wegen ungültigem Header, selbe URL mit idHTTP (Indy) funktioniert.
Delphi-Quellcode:
Geht das?
Data.SaveToFile('xxx.png');
png.LoadFromFile('xxx.png'); Wenn nein, mit 'nem anderen Programm prüfen, ob der Stream eine vernünftige PNG-Datei enthält. |
AW: httpCLI: Download PNG funktioniert nicht, JPG geht
hmmm, saveToFile / LoadFromFile geht. Dann sollte der selbe Stream ohne "Zwischenspeichern" aber doch auch gleich funktionieren :?: :? :roll:.
Rätselhaft, aber so habe ich zumindest einen Workaround.
Delphi-Quellcode:
erst mal danke, mal sehen ob ich noch rausfinde, warum das nicht auch ohne Umweg über die Datei geht.
Data.SaveToFile(getTempDir+'\Image.png');
png.LoadFromFile(getTempDir+'\Image.png'); Gruß, Siggi |
AW: httpCLI: Download PNG funktioniert nicht, JPG geht
Setz' bitte mal 'nen Breakpoint vor
Delphi-Quellcode:
und debugge Dich da rein. Die ersten acht Byte des Streams müssten
png.LoadFromStream(Data)
Delphi-Quellcode:
bzw.
#137 #80 #78 #71 #13 #10 #26 #10
Delphi-Quellcode:
sein oder die ersten vier als ASCII
$89 $50 $E4 $47 $0D $0A $1A $0A
Delphi-Quellcode:
und Position von Data muss 0 sein.
‰PNG
|
AW: httpCLI: Download PNG funktioniert nicht, JPG geht
sowohl der MemoryStream aus IdHTTP (Indy) als auch aus httpCLI (Overbyte) fangen so an:
Zitat:
Ich suche nicht weiter und mache das jetzt unschön aber funktionierend so:
Delphi-Quellcode:
und das steckt nochmals in einem try..except..end für den Fall, dass auch das schief geht und zumindest eine verständliche Fehlermeldung und ein Logeintrag erfolgen.
try
png.LoadFromStream(Data); except // wenn es nicht geht -> Umweg über Datei Data.SaveToFile(getTempDir+'\Image.png'); png.LoadFromFile(getTempDir+'\Image.png'); end; Viele Grüße, Siggi |
AW: httpCLI: Download PNG funktioniert nicht, JPG geht
Es gibt im englischen Teil der DP jetzt auch ein ICS Forum!
Vielleicht mal da nachfragen? |
AW: httpCLI: Download PNG funktioniert nicht, JPG geht
So lädst du ein PNG in einen Stream und von dort direkt in ein TPngImage.
TImage, THttpCli, TButton auf Form ziehen, uses mit pngimage ergänzen.
Delphi-Quellcode:
uses …. pngimage; function TForm80.getpngimage( quelle : string; png : TPngImage ):boolean; var tm : TMemoryStream; begin tm := TMemoryStream.Create; try httpcli1.RcvdStream := tm; httpcli1.URL := quelle; httpCli1.Get; tm.Position := 0; png.LoadFromStream( tm ); finally tm.free; end; end; Aufruf:
Delphi-Quellcode:
Ich habe gerade gemerkt, dass den Funktionen noch kein Result zugewiesen wird ;-). Sollte man noch tun.procedure TForm80.Button1Click(Sender: TObject); var quelle : string; hpng : TPngImage; begin quelle := 'http://pngimg.com/uploads/olives/olives_PNG14287.png'; hpng := TPngImage.Create; try getpngimage( quelle, hpng ); image1.Picture.Assign( hpng ); finally hpng.Free; end; end; Natürlich solltest du den Code erweitern - ist nur eine kurze Demo, welche funktioniert. [Wenn du eine Anwendung schreibst, welche immer wieder die gleichen URLs auf neue Version abfragt, dann lohnt es sich die Bilder (etc.) zu "cachen". Beim Abrufen der Daten vom Server kannst du dann via HeaderData prüfen, ob die Datei bereits lokal vorhanden ist und falls Ja, den Download abbrechen. Und wenn du Datei speichern willst:
Delphi-Quellcode:
function TForm80.geturl( quelle, ziel : string ):boolean;
var tf : TFileStream; begin tf := TFileStream.Create( ziel, fmCreate or fmOpenWrite ); try httpcli1.RcvdStream := tf; httpcli1.URL := quelle; httpCli1.Get; finally tf.free; end; end; |
AW: httpCLI: Download PNG funktioniert nicht, JPG geht
Ich habe auch die Vermutung, dass GetImageType etwas am Position des Streams verändert. Daher mache anstatt den 2 GetImageType Aufrufen nur einen wie folgt:
Code:
s := TypeToStr(GetImageType(Data)); if s = 'Image/JPEG' then Image.LoadFromStream(Data) // <--- das funktioniert !!! else if s = 'Image/PNG' then ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:10 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