Search code examples
delphidelphi-10-seattle

how do i Assigning Timage bitmap to jpg correctly?


i am doing the following to resize a Timage graphic and save it as jpg . the image saved blank .

here is how i assign the Timage

begin
 with TOpenDialog.Create(self) do
    try
      Caption := 'Open Image';
      Options := [ofPathMustExist, ofFileMustExist];
      Filter  := 'JPEG Image File (*.jpg)|*.jpg|JPEG Image File (*.jpeg)|*.jpeg|Bitmaps (*.bmp)|*.bmp';
      if Execute then
        image1.Picture.LoadFromFile(FileName);
    finally
      Free;
    end;
end;

and here is how i resize the timage and assigning it into a jpg .

 with Image2.Canvas do begin
    Lock;
    try
      try
        Image2.Picture.Graphic.Width := 50;
        Image2.Picture.Graphic.Height := 50;
        FillRect(ClipRect);
        StretchDraw(rect(0, 0, 50, 50), image1.Picture.Bitmap);
      except
        on E: Exception do
//log

      end;
    finally
      Unlock;
    end;
  end;




Jpg := TJPEGImage.Create;
try

Jpg.Performance := jpBestSpeed;
Jpg.ProgressiveEncoding := True;
Jpg.ProgressiveDisplay := True;
Jpg.Assign(image2.Picture.Bitmap);
Jpg.CompressionQuality := 90;
Jpg.Compress;
jpg.SaveToFile('screena.jpg');



finally
Jpg.Free;
end;

The saved jpg becomes blank what i am doing wrong ? all i needed to do is load image from disk into Timage then adjust the width and height and assign it again into a jpg


Solution

  • The reason your image is blank is because you are using the Picture.Bitmap property when drawing Image1 onto the canvas of Image2:

    StretchDraw(rect(0, 0, 50, 50), image1.Picture.Bitmap);
    

    If you have NOT loaded a .bmp file into Image1, accessing the Bitmap property will wipe out the current image and replace it with a blank image. This is documented behavior:

    Use Bitmap to reference the picture object when it contains a bitmap. If Bitmap is referenced when the picture contains a Metafile or Icon graphic, the graphic won't be converted (Types of Graphic Objects). Instead, the original contents of the picture are discarded and Bitmap returns a new, blank bitmap.

    The TCanvas.StretchDraw() method accepts any TGraphic object in its 3rd parameter. You should be passing in the Picture.Graphic property instead of the Picture.Bitmap property:

    StretchDraw(rect(0, 0, 50, 50), image1.Picture.Graphic);
    

    On a side note: When assigning the TOpenDialog.Filter property, consider using the VCL's GraphicFilter() function in the Graphics unit:

    Returns a file filter compatible with the Filter property of an Open or Save dialog.

    Call GraphicFilter to obtain a value for the Filter property of an Open, Open Picture, Save Picture or Save dialog box. The GraphicClass parameter can specify one of these values: TBitmap, TGraphic, TIcon, TMetafile, or a user-defined descendant of TGraphic.

    For example:

    Filter := GraphicFilter(TGraphic);
    

    If you are going to populate the Filter manually, then at the least, don't have separate entries for the different JPEG extensions. Group them together in a single entry, eg:

    Filter  := 'JPEG Images (*.jpg, *.jpeg)|*.JPG;*.JPEG|Bitmap Images (*.bmp)|*.BMP';