Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: function not returning a TJPEGImage



Permlink Replies: 3 - Last Post: Dec 1, 2017 11:08 AM Last Post By: Remy Lebeau (Te...
Adalberto Baldini

Posts: 139
Registered: 1/31/12
function not returning a TJPEGImage
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 30, 2017 2:40 AM
Delphi XE5 Version 19.0.14356.6604

I have this function :

function TImageBox.Compress_Image(JpegImage_wk: TJPEGImage; rate, size : int64) : TJPEGImage;
var
compression : extended;
Mem_Stream : TMemoryStream;
begin
if not(size <= rate) then
begin
try
Mem_Stream := TMemoryStream.Create;
JpegImage_wk.DIBNeeded; // decompress
Compression := int(100 / int(size / rate));
JpegImage_wk.CompressionQuality := Trunc(compression);
JpegImage_wk.Compress;
// debug only to verify that it has compressed
Mem_Stream.Seek(0, soFromBeginning);
JpegImage_wk.SaveToStream(Mem_Stream);
size := Mem_Stream.Size; // it compress well
finally
Mem_Stream.Free;
end;
end;
Result := JpegImage_wk ;
end;

I call it :
// Jpeg := Compress_Image(Jpeg, rate, size);
Jpeg.Assign(Compress_Image(Jpeg, rate, size));
Mem_Stream.Seek(0, soFromBeginning);
Jpeg.SavetoStream(Mem_Stream);
size := Mem_Stream.Size;

in both version it return original size, or it means it doesn't get back compressed Jpeg

regards
Adalberto Baldini
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: function not returning a TJPEGImage
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 30, 2017 9:44 AM   in response to: Adalberto Baldini in response to: Adalberto Baldini
Adalberto Baldini wrote:

Jpeg := Compress_Image(Jpeg, rate, size);

What is the point of returning the input object? Since the function
modifies the input object, the Result is redundant. If you are not
going to return a new TJPEGImage object then I would suggest changing
the function into a procedure instead.

Jpeg.Assign(Compress_Image(Jpeg, rate, size));

This is a no-op, because you are just assigning the input image object
back to itself.

in both version it return original size, or it means it doesn't get
back compressed Jpeg

It is not enough to just load a TJPEGImage and then call Compress() on
it. It doesn't work that way. You have to re-load the image data to
force the compression to be applied.

For example, by using an intermediate TBitmap:

function TImageBox.Compress_Image(JpegImage_wk: TJPEGImage; rate, size
:   Int64) : TJPEGImage;
var
  compression : Extended;
  bmp: TBitmap;
  Mem_Stream : TMemoryStream;
begin
  if (size > rate) then
  begin
    Compression := int(100 / int(size / rate));
    bmp := TBitmap.Create;
    try
      bmp.Assign(JpegImage_wk);
      JpegImage_wk.CompressionQuality := Trunc(compression);
      JpegImage_wk.Assign(bmp);
    finally
      bmp.Free;
    end;
    // debug only to verify that it has compressed
    Mem_Stream := TMemoryStream.Create;
    try
      JpegImage_wk.SaveToStream(Mem_Stream);
      size := Mem_Stream.Size;
    finally
      Mem_Stream.Free;
    end;
  end;
  Result := JpegImage_wk;
end;


Or, just use the TMemoryStream you already have to re-load the data,
and then you don't need the TBitmap:

function TImageBox.Compress_Image(JpegImage_wk: TJPEGImage; rate, size
:   Int64) : TJPEGImage;
var
  compression : Extended;
  bmp: TBitmap;
  Mem_Stream : TMemoryStream;
begin
  if (size > rate) then
  begin
    Compression := int(100 / int(size / rate));
    JpegImage_wk.CompressionQuality := Trunc(compression);
    Mem_Stream := TMemoryStream.Create;
    try
      JpegImage_wk.Compress;
      JpegImage_wk.SaveToStream(Mem_Stream);
      Mem_Stream.Position := 0;
      JpegImage_wk.LoadFromStream(Mem_Stream);
      // debug only to verify that it has compressed
      size := Mem_Stream.Size;
    finally
      Mem_Stream.Free;
    end;
  end;
  Result := JpegImage_wk;
end;


Or, this might work, too:

type
  TJPEGImageAccess = class(TJPEGImage);
 

function TImageBox.Compress_Image(JpegImage_wk: TJPEGImage; rate, size
: Int64) : TJPEGImage;
var
compression : Extended;
Mem_Stream : TMemoryStream;
begin
if (size > rate) then
begin
Compression := int(100 / int(size / rate));
JpegImage_wk.CompressionQuality := Trunc(compression);
JpegImage_wk.Compress;
TJPEGImageAccess(JpegImage_wk).FreeBitmap;
// debug only to verify that it has compressed
Mem_Stream := TMemoryStream.Create;
try
JpegImage_wk.SaveToStream(Mem_Stream);
size := Mem_Stream.Size;
finally
Mem_Stream.Free;
end;
end;
Result := JpegImage_wk;
end;
{code}

--
Remy Lebeau (TeamB)
Adalberto Baldini

Posts: 139
Registered: 1/31/12
Re: function not returning a TJPEGImage
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 1, 2017 12:52 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi Remy,
thanks for yr suggestion, really problem is that it is not possible to assign jpeg to itself.

JpegImage_Read := Compress_Image(JpegImage, rate, size); // ok

I simplified my function and it works

function TImageBox.Compress_Image(JpegImage_wk: TJPEGImage; rate, size : int64) : TJPEGImage;
var
compression : extended;
begin
if not(size <= rate) then
begin
JpegImage_wk.DIBNeeded; // decompress, if missing compress doesn't work !!!!!!!!!!!
Compression := int(100 / int(size / rate));
JpegImage_wk.CompressionQuality := Trunc(compression);
JpegImage_wk.Compress;
end;
Result := JpegImage_wk ;
end;

Regards
Adalberto
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: function not returning a TJPEGImage
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 1, 2017 11:08 AM   in response to: Adalberto Baldini in response to: Adalberto Baldini
Adalberto Baldini wrote:

thanks for yr suggestion, really problem is that it is not possible
to assign jpeg to itself.

Like I said, there is no good reason for Compress_Image() to even have
a return value at all, since the function modifies the TJPEGImage that
is passed in. It is not allocating a new TJPEGImage object for return.
You are misusing that return value, which is what is getting you into
trouble. So get rid of the return value altogether:

Compress_Image(JpegImage, rate, size); // ok
 
procedure TImageBox.Compress_Image(JpegImage_wk: TJPEGImage; rate, size
: Int64);
var
  compression : extended;
begin
  if size > rate then
  begin
    Compression := int(100 / int(size / rate));
    JpegImage_wk.DIBNeeded; // decompress, if missing compress doesn't
work !!!!!!!!!!!
    JpegImage_wk.CompressionQuality := Trunc(compression);
    JpegImage_wk.Compress;
  end;
end;


--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02