Recent

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

Aidex

  • Jr. Member
  • **
  • Posts: 82
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

  • Hero Member
  • *****
  • Posts: 853
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 »
Check out  loaded on Strava
https://www.strava.com/athletes/109391137

Aidex

  • Jr. Member
  • **
  • Posts: 82
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: 12462
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;  

Jiyahana

  • New Member
  • *
  • Posts: 12
Re: TJpegImage.Compress and SaveToStream
« Reply #4 on: February 05, 2024, 10:39:50 am »
Yes, here is alternative method

Code: [Select]
uses
  Classes, SysUtils, Graphics, BGRABitmap, BGRABitmapTypes;

procedure SaveBitmapToStreamAsJPEG(Bitmap: TBitmap; Stream: TStream; CompressionQuality: integer);
var
  Bmp32: TBGRABitmap;
begin
  Bmp32 := TBGRABitmap.Create(Bitmap);
  try
    Bmp32.SaveToStreamAs(Bitmap, Stream, ifJPEG, CompressionQuality);
  finally
    Bmp32.Free;
  end;
end;
and If you want to manually compress your images then you can choose online application such as jpeg compressor it compress images with losing the quality.

TRon

  • Hero Member
  • *****
  • Posts: 3631
Re: TJpegImage.Compress and SaveToStream
« Reply #5 on: February 27, 2024, 01:06:27 am »
completely off-topic rant

Great.

Dumb AI answers that find their way in the forums. Ideal showcase to confirm that AI is only about (most common) predictability. Perfect technology to let the sheep be sheep (or actually degenerate them into something even more horrific).
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

lainz

  • Hero Member
  • *****
  • Posts: 4610
  • Web, Desktop & Android developer
    • https://lainz.github.io/
Re: TJpegImage.Compress and SaveToStream
« Reply #6 on: February 27, 2024, 01:17:51 am »
completely off-topic rant

Great.

Dumb AI answers that find their way in the forums. Ideal showcase to confirm that AI is only about (most common) predictability. Perfect technology to let the sheep be sheep (or actually degenerate them into something even more horrific).

AI works for me (TM) most of the time, but you need to give it the correct promt.

I generated a PDF in Android with AI, not so complex but I've finished it in less than an hour, coding it by myself can take the double of time or more.

Edit: But I agree, these bad answers should not be published in the forum..

TRon

  • Hero Member
  • *****
  • Posts: 3631
Re: TJpegImage.Compress and SaveToStream
« Reply #7 on: February 27, 2024, 01:46:30 am »
AI works for me (TM) most of the time, but you need to give it the correct promt.
The "problem" is, that although it can be used to ease up writing repetitive code (at least repetitive for/to the AI), that the answers are based on (common available) input and used to predict a most commonly accepted answer.

There is nothing unique, refreshing or smart about the generated code, or it must be you prompted it to combine different variations of the theme that no-one has though of before (but then you are the one that combined them).

Thus basically a one-size-fits-all with a little flavour of randomness attached to it so that it appears to be .......  :)

That is working great if you expected that and are able to live with such an answer (not saying it is wrong perse, but just based on/for the masses).
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: TJpegImage.Compress and SaveToStream
« Reply #8 on: February 27, 2024, 02:05:31 am »
I use TZipper , it can be used for streams.
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018