Question

I have a TImage which displays a JPG image from a folder. Each JPG image name is numerical (e.g. 5968.jpg) If the JPG image does not exist, i currently load a template JPG.

However, I would like to check the internet for it after checking the local folder

I know the URL and I just concatenate the image number and extension to it (e.g. 'http://www.myurl.com/images/' + Tags.Names[Index] + '.jpg')

I would like to download this image if it does not exist locally.

if FileExists(TagPath + Tags.Names[Index] + '.jpg') then
    imgTag.Picture.LoadFromFile(TagPath + Tags.Names[Index] + '.jpg')
   else
    imgTag.Picture.LoadFromFile(ExtractFilePath(Application.ExeName) + 'Template.jpg');

How would I download the image (use idHTTP ?) to the TImage (imgTag). How would I handle any exception.

The flow should be as such, without any errors.

if FileExists locally, load image
else
 if fileEists on the internet load Image
  else
   Load the template

thanks

Was it helpful?

Solution

You can use Indy's TIdHTTP component, eg:

uses
  ..., IdHTTP;

var
  FileName: string;
  Strm: TMemoryStream;
begin
  FileName := TagPath + Tags.Names[Index] + '.jpg';
  if not FileExists(FileName) then
  begin
    try
      Strm := TMemoryStream.Create;
      try
        HTTP := TIdHTTP.Create(nil);
        try
          HTTP.Get('http://www.myurl.com/images/' + Tags.Names[Index] + '.jpg', Strm);
        finally
          HTTP.Free;
        end;
        Strm.Position := 0;
        Strm.SaveToFile(FileName);
      finally
        Strm.Free;
      end;
    except
      FileName := ExtractFilePath(Application.ExeName) + 'Template.jpg';
    end;
  end;
  imgTag.Picture.LoadFromFile(FileName);
end;

OTHER TIPS

You can resort to the standard TDownloadURL action in order to make a simple download of the internet and add this to your logic, something in the lines of:

uses
  ExtActns;

function TMyForm.TryDownloadFile(const AURL, AFileName: string): Boolean;
begin
  Result := False;
  with TDownLoadURL.Create(nil) do
  try
    URL := AURL;
    Filename := AFileName;
    try
      ExecuteTarget(nil);
      Result := True;
    except
      ; //please, improve this handling specific exceptions
    end;
  finally
    Free;
  end;
end;

procedure TMyForm.LoadFile(Index: Integer);
var
  FileName: string;
begin
  FileName := TagPath + Tags.Names[Index] + '.jpg';
  if not FileExists(FileName) then
    if not TryDownlaodFile('http://www.myurl.com/images/' + Tags.Names[Index] + '.jpg', 
      FileName) then
      FileName := ExtractFilePath(Application.ExeName) + 'Template.jpg';
  imgTag.Picture.LoadFromFile(FileName);
end;

The shown code sin is that I eat any exception in the exception handler, and that's a bad practice, but I wrote this answer directly in this window and have no time to check which particular exceptions can be raised in the different failure scenarios with the action. It would be nice if you make that improvements and come back and contribute it to the community.

i ussually use this code to check is file exists on webserver

function CheckUrl(url: string): boolean;
var
  hSession, hfile, hRequest: hInternet;
  dwindex,dwcodelen: DWord;
  dwcode:array[1..20] of Char;
  res: PChar;
begin
  if Pos('http://', LowerCase(url)) = 0 then
    url := 'http://' + url;
  Result := False;
  hSession := InternetOpen('InetURL:/1.0', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if Assigned(hsession) then
  begin
    hfile := InternetOpenUrl(hsession, PChar(url), nil, 0, INTERNET_FLAG_RELOAD, 0);
    dwIndex := 0;
    dwCodeLen := 10;
    HttpQueryInfo(hfile, HTTP_QUERY_STATUS_CODE, @dwCode, dwCodeLen, dwIndex);
    res := PChar(@dwCode);
    Result := (res = '200') or (res = '302');
    if Assigned(hFile) then
      InternetCloseHandle(hFile);
    InternetCloseHandle(hSession);
  end;
end;

and to download file you can use Jachguate answer

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top