1

I want to get an image from the web into stream (without saving) and displaying it on TImage. The following code produces an error:

response := TMemoryStream.Create;
try
   HttpGetBinary('http://www.example-url/example_image.jpg', response);
   Image.Picture.LoadFromStream(response);
finally
   response.Free;
end;

Project ------- raised exception class 'EReadError' with message: Stream read error

This is the function in Synapse library(in the picture.inc) that the error points to:

function TPicFileFormatsList.FindByStreamFormat(Stream: TStream): TGraphicClass;
var
  I: Integer;
begin
  for I := Count - 1 downto 0 do
  begin
    Result := GetFormats(I)^.GraphicClass;
    if Result.IsStreamFormatSupported(Stream) then   // <<<<<< this is the error line
      Exit;
  end;
  Result := nil;
end;
Thom A
  • 88,727
  • 11
  • 45
  • 75
  • Set the stream position to the beginning before you load it to the image. Like `response.Position := 0; Image.Picture.LoadFromStream...` – TLama Feb 19 '14 at 09:24
  • I tried that before posting here. The result is the same. –  Feb 19 '14 at 10:04

1 Answers1

1

You have to include the JPEGLib unit somewhere in your project, so that the JPEG graphic class gets registered.

uses
  JPEGLib, // to support JPEG
  PNGcomn, // to support PNG
  httpsend;

response := TMemoryStream.Create;
try
   if HttpGetBinary('http://www.example-url/example_image.jpg', response) then
   begin
     response.Seek( 0, soFromBeginning );
     Image.Picture.LoadFromStream( response );
   end;
finally
   response.Free;
end;
Sir Rufo
  • 18,395
  • 2
  • 39
  • 73
  • 1
    I don't have FPC by hand but I think that if the `TImage.Picture` has the `LoadFromStream` method, there should be a chance to load it directly from stream. It's the `TPicFileFormatsList.FindByStreamFormat` method that fails, so couldn't the problem be (except resetting the stream position) in missing unit which registers the JPEG format ? It's just a wild guess... – TLama Feb 19 '14 at 10:57
  • 1
    +1 @TLama You are totally right ... FPC differs in that point from Delphi :o) – Sir Rufo Feb 19 '14 at 11:12
  • This works. The JPEGLib and PNGcomn are not necessary, the debugger gives the message that they are not being used in my unit. I should have mentioned that I use FPC and not Delphi :). Thank you. –  Feb 19 '14 at 12:03
  • Ok, so the only problem was that you didn't reset the stream position ? You've told me that you tried that and you got the same result... – TLama Feb 19 '14 at 12:31
  • This: response.Position := 0 did not work. This: response.Seek(0, soFromBeginning) worked. Dunno... I admit I am not really familiar with stream. –  Feb 19 '14 at 13:33
  • Ah, now I see it. They even warn that the [`TStream.Position`](http://www.freepascal.org/docs-html/rtl/classes/tstream.position.html) is not supported by all descendants. And `TMemoryStream` is one of those. From `TMemoryStream` you can [`only read`](https://github.com/graemeg/freepascal/blob/master/rtl/objpas/classes/classesh.inc#L941) the stream position, not set. Weird design... – TLama Feb 19 '14 at 13:50
  • @TLama The setter `SetPosition` is definied in `TStream` and calls `Seek( Pos, soFromBeginning );` by default. So this should work ... and just verified by a test `respond.Position := 0;` does the job as well – Sir Rufo Feb 19 '14 at 15:42