Как получить картинку с URL и поместить ее во временной интервал с помощью TNetHTTPClient или TNetHTTPRequest?

#delphi #delphi-10.3-rio

#delphi #delphi-10.3-rio

Вопрос:

Как получить картинку с URL и поместить ее во временной интервал с помощью TNetHTTPClient или TNetHTTPRequest? Я новичок, и я использую Delphi-10.3-Rio.

Я написал простое тестовое приложение, но оно работает не так, как я ожидал.

Я использовал TNetHTTPClient и TNetHTTPRequest

   object NetHTTPClient: TNetHTTPClient
    Asynchronous = False
    ConnectionTimeout = 60000
    ResponseTimeout = 60000
    HandleRedirects = True
    AllowCookies = False
    UserAgent = 'Embarcadero URI Client/1.0'
    OnAuthEvent = NetHTTPClientAuthEvent
    Left = 7
    Top = 2
  end
  object NetHTTPRqstPicture: TNetHTTPRequest
    Asynchronous = False
    ConnectionTimeout = 60000
    ResponseTimeout = 60000
    MethodString = 'GET'
    Client = NetHTTPClient
    OnRequestCompleted = NetHTTPRqstPictureRequestCompleted
    Left = 103
    Top = 5
  end
  
 implementation
{$R *.dfm}
const
  cUrlPicture = 'http://192.168.1.3/local/fflprapp/tools.cgi?action=getImageamp;name=56/20200823171910_718702lp_PA088VI_463274.png';


procedure TForm1.btnGetPictClick(Sender: TObject);
begin {0}
  NetHTTPRqstPicture.Get(cUrlPicture);
end;


procedure TForm1.NetHTTPClientAuthEvent(const Sender: TObject; AnAuthTarget: TAuthTargetType;
  const ARealm, AURL: string; var AUserName, APassword: string; var AbortAuth: Boolean;
  var Persistence: TAuthPersistenceType);
begin {0}
  if AnAuthTarget = TAuthTargetType.Server then
     begin
       AUserName := 'root';
       APassword := 'ACCC8ED325EF';
     end;
end;


procedure TForm1.NetHTTPRqstPictureRequestCompleted(const Sender: TObject;
                                                  const AResponse: IHTTPResponse);
var
  strm   : TStream;
  pngImg : TPNGImage;
begin {0}
  strm   := TStream.Create;
  pngImg := TPNGImage.Create;

  strm   := AResponse.ContentStream;
  pngImg.LoadFromStream(strm);
  imgPict.Picture.Graphic := pngImg;

  FreeAndNil(pngImg);   // OK always
  FreeAndNil(strm);     // Here is something strange.
end;

end.
  

— вот как выполняется FreeAndNil (strm) —

1-й клик на btnGetPict — все в порядке

второй щелчок по btnGetPict — появляется сообщение: нарушение доступа по адресу 00407F74 в модуле ‘ProjGetPicture.exe ‘. Считывание адреса FFFFFFFD.

3-й щелчок по btnGetPict — все в порядке

4-й щелчок по btnGetPict — снова появляется то же сообщение и так далее.

Я не знаю, почему.

Если я удалю FreeAndNil(strm); , все будет в порядке, но это утечка памяти.

Если я изменю код, подобный этому

 var 
  strmG : TStream;

procedure TForm1.FormCreate(Sender: TObject);
begin
  strmG := TStream.Create;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FreeAndNil(strmG);
end;

// and use strmG instead strm in:
//  strmG := AResponse.ContentStream;
//  pngImg.LoadFromStream(strmG);
  

Все выполняется …. пока программа не закроется, когда появится то же самое сообщение.

Комментарии:

1. Вы уже прочитали документацию Embarcadero? Используя HTTP-клиент

Ответ №1:

Вставьте следующий код в обработчик нажатия btnGetPict кнопки

 procedure TForm1.btnGetPictClick(Sender: TObject);
var
  Memo : TMemoryStream;
  png : TPngImage;
begin
  Memo := TMemoryStream.Create;
  try
    NetHTTPClient1.Get(cUrlPicture, Memo); // cUrlPicture - this you constant with url from an picture
    Memo.Position := 0;
    png := TPngImage.Create;
    try
      png.LoadFromStream(Memo);
      Image1.Picture.Assign(png);
    finally
      png.Free;
    end;
  finally
    Memo.free;
  end;
end;
  

Кроме того, не забудьте добавить название библиотеки PNGImage в uses строку.
Если вы хотите загрузить файл jpeg, подключите библиотеку JPEG.
Вставьте приведенный ниже код.

 procedure TForm1.Button9Click(Sender: TObject);
var
   Memo : TMemoryStream;
   jpg:TJPEGImage;
begin
  Memo := TMemoryStream.Create;
  try
    NetHTTPClient1.Get(cUrlPicture, Memo);
    Memo.Position := 0;
    jpg := TJPEGImage.Create;
    try
      jpg.LoadFromStream(Memo);
      Image1.Picture.Assign(jpg);
    finally .
      jpg.Free;
    end;
  finally .
    Memo.free;
  end;
end;