Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot compress JPEG image and show it on screen

Tags:

delphi

I try to load an image in imgQInput (which is a TImage), assign it to a TJpegImage, compress it (compression factor 5) and show it in imgQOutput (another TImage). But it doesn't work. The image in imgQOutput is the same as the original. It should look VERY pixelated because of the compression factor! The compression works however, because when I save the JPEG to disk it is really small.

  JPG:= TJPEGImage.Create;
   TRY
     JPG.CompressionQuality:= trkQuality.Position;
     JPG.Assign(imgQInput.Picture.Graphic);
     CompressJpeg(JPG);
     imgQOutput.Picture.Assign(JPG);          <--------- something wrong here. the shown image is not the compressed image but the original one
   FINALLY
     FreeAndNil(JPG);
   END;


function CompressJpeg(OutJPG: TJPEGImage): Integer;
VAR tmpQStream: TMemoryStream;
begin
 tmpQStream:= TMemoryStream.Create;
 TRY
   OutJPG.Compress;
   OutJPG.SaveToStream(tmpQStream);
   OutJPG.SaveToFile('c:\CompTest.jpg');       <--------------- this works
   Result:= tmpQStream.Size;
 FINALLY
   FreeAndNil(tmpQStream);
 END;
end;
like image 802
Server Overflow Avatar asked Feb 26 '12 20:02

Server Overflow


2 Answers

You did not used the compressed JPG at all.

Change CompressJpeg as followings:

function CompressJpeg(OutJPG: TJPEGImage): Integer;
VAR tmpQStream: TMemoryStream;
begin
 tmpQStream:= TMemoryStream.Create;
 TRY
   OutJPG.Compress;
   OutJPG.SaveToStream(tmpQStream);
   OutJPG.SaveToFile('c:\CompTest.jpg');    // You can remove this line.
   tmpQStream.Position := 0;                //
   OutJPG.LoadFromStream(tmpQStream);       // Reload the jpeg stream to OutJPG
   Result:= tmpQStream.Size;
 FINALLY
   FreeAndNil(tmpQStream);
 END;
end;
like image 151
Vahid Nasehi Avatar answered Nov 15 '22 05:11

Vahid Nasehi


Here is a competing answer for you, with less data jugglery (remember, images can be large!)

type
  TJPEGExposed = class(TJPEGImage);     // unfortunately, local class declarations are not allowed

procedure TForm1.FormClick(Sender: TObject);
var
  JPEGImage: TJPEGImage;
const
  jqCrappy = 1;
begin
  Image1.Picture.Bitmap.LoadFromFile(GetDeskWallpaper);

  Image2.Picture.Graphic := TJPEGImage.Create;
  JPEGImage := Image2.Picture.Graphic as TJPEGImage;    // a reference
  JPEGImage.Assign(Image1.Picture.Bitmap);
  JPEGImage.CompressionQuality := jqCrappy;    // intentionally
  JPEGImage.Compress;
  TJPEGExposed(JPEGImage).FreeBitmap;    { confer: TBitmap.Dormant }
end;

TJPEGImage.FreeBitmap disposes volatile DIB contained within TJPEGImage instance. In the illustrated case this causes class to decode recently .Compress'ed JPEG in response to TImage repainting.

like image 42
OnTheFly Avatar answered Nov 15 '22 04:11

OnTheFly