Entwickler-Ecke
Internet / Netzwerk - Eine URL aus einem Quelltext lesen / Image aus URL laden
Terra23 - So 08.07.12 18:04
Titel: Eine URL aus einem Quelltext lesen / Image aus URL laden
Hi!
Ich habe leider schon wieder ein Problem. Ich habe es bereits geschafft, mit Hilfe der Suche und einigen Threads, den Quellcode einer Seite (z.B.
dieser Seite [
http://yugioh.wikia.com/wiki/Tour_Guide_From_the_Underworld]) in ein Memo zu laden. Nun möchte ich aus dem Quelltext nur den String auslesen, in dem das Wort "300px-" vorkommt.
Hier mal für euch die Seite mit dem Quelltext zum Nachvollziehen:
Klick [
http://yugioh.wikia.com/wiki/Tour_Guide_From_the_Underworld]
Es sind auf diesen Wikia-Seiten immer so viele Images und Thumbnails verlinkt, deswegen muss es der folgende Teiltext sein, der "300px-" enthält.
Für diese Beispielseite wäre das diese URL:
http://images4.wikia.nocookie.net/__cb20120531135837/yugioh/images/thumb/9/96/TourGuideFromtheUnderworld-BP01-EN-R-1E.png/300px-TourGuideFromtheUnderworld-BP01-EN-R-1E.png
Leider komme ich mit Pos und Copy nicht wirklich weiter, da ich ja, wie gesagt, nur die URL haben will, die den String "300px-" enthält.
Und wenn ich diese URL dann extrahiert habe, wie kriege ich sie in ein Image geladen?
Kann mir jemand vielleicht ein wenig unter die Arme greifen (gern auch mit passenden Suchbegriffen, sofern diese nicht Pos und Copy sind). ;)
Gruß,
Terra
Moderiert von
Narses: Topic aus Sonstiges (Delphi) verschoben am So 08.07.2012 um 18:34
MDX - So 08.07.12 22:08
Entweder du suchst alle src="URL"-Tags aus dem Quelltext heraus und filterst dann die Adresse raus wo "300px" vorkommt oder wenn es auf jeder Seite der Fall ist, dann filtere von src=" nach " width="300", sollte mit Pos, PosEx und Copy möglich sein.
Aber:
Du kannst hier auch mit Pos und PosEx/Copy nach <link rel="image_src" href=" und " /> filtern und dann die Adresse von 100px mit StringReplace zu 300px umändern.
In ein Image bekommst du Sie geladen, wenn du sie herunterlädst, anders geht das IMHO nicht...
Terra23 - Mo 09.07.12 18:07
Sorry, aber ich bin dazu irgendwie zu dämlich. Ich kann nichtmal die URL des Bildes extrahieren... :(
bummi - Mo 09.07.12 18:10
Du hast die nötigen Suchbegriffe bereits selbst genannt und darum gebeten Dir damit nicht unter die Arme zu greifen.
Das sind Basics die man sich erarbeiten muss....
jaenicke - Mo 09.07.12 18:16
Poste doch einfach mal was du versucht hast. ;-)
Alternativ könntest du einen HTML Parser verwenden, sei es der von den JEDIs (ich glaube da gibt es einen, oder? :gruebel:), der des Internet Explorers oder ein anderer für Delphi.
MDX hat folgendes geschrieben : |
In ein Image bekommst du Sie geladen, wenn du sie herunterlädst, anders geht das IMHO nicht... |
Ja, richtig, wobei man da immer mit Streams arbeiten kann. Herunterladen in den Arbeitsspeicher reicht also. (Nur zur Klarstellung, dass keine Datei benötigt wird, wenn du von Herunterladen schreibst.)
Terra23 - Mo 09.07.12 18:26
Ja, das mache ich gerne.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
| procedure TForm1.Button2Click(Sender: TObject); var S: String; Stelle: Integer; Start: Integer; I: Integer; Stop: Integer; begin Stelle := Pos('300px-', Memo1.Text);
For I := Stelle DownTo 0 Do If Memo1.Text[I] = '"' Then Begin Start := I+1; Break; End;
For I := Start To Length(Memo1.Text) Do If Memo1.Text[I] = '"' Then Begin Stop := I; Break; End;
S := Copy(Memo1.Text, Start, (Stop-Start)); Label1.Caption := S; end; |
Ich weiß, dass die Variable "Start" richtig befüllt wird; das habe ich probiert. Inzwischen weiß ich auch, wo der Fehler lag... ;)
Gruß,
Terra
EDIT: QUELLCODE BEHOBEN!!!
Moderiert von
Narses: Beiträge zusammengefasstHab es jetzt raus. Es darf nicht heißen...
... sondern muss heißen...
Habe das jetzt mit verschiedenen URLs ausprobiert und es klappt jedes Mal, die URL des Bildes zu extrahieren.
Mal ne andere Frage: Geht das Laden des Quelltextes auch irgendwie schneller? Also im eigentlichen Programm will ich den Text nicht erst in ein Memo laden und dann extrahieren und dann das Bild anzeigen. Es soll für den User so aussehen, als wird nur das Bild gezeigt. Geht das vielleicht, wenn ich den Quelltext in eine Stringlist lade? Wenn ja, wie mache ich das?
haentschman - Mo 09.07.12 20:00
Hallo...
Zitat: |
Geht das vielleicht, wenn ich den Quelltext in eine Stringlist lade? Wenn ja, wie mache ich das? |
1. Stringlist erzeugen
2. Text in Stringlist (wie beim Memo)
3. damit arbeiten
4. Stringlist freigeben
8)
Terra23 - Mo 09.07.12 20:08
Wäre das so richtig?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure TForm1.Button1Click(Sender: TObject); begin Quellstream := TStringList.Create; Try Quellstream.Text := IdHTTP1.Get(Edit1.Text); MEINE ARBEIT MIT DEM STREAM Finally Quellstream.Free; End; end; |
Ich habe noch nie wirklich mit dem Try-Finally-End gearbeitet, daher nochmal meine Rückfrage.
Gruß,
Terra
PS: Kann mir jemand erläutern, was Try-Finally-End macht?
MDX - Mo 09.07.12 20:26
Delphi-Quelltext
1: 2: 3: 4: 5:
| try VersucheIrgendwas; finally HatFuntkioniertAlsoIrgendwasAnderesMachen; end; |
daneben gibts auch noch
Delphi-Quelltext
1: 2: 3: 4: 5:
| try VersucheIrgendwas; except HatNichtFunktioniertAlsoFehlerAbfangen; end; |
Achja, willst du mehr als eine Zeile Code nach
try,
finally oder
except ausführen musst du die Anweisungen alle in einen
begin,
end Block setzen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| try begin [...] end; finally begin [...] end; end; |
haentschman - Mo 09.07.12 21:07
Ergänzung:
egal was zwischen try und finally passiert... der finally Block wird immer ausgeführt. Mal angenommen du wölltest deine procedure mit exit verlassen... der finally Block wird dann nach dem exit abgearbeitet und erst dann die procedure verlassen.
Terra23 - Mo 09.07.12 21:13
Danke für eure Hilfe.
Kann mir noch kurz jemand von euch erklären, warum ich keine Bilder laden kann?
Erklärung:
In Label1.Caption steht die URL des Bildes, das ich laden will.
Hier mein aktueller Code:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| ImgStream := TMemoryStream.Create; Try Begin IdHTTP1.Get(Label1.Caption, ImgStream); ImgStream.Position := 0; JvImage1.Picture.Graphic.LoadFromStream(ImgStream); End; Finally; ImgStream.Free; End; |
Ich würde das Bild gern anzeigen lassen ohne es auf der Festplatte zwischenzuspeichern. Ich hatte zwar einen langen Code gefunden (
hier [
http://www.delphipraxis.net/299979-post.html]) aber das geht nur für JPGs. Wenn ich ein PNG laden will, führt dies eine Exception herbei (logisch).
Leider kann ich probieren, wie ich will ... ich finde nirgends die passende Antwort...
Narses - Mo 09.07.12 22:46
Moin!
MDX hat folgendes geschrieben : |
Achja, willst du mehr als eine Zeile Code nach try, finally oder except ausführen musst du die Anweisungen alle in einen begin, end Block setzen:
|
Für´s Protokoll: Das ist nicht korrekt, das begin/end ist hier überflüssig. Die try-Blöcke sind wie begin eine Klammer. :idea:
Delphi-Quelltext
1: 2: 3: 4: 5:
| try finally end; |
cu
Narses
bummi - Mo 09.07.12 22:52
Wenn Du ein PNG laden willst musst Du ein TPNGImage erzeugen, dieses aus dem Stream laden und dann Image.Picture.Graphic zuweisen (assign) und wieder freigeben.
Terra23 - Di 10.07.12 00:01
@bummi: Aber sowohl das normale Image als auch das Image aus den Jedi-Komponenten müssten doch eigentlich beide Dateiformate öffnen können. Wenn ich das über den Objektinspektor zuweise, klappt das ja auch. Ich bin verwirrt...
@narses: Danke für die Richtigstellung bezüglich Begin / End...
MDX - Di 10.07.12 00:21
Narses hat folgendes geschrieben : |
Moin!Für´s Protokoll: Das ist nicht korrekt, das begin/end ist hier überflüssig. Die try-Blöcke sind wie begin eine Klammer. :idea: |
Man lernt immer was dazu :D
Wieder bisschen Quellcode gespart :)
jaenicke - Di 10.07.12 02:38
Terra23 hat folgendes geschrieben : |
@bummi: Aber sowohl das normale Image als auch das Image aus den Jedi-Komponenten müssten doch eigentlich beide Dateiformate öffnen können. Wenn ich das über den Objektinspektor zuweise, klappt das ja auch. Ich bin verwirrt... |
Da gibt es aber die Dateierweiterung als zusätzliche Information. Deshalb kann beim Laden einer gespeicherten Datei automatisch die passende Klasse benutzt werden.
Wenn du aber ein Bild aus einem Stream lädst, gibt es diese Information nicht. Und deshalb musst du die korrekte Klasse selbst zur Erzeugung des Bildobjekts auswählen.
Terra23 - Di 10.07.12 14:17
Hi!
Ich habe jetzt mal die Dateiendung ausgelesen. Das klappt auch einwandfrei. Die Endung speichere ich in der String-Variablen namens "Art" zwischen.
Dann starte ich folgende Abfrage, die eigentlich auch korrekt sein müsste:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
| If Art = 'jpg' Then Begin Try ImgStream := TMemoryStream.Create; IdHTTP1.Get(Label1.Caption, ImgStream); ImgStream.Position := 0; JPGBild := TJPEGImage.Create; JPGBild.LoadFromStream(ImgStream); JvImage1.Picture.Assign(JPGBild); Finally JPGBild.Free; ImgStream.Free; End; End;
If Art = 'png' Then Begin Try ImgStream := TMemoryStream.Create; IdHTTP1.Get(Label1.Caption, ImgStream); ImgStream.Position := 0; PNGBild := TPNGImage.Create; PNGBild.LoadFromStream(ImgStream); JvImage1.Picture.Assign(PNGBild); Finally PNGBild.Free; ImgStream.Free; End; End; |
Wenn ich das Programm dann starten will, bekomme ich die Meldung "Undefinierter Bezeichner: 'TPNGImage'", was ich mir leider nicht erklären kann. Ich dachte, wenn ich die Variablen so definiere...
Delphi-Quelltext
1: 2:
| var JPGBild: TJPEGImage; PNGBild: TPNGImage; |
... dass es dann funktionieren würde.
Kann mich mal jemand bitte auf den richtigen Weg schubsen??
jaenicke - Di 10.07.12 15:50
Du hast die Unit für TPngImage nicht eingebunden, deshalb findet Delphi die Klasse nicht. Die Unit heißt in der Regel PngImage, sei es die von Delphi selbst oder eine fremde.
bummi - Di 10.07.12 15:58
häng mal in eine Deiner Units
Delphi-Quelltext
1: 2:
| initialization RegisterClasses([TIcon, TMetafile, TBitmap, TJPEGImage,TPngImage]); |
bzw. was Du davon brauchst.
jaenicke - Di 10.07.12 17:32
Das ist hier nicht das Problem, dann würde die Meldung lauten, dass die Klasse nicht gefunden wurde. Hier handelt es sich nicht um einen Laufzeitfehler sondern um einen Fehler beim Kompilieren. ;-)
bummi - Di 10.07.12 18:02
:bawling: wieder nicht richtig gelesen, sorry ...
Terra23 - Di 10.07.12 19:47
Ich habe mir jetzt mal die Unit "TPNGImage" ausm Netz runtergeladen und zu den anderen Units gepackt. Dann kam die Meldung "Datei nicht gefunden: 'ZLibEx.dcu'", obwohl diese Unit gar nicht unter "Uses" aufgeführt ist.
Muss ich jetzt tatsächlich ne andere Komponente (TPNGImage) suchen und installieren? Die TImage-Komponente aus Delphi 7 kennt doch PNG-Dateien. Warum ist das Ganze jetzt am Ende doch so kompliziert?
Klar, wenn man programmiert, darf man nicht erwarten, dass man alles serviert bekommt, aber wenn eine Komponente schon mit den Dateien umgehen kann, dürfte man dann nicht erwarten, dass die auch funktioniert?
Gruß,
Terra
jaenicke - Di 10.07.12 21:13
Ich habe keine Ahnung welche Komponente du da hast, aber die Standardkomponente, die jetzt mit Delphi mitgeliefert wird, funktioniert bei mir problemlos:
http://www.torry.net/authorsmore.php?id=6929
Terra23 - Di 10.07.12 21:21
Ich verfüge über die Standard-Komponente (TImage) und die aus den JediVCLs (TJvImage). Die Unit "TPNGImage" hatte ich mir "lose" also einzeln heruntergeladen ohne eine Komponente dazu.
Wie installiere ich denn die Komponente, die du verlinkt hast?
jaenicke - Di 10.07.12 21:23
Du entpackst das Zip-Archiv und fügst den Pfad dem Bibliothekspfad hinzu oder die Units dem Projekt.
Terra23 - Di 10.07.12 21:30
Das Programm beschwert sich immer noch über "TPNGImage".
Ich habe den Ordner in die Bibliothek aufgenommen und die Unit ins Programm.
Trotzdem beschwert es sich...
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:
| procedure TForm1.Button2Click(Sender: TObject); var ImgStream: TMemoryStream; Art: String; JPGBild: TJPEGImage; PNGBild: TPNGImage; -> hier beschwert sich das Programm (Undefinierter Bezeichner: TPNGImage) begin Diverse Aktionen, die für den Fehler irrelevant sind
Art := Copy(Label1.Caption, J, 3);
If Art = 'jpg' Then Begin Try ImgStream := TMemoryStream.Create; IdHTTP1.Get(Label1.Caption, ImgStream); ImgStream.Position := 0; JPGBild := TJPEGImage.Create; JPGBild.LoadFromStream(ImgStream); JvImage1.Picture.Assign(JPGBild); Finally JPGBild.Free; ImgStream.Free; End; End;
If Art = 'png' Then Begin Try ImgStream := TMemoryStream.Create; IdHTTP1.Get(Label1.Caption, ImgStream); ImgStream.Position := 0; PNGBild := TPNGImage.Create; PNGBild.LoadFromStream(ImgStream); JvImage1.Picture.Assign(PNGBild); Finally PNGBild.Free; ImgStream.Free; End; End; |
jaenicke, weißt du da Rat? Das übersteigt echt meine dürftigen Programmierkenntnisse...
jaenicke - Di 10.07.12 21:31
Du musst auch noch die Unit PngImage in die uses Klausel aufnehmen.
Terra23 - Di 10.07.12 21:33
Hab ich doch schon...
Delphi-Quelltext
1: 2: 3: 4: 5:
| uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, ShellApi, ExtCtrls, JPEG, JvImage, JvExExtCtrls, PNGImage, PNGExtra; |
jaenicke - Di 10.07.12 21:35
Ah, tut mir leid, ich habe kurz in die Unit hineingeschaut, die Klasse heißt TPngObject. :idea:
Terra23 - Di 10.07.12 21:42
Vielen Dank, es funktioniert.
Hier nochmal für alle, die zukünftig auf diesen Thread stoßen, die Zusammenfassung:
So lädt man ein JPG aus einem Stream in ein Image:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| procedure TForm1.Button2Click(Sender: TObject); var ImgStream: TMemoryStream; JPGBild: TJPEGImage; PNGBild: TPNGObject; begin Try ImgStream := TMemoryStream.Create; IdHTTP1.Get( ImgStream.Position := 0; JPGBild := TJPEGImage.Create; JPGBild.LoadFromStream(ImgStream); Image1.Picture.Assign(JPGBild); Finally JPGBild.Free; ImgStream.Free; End; End; |
So lädt man ein PNG aus einem Stream in ein Image:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure TForm1.Button2Click(Sender: TObject); var ImgStream: TMemoryStream; JPGBild: TJPEGImage; PNGBild: TPNGObject; begin Try ImgStream := TMemoryStream.Create; IdHTTP1.Get( ImgStream.Position := 0; PNGBild := TPNGObject.Create; PNGBild.LoadFromStream(ImgStream); JvImage1.Picture.Assign(PNGBild); Finally PNGBild.Free; ImgStream.Free; End; |
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!