2009-08-04 5 views

Trả lời

28

Với sự trợ giúp của TMemoryStream và Indy component.

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

Bạn thậm chí có thể làm mà không có TGifImage và làm img1.Picture.LoadFromStream (MS); –

+1

** Cảnh báo: ** Nếu có một ngoại lệ trong 'TIdHTTP.Get', thì mã này sẽ giải phóng biến' GIF' chưa được khởi tạo. Không sử dụng các biến trong phần "cuối cùng" nếu bạn chưa khởi tạo chúng * trước khi * nhập phần "thử" tương ứng. –

+1

Không, Lars, bạn không thể làm điều đó. 'TPicture.LoadFromStream' được bảo vệ, không công khai. Bên cạnh đó, nó chỉ gọi 'Bitmap.LoadFromStream', do đó, nó sẽ không biết làm thế nào để tải dữ liệu GIF anyway. –

3

Mã cũng hoạt động cho JPEG.

+0

Thêm "sử dụng JPEG", tôi đã làm ví dụ của tôi với đơn vị GIF, bạn cần sử dụng Jpeg. –

+0

Xanh hơn, bạn chưa sử dụng đúng phương thức 'Get'. Nếu bạn muốn nó lấp đầy luồng, bạn cần phải nhớ truyền luồng dưới dạng tham số. Phiên bản một đối số của 'Get' trả về nội dung tài nguyên dưới dạng chuỗi trong giá trị trả về của hàm. –

+0

Có Rob, Tôi đã tìm thấy sai lầm của mình. Cảm ơn mọi người đã giúp đỡ. – Greener

0

Đối với this project Tôi đã sử dụng các thành phần Indy (như phản hồi đầu tiên), nhưng sử dụng mã bên trong một chuỗi. Dễ sử dụng để tải xuống các hình ảnh lớn hoặc một số lượng lớn hình ảnh. Bạn có thể xem giải thích đầy đủ về dự án trong liên kết (bằng tiếng Tây Ban Nha nhưng bạn có thể sử dụng bản dịch tự động).

Trong trường hợp này, tôi sử dụng nó để tải xuống tất cả hình ảnh from this page.
Ở đây tôi sử dụng một thành phần khác IdSSL:TIdSSLIOHandlerSocket, cần thiết để truy cập vào địa chỉ https url; Nếu bạn phải truy cập vào http, không cần đến nó.

(bình luận tiếng anh thêm)

Mã của TDownImageThread là:

{: 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; 

Để sử dụng nó, gọi là tương tự như sau:

// 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

sử dụng tốt hơn chức năng này để tải về:

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