Recent

Author Topic: Array of TMemorystream  (Read 6854 times)

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Array of TMemorystream
« Reply #15 on: November 20, 2017, 09:52:57 pm »
Not sure what you mean.
That is just code to ensure he doesn't cache .pngs or whatever.
"extension" is part of the string stored in a specific row index (grid.Cells[6,i]).

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Array of TMemorystream
« Reply #16 on: November 20, 2017, 09:57:08 pm »
"extension" is part of the string stored in a specific row index (grid.Cells[6,i]).
Yes, i understand that part. so..

Quote
That is just code to ensure he doesn't cache .pngs or whatever.
imho means that there is only images cached when the name has extension jpg or jpeg, ergo there is no relation between the cached array and the number of rows in a grid. That is unless i misunderstood TS wishes or your provided approach.

To put it into other words the i iterator for the grid should not be used for the cached array... that is, unless you wish to maintain the 1 on 1 relation between grid filenames and cached array (but that was not indicated by TS' original code).
« Last Edit: November 20, 2017, 10:01:53 pm by molly »

wp

  • Hero Member
  • *****
  • Posts: 11858
Re: Array of TMemorystream
« Reply #17 on: November 20, 2017, 10:47:57 pm »
It was not that easy... meanwhile i have this witch works with the current pictures in my loop. But when I call the first picture at the end with the same command LoadFromStream(cache[1]) my app crashes...

Code: Pascal  [Select][+][-]
  1. begin
  2.   for i := 1 to StringGrid1.Rowcount -1 do begin   //reads 3 Files
  3.     extension := ExtractFileExt(StringGrid1.Cells[6,i]);
  4.     if ((Uppercase(extension) = '.JPG') or (Uppercase(extension) = '.JPEG')) then begin
  5.       try
  6.        setlength(cache,i+1);
  7.        mmm := Tmemorystream.create;
  8.         mmm.LoadFromFile(StringGrid1.Cells[6,i]);
  9.        cache[i] := mmm;
  10.        Image1.Picture.LoadFromStream(Cache[i]);   //displays current file correct
  11.       finally
  12.         mmm.free;
  13.       end;
  14.        showmessage(inttostr(i));
  15.     end;
  16.  end;
  17.  showmessage(inttostr(i));
  18.  Image1.Picture.LoadFromStream(Cache[1]);  //should display first file but crashes ?????
  19. end;    

Another idea: After loading a file into a stream the stream position is at the end. If you want to read the same stream later again (your last line) then you must rewind the stream back to its beginning before reading:

Code: Pascal  [Select][+][-]
  1.  [...]
  2.  showmessage(inttostr(i));
  3.  Cache[1].Position := 0;                     // rewind the stream
  4.  Image1.Picture.LoadFromStream(Cache[1]);
  5. end;    

ratmalwer

  • Jr. Member
  • **
  • Posts: 57
Re: Array of TMemorystream
« Reply #18 on: November 20, 2017, 10:50:26 pm »
Hi molly and howard
I read your discusion. You are right: I was assuming the value is stored in the array when freeing the stream.
I appoligize that I did not supply the correct Errormessage... sometimes difficult, I have to translate and do not know exactly what ist is in english.

So I adjusted the code it looks almost like the one you provided but kept the stringlist as my source. Ther are only JPG in this.

The error trying to display a picure at the end (or in other Procedure) is: Exception-Class EInvalidGraphic   unknown Pictureformat In File include\picture.inc line 5.7.8

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button4Click(Sender: TObject);
  2. var i: integer;
  3.   filename: string;
  4.   ImageCount : Integer;
  5. begin
  6.   ImageCount := StringGrid1.Rowcount -1;
  7.   SetLength(cache,ImageCount);
  8.   for i := 1 to ImageCount do begin   // 1 - 3  all .jpg
  9.        Filename := StringGrid1.Cells[6,i];
  10.        cache[i-1] := TMemorystream.create;
  11.        cache[i-1].LoadFromFile(Filename);
  12.        Image1.Picture.LoadFromStream(Cache[i-1]);   //displays current file correct
  13.        showmessage(inttostr(i));
  14.   end;
  15.   Image1.Picture.LoadFromStream(Cache[1]);  //should display first file but crashes with Exception-Class EInvalidGraphic   unknown Pictureformat In File include\picture.inc
  16. end;
« Last Edit: November 20, 2017, 10:55:07 pm by ratmalwer »

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Array of TMemorystream
« Reply #19 on: November 20, 2017, 11:11:55 pm »
I appoligize that I did not supply the correct Errormessage... sometimes difficult, I have to translate and do not know exactly what ist is in english.
The translation is why i personally dislike using native locale for lazarus/fpc as the common language to use is English.

No need to apologize, it is just that the error message is usually indicating the cause of what went wrong. You see it when running your code (of course), but we don't  :)

Quote
The error trying to display a picure at the end (or in other Procedure) is: Exception-Class EInvalidGraphic   unknown Pictureformat In File include\picture.inc line 5.7.8
ah, that is indeed a much more clear indication. Have you followed wp's advise to rewind the streams position ?

If that isn't helping then there is a possibility that the image loaded is indeed really unsupported (sound strange but it could happen).

but first let's take a look at your code:
Code: [Select]
... i = 1
  cache[i-1] := TMemorystream.create;  // i-1 = 1-1 = cache[0]
...
  Image1.Picture.LoadFromStream(Cache[1]);  //should display first file but crashes with Exception-Class EInvalidGraphic   unknown Pictureformat In File include\picture.inc
...
so... that seems a bit off, not ?

You can always verify by using
Code: [Select]
if assigned(cache[1]) then Image1.Picture.LoadFromStream(Cache[1]) else showmessage('oops, error encountered')
« Last Edit: November 20, 2017, 11:14:30 pm by molly »

ratmalwer

  • Jr. Member
  • **
  • Posts: 57
Re: Array of TMemorystream
« Reply #20 on: November 20, 2017, 11:27:17 pm »
BINGO!!! I overlooked even that!

So I enclose the latest running code, in the hope it still runs in future an helps others.

thanks Howard and Molly

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button4Click(Sender: TObject);
  2. var i: integer;
  3.   filename: string;
  4.   ImageCount : Integer;
  5. begin
  6.   ImageCount := StringGrid1.Rowcount -1;
  7.   SetLength(cache,ImageCount);
  8.   for i := 1 to ImageCount do begin   // 1 - 3  all .jpg
  9.        Filename := StringGrid1.Cells[6,i];
  10.        cache[i-1] := TMemorystream.create;
  11.        cache[i-1].LoadFromFile(Filename);
  12.        Image1.Picture.LoadFromStream(Cache[i-1]);   //displays current file correct
  13.        showmessage(inttostr(i));
  14.   end;
  15.  
  16.  
  17.  Cache[1].Position := 0;                     // rewind the stream
  18.  Image1.Picture.LoadFromStream(Cache[1]);
  19.  
  20. end;

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Array of TMemorystream
« Reply #21 on: November 21, 2017, 12:00:12 am »
I attach a compilable project that demonstrates a cleaner way to set up, and then access, a picture cache.

 

TinyPortal © 2005-2018