I need to add people's portraits into my app. I'm looking for the most reasonable way to accept as input an image in GIF, BMP, JPG, or PNG, and of (relatively) arbitrary size, then to resize it to my target size (ca. 200x240) and format (JPG). I want a solution which does a good job of scaling, minimizing artifacts. Not in search of a science project, nor a solution which depends on DLLs (other than standard Windows stuff), nor expensive 3rd party image processing tools.

Comments

  1. Thanks to all for the suggestions. I have found that the TMS TAdvOfficeImage component works very well for loading from numerous formats. However, how to get from there to a scaled JPEG file is not apparent. Unlike TImage, they do not expose a TBitmap, so I am in murky waters. Moreover, I have found minimal information on how to use it for other than presenting an image on a form. It does provide stream I/O, however, which may be the path I need....

    ReplyDelete
  2. GdiPlus has a nice demo showing most topics. Extracts:

    procedure TDemoCropAndScaleImages.Run;
    var
      Image: IGPImage;
      Width, Height: Integer;
      DestinationRect: TGPRectF;
    begin
      Image := TGPImage.Create('Apple.gif');
      Width := Image.Width;
      Height := Image.Height;
      // Make the destination rectangle 30 percent wider and
      // 30 percent taller than the original image.
      // Put the upper-left corner of the destination
      // rectangle at (150, 20).
      DestinationRect.Initialize(150, 20, 1.3 * Width, 1.3 * Height);
      // Draw the image unaltered with its upper-left corner at (0, 0).
      Graphics.DrawImage(Image, 0, 0);
      // Draw a portion of the image. Scale that portion of the image
      // so that it fills the destination rectangle.
      Graphics.DrawImage(Image, DestinationRect,
        0, 0,          // upper-left corner of source rectangle
        0.75 * Width,  // width of source rectangle
        0.75 * Height, // height of source rectangle
        UnitPixel);
    end;

    procedure TDemoTransformJpeg.Run;
    var
      Image: IGPImage;
      Width, Height: Integer;
      Params: IGPEncoderParameters;
    begin
      Image := TGPImage.Create('ImageFile.jpg');
      Graphics.DrawImage(Image, 0, 0, Image.Width div 2, Image.Height div 2);
      Width := Image.Width;
      Height := Image.Height;
      TextOutput.Add(Format('The width of the image is %d,', [Width]));
      if ((Width mod 16) = 0) then
        TextOutput.Add('which is a multiple of 16.')
      else
        TextOutput.Add('which is not a multiple of 16.');
      TextOutput.Add(Format('The height of the image is %d,', [Height]));
      if ((Height mod 16) = 0) then
        TextOutput.Add('which is a multiple of 16.')
      else
        TextOutput.Add('which is not a multiple of 16.');
      Params := TGPEncoderParameters.Create;
      Params.Add(EncoderTransformation, EncoderValueTransformRotate90);
      Image.Save('ImageFileR90.jpg', TGPImageFormat.Jpeg, Params);
      // Reload rotated image
      Image := TGPImage.Create('ImageFileR90.jpg');
      Graphics.DrawImage(Image, 330, 0, Image.Width div 2, Image.Height div 2);
    end;

    procedure TDemoBmpToPng.Run;
    var
      Image: IGPImage;
    begin
      Image := TGPImage.Create('Bird.bmp');
      Graphics.DrawImage(Image, 10, 10, Image.Width, Image.Height);
      try
        Image.Save('Bird.png', TGPImageFormat.Png);
        TextOutput.Add('Bird.png was saved successfully.');
        Image := TGPImage.Create('Bird.png');
        Graphics.DrawImage(Image, 130, 10, Image.Width, Image.Height);
      except
        on E: Exception do
          TextOutput.Add('Failure: ' + E.Message);
      end;
    end;

    ReplyDelete

Post a Comment