Recent

Author Topic: TJpegImage.Compress and SaveToStream  (Read 532 times)

Aidex

  • Jr. Member
  • **
  • Posts: 75
TJpegImage.Compress and SaveToStream
« on: March 30, 2021, 10:16:22 am »
Hi!
I want to save a bitmap as a JPEG into a MemoryStream.
Unfortunately, I am not able to load it from the stream again (results a black bitmap in correct size).
In Delphi 7 it had worked. In Delphi there is the method TJpegImage.Compress(), but it doesn't seem to exist in FP.
Could the missing Compress() method be the problem? Is Compress() not needed or is there an alternative?
Thanks!

Code: Pascal  [Select][+][-]
  1. jpg:=TJpegImage.Create;
  2. jpg.Assign(bmp);
  3. jpg.CompressionQuality:=90;
  4. // jpg.Compress;   missing in FP ?
  5. jpg.SaveToStream(m);
  6. jpg.Destroy;
  7.  

loaded

  • Full Member
  • ***
  • Posts: 198
Re: TJpegImage.Compress and SaveToStream
« Reply #1 on: March 30, 2021, 12:48:35 pm »
Hi,
You must reset the position value before restoring from stream.
Tested working code sample ;
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   jpg:TJpegImage;
  4.   m:TMemoryStream;
  5. begin
  6.   m:=TMemoryStream.Create;
  7.   m.Position:=0;
  8.  
  9.   jpg:=TJpegImage.Create;
  10.   jpg.Assign(image1.Picture.Bitmap);
  11.   jpg.CompressionQuality:=90;
  12.   jpg.SaveToStream(m);
  13.   jpg.Destroy;
  14.  
  15.   m.Position:=0; // <-------------
  16.   image2.Picture.LoadFromStream(m);
  17.  
  18. end;
  19.  
« Last Edit: March 30, 2021, 12:50:53 pm by loaded »
Installing the spelling, google translate is used :)

Aidex

  • Jr. Member
  • **
  • Posts: 75
Re: TJpegImage.Compress and SaveToStream
« Reply #2 on: March 30, 2021, 01:17:15 pm »
Thanks for your help!  :)
I had already done the positioning m.Position:=0;
My source code is a bit more complex ... then the problem is somewhere in my complex source code.
Ok, now that I know it's not the missing .Compress, I'll have to go troubleshooting some more.
Converting an old Delphi program does have more pitfalls in the details than I had thought.  ::)
Thanks again.
« Last Edit: March 30, 2021, 01:21:19 pm by Aidex »

wp

  • Hero Member
  • *****
  • Posts: 8410
Re: TJpegImage.Compress and SaveToStream
« Reply #3 on: March 30, 2021, 01:42:31 pm »
Compress has been introduced in FPC 3.2. But it does nothing else than saving to a temp stream and reading it back - so, forget about it.
Code: Pascal  [Select][+][-]
  1. procedure TJPEGImage.Compress;
  2. var
  3.   TempStream: TMemoryStream;
  4. begin
  5.   TempStream := TMemoryStream.Create;
  6.   try
  7.     FreeSaveStream;
  8.     SaveToStream(TempStream);
  9.     TempStream.Position := 0;
  10.     LoadFromStream(TempStream);
  11.   finally
  12.     TempStream.Free;
  13.   end;
  14. end;

Delphi's online help is talking non-sense here (translated from German): "By changing property "CompressionQuality" no compression can be achieved.  Always use the method "Compress" for this purpose". I checked it: the following code always results in a low-quality image no matter whether Compress is called or not, even with Delphi 7:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   bmp: TBitmap;
  4.   jpg: TJpegImage;
  5. begin
  6.   bmp := TBitmap.Create;
  7.   try
  8.     bmp.SetSize(100, 100);
  9.     bmp.Canvas.Brush.Color := clWhite;
  10.     bmp.Canvas.FillRect(0, 0, 100, 100);
  11.     bmp.Canvas.TextOut(0, 0, 'Test');
  12.  
  13.     jpg := TJpegImage.Create;
  14.     try
  15.       jpg.Assign(bmp);
  16.       jpg.CompressionQuality := 5;   // very low quality to see in the save image whether compression has been performed.
  17.       jpg.Compress;
  18.       jpg.SaveToFile('test.jpg');
  19.     finally
  20.       jpg.Free;
  21.     end;
  22.  
  23.   finally
  24.     bmp.Free;
  25.   end;
  26. end;  
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

 

TinyPortal © 2005-2018