17

I am looking for any code samples that show how to pull images from URL into Delphi TImage component.

Thanks,

Fabrizio
  • 7,603
  • 6
  • 44
  • 104
Greener
  • 477
  • 3
  • 9
  • 22

4 Answers4

34

With help of TMemoryStream and 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;
Fabrizio
  • 7,603
  • 6
  • 44
  • 104
Mohammed Nasman
  • 10,992
  • 7
  • 43
  • 68
  • You could even do without the TGifImage and do img1.Picture.LoadFromStream(MS); – Lars Truijens Aug 04 '09 at 14:03
  • 2
    **Warning:** If there is an exception in `TIdHTTP.Get`, then this code will free the uninitialized `GIF` variable. Do not use variables in a "finally" section if you haven't initialized them *before* entering the corresponding "try" section. – Rob Kennedy Aug 04 '09 at 14:04
  • 1
    No, Lars, you can't do that. `TPicture.LoadFromStream` is protected, not public. Besides, it just calls `Bitmap.LoadFromStream`, so it won't know how to load GIF data anyway. – Rob Kennedy Aug 04 '09 at 14:07
  • Thanks Rob, I did it in hurry specially the Gif side, I was looking to store the Stream directly into TImage but recognized it's not available. – Mohammed Nasman Aug 04 '09 at 14:13
  • Mohammed, The code works with GIF as you posted. I appreciated it. I was not able to use with JPEGs (I use D2009). I posted my code above. any suggestions would be appreciated Thanks, Chris aka Greener – Greener Aug 04 '09 at 15:23
  • I have just found my typo in the code. It worked with JPEG. I do not get why negative votes. THANKS AGAIN !!! – Greener Aug 04 '09 at 15:30
4

Code Worked for JPEG as well.

Greener
  • 477
  • 3
  • 9
  • 22
  • Add "uses JPEG ", I made my example with GIF unit, you need to use Jpeg one. – Mohammed Nasman Aug 04 '09 at 15:22
  • Greener, you have not used the right `Get` method. If you want it to fill a stream, you need to remember to pass the stream as a parameter. The one-argument version of `Get` returns the resource contents as a string in the function's return value. – Rob Kennedy Aug 04 '09 at 15:45
  • Yes Rob, I found my mistake. Thanks again to everyone for help. – Greener Aug 04 '09 at 17:16
  • You should edit your first post or add comments to relevant answers instead. – curious slab Aug 05 '09 at 10:56
2

For this project I used Indy components (like first response), but using the code inside a thread. Usefull for download big images or a big number of images. You can see the complete explaination of project in link (is in spanish but you can use automatic translation).

In this case I use it for download all images from this page.
Here I use another component IdSSL:TIdSSLIOHandlerSocket, necessary for access to an https url; If you must access to an http, don't need it.

The code of TDownImageThread is (added english comments):

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

To use it, the call is similar to this:

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

Better use this Function for downloading:

function DownloadFile(Url, DestFile: string): Boolean;
begin
   try
     Result := UrlDownloadToFile(nil, PChar(Url), PChar(DestFile), 0, nil) = 0;
   except
     Result := False;
   end;
end;
Ingo
  • 5,239
  • 1
  • 30
  • 24