2009-08-04 10 views

Antwort

28

Mit Hilfe von TMemoryStream und Indy-Komponente.

uses 
    GIFImg; 

procedure TForm1.btn1Click(Sender: TObject); 
var 
    MS : TMemoryStream; 
    GIf: TGIFImage; 
begin 
    MS := TMemoryStream.Create; 
    GIf := TGIFImage.Create; 
    try 
    IdHTTP1.get('http://www.google.com/intl/en_ALL/images/logo.gif',MS); 
    Ms.Seek(0,soFromBeginning);  
    Gif.LoadFromStream(MS); 
    img1.Picture.Assign(GIF); 

    finally 
    FreeAndNil(GIF); 
    FreeAndNil(MS); 
    end; 
end; 
+0

Sie könnten sogar ohne die TGifImage und tun img1.Picture.LoadFromStream (MS); –

+1

** Warnung: ** Wenn es eine Ausnahme in 'TIdHTTP.Get' gibt, wird dieser Code die nicht initialisierte' GIF'-Variable freigeben. Verwenden Sie keine Variablen in einem "finally" -Abschnitt, wenn Sie sie nicht initialisiert haben * bevor * den entsprechenden Abschnitt "try" eingeben. –

+1

Nein, Lars, das geht nicht. 'TPicture.LoadFromStream' ist geschützt, nicht öffentlich. Außerdem ruft es nur 'Bitmap.LoadFromStream' auf, sodass es sowieso nicht weiß, wie GIF-Daten geladen werden. –

3

Code arbeitete auch für JPEG.

+0

Hinzufügen "verwendet JPEG", ich habe mein Beispiel mit GIF-Einheit gemacht, müssen Sie Jpeg eins verwenden. –

+0

Grüner, Sie haben nicht die richtige Get-Methode verwendet. Wenn Sie möchten, dass ein Stream gefüllt wird, müssen Sie daran denken, den Stream als Parameter zu übergeben. Die Ein-Argument-Version von 'Get' gibt den Inhalt der Ressource als String im Rückgabewert der Funktion zurück. –

+0

Ja Rob, Ich habe meinen Fehler gefunden. Danke nochmal an alle für Hilfe. – Greener

0

Für this project habe ich Indy-Komponenten (wie erste Antwort) verwendet, aber den Code in einem Thread verwenden. Nützlich zum Herunterladen großer Bilder oder einer großen Anzahl von Bildern. Sie können die vollständige Erklärung des Projekts in Verbindung sehen (ist in Spanisch, aber Sie können automatische Übersetzung verwenden).

In diesem Fall verwende ich es für den Download aller Bilder from this page.
Hier verwende ich eine andere Komponente IdSSL:TIdSSLIOHandlerSocket, notwendig für den Zugriff auf eine https URL; Wenn Sie auf eine http zugreifen müssen, brauchen Sie es nicht.

Der Code von TDownImageThread wird (hinzugefügt Englisch Kommentare):

{: Clase para descargar una imagen y almacenarla en disco.} 
    {: Class to download image and save to disk} 
    TDownImageThread = class(TThread) 
    private 
    FURLImage: string; 
    FPathImage: string; 
    FFileNameImage: string; 
    // Internas 
    ImageName: string; 
    PathURL: string; 
    // Componente 
    idH:TidHTTP; 
    IdSSL:TIdSSLIOHandlerSocket; 
    public 
    // redefinir métodos // redefine methods 
    constructor Create(AURL:string; AOutPathImages:string); 
    destructor Destroy; override; 
    procedure Execute; override; 
    {: URL de la imagen a descargar. // URL to download} 
    property URLImage:string read FURLImage write FURLImage; 
    {: Path de disco local donde voy a almacenar la imagen.} 
    {: Local path to save the images} 
    property PathImage:string read FPathImage; 
    {: Nombre completa (path+Nombre) de la imagen almacenada en disco local} 
    {: complete name (path+name) of loval image} 
    property FileNameImage:string read FFileNameImage; 
    end; 



.... 


{ TDownImageThread } 
constructor TDownImageThread.Create(AURL, AOutPathImages: string); 
var 
    URI:TidURI; 
begin 

    // crear el thread suspendido // Create suspended thread 
    inherited Create(True); 
    // Parámetros: URL y dir de salida // Params URL and output dir. 
    Self.FURLImage := AURL; 
    Self.FPathImage := AOutPathImages; 
    // Crear con URL // create with URL 
    URI := TidURI.Create(AURL); 
    try 
    ImageName := URI.Document; 
    PathURL := URI.Path; 
    finally 
    URI.Free; 
    end; 
end; 

destructor TDownImageThread.Destroy; 
begin 
    inherited; 
end; 

//: recupara la imagen y la guarda en disco 
procedure TDownImageThread.Execute(); 
var 
    Stream:TFileStream; 
    IdH:TidHTTP; 
    IdSSL:TIdSSLIOHandlerSocket; 
    path:string; 
    dir:string; 
begin 
    // Directorio de salida // output directory 
    dir := AnsiReplaceText(PathURL, '/', STR_EMPTY); 
    // Nombre vacío // empty name 
    if (ImageName = STR_EMPTY) then begin 
    Exit; 
    end; 
    // Path de salida  // output path 
    path := IncludeTrailingBackslash(IncludeTrailingBackslash(PathImage) + 
      dir) + ImageName; 
    // Crearlo por si no existe // create it if not exist 
    ForceDirectories(ExtractFilePath(path)); 
    try 
    // Stream para la imagen // Stream for the image 
    Stream := TFileStream.Create(path, fmCreate); 
    try 
     // Crear componente para acceder /// Create the component in runtime 
     IdH := TidHttp.Create(nil); 
     IdH.ReadTimeout := 30000; 
     // necessary to use HTTPS 
     IdSSL := TIdSSLIOHandlerSocket.Create(nil); 
     IdH.IOHandler := IdSSL; 
     IdSSL.SSLOptions.Method := sslvTLSv1; 
     IdSSL.SSLOptions.Mode := sslmUnassigned; 
     idH.HandleRedirects := True; 
     IdH.RedirectMaximum := 3; 

     // proteccion 
     try 
     // Obtener la imagen // get the image 
     IdH.Get(Trim(FURLImage), Stream); 
     except 
     // Error al descargar la imagen 
     //.. Volcarlo al log 
     end; 
    finally 
     // Liberar // Free component 
     idH.Free; 
     // IdSSL.Free; 
     Stream.Free; 
    end; 
    // Path de salida  // output path 
    FFileNameImage := path; 
    except 
    // error al crear el fichero // error on create file 
    //... Log 
    end; 
end; 

es zu benutzen, der Anruf ist ähnlich wie diese:

// Crear un nuevo thread para descargar la imagen 
// Create a new thread LINK+output path 
th := TDownImageThread.Create(mmLinks.Lines[i], pathImages); 
// Procedimiento de retorno al finalizar 
// procedure to return on thread finalize 
th.OnTerminate := TerminateThread; 
th.Resume; 
0

Bessere Nutzung dieser Funktion zum Herunterladen:

function DownloadFile(Url, DestFile: string): Boolean; 
begin 
    try 
    Result := UrlDownloadToFile(nil, PChar(Url), PChar(DestFile), 0, nil) = 0; 
    except 
    Result := False; 
    end; 
end;