After looking for a way to resize TPngObject and maintain the transparency + alpha channels to no avail, I'm trying to use GDI+
Here is my code, and it seems to work fine. it will down/up scale a PNG. Tested on XP so far:
uses GDIPAPI, GDIPOBJ, GDIPUTIL;
procedure TForm1.Button1Click(Sender: TObject);
var
encoderClsid: TGUID;
stat: TStatus;
img, img_out: TGPImage;
begin
img := TGPImage.Create('in.png'); // 200 x 200
img_out := img.GetThumbnailImage(100, 100, nil, nil);
GetEncoderClsid('image/png', encoderClsid);
img_out.Save('out.png', encoderClsid);
img_out.free;
img.Free;
end;
My question: is using GetThumbnailImage
the correct way of doing this? I did not find any other method.
I don't think that GetThumbnailImage
method is a good way to go because I doubt that you will get a high quality resampled image. In this article you can find how to rescale the image. They're using the DrawImage
method for that, so I would do the same. Just before that I would set also the high quality graphics modes to get high quality output. Here is an example:
procedure TForm1.Button1Click(Sender: TObject);
var
Input: TGPImage;
Output: TGPBitmap;
Encoder: TGUID;
Graphics: TGPGraphics;
begin
Input := TGPImage.Create('C:\InputImage.png');
try
// create the output bitmap in desired size
Output := TGPBitmap.Create(100, 100, PixelFormat32bppARGB);
try
// create graphics object for output image
Graphics := TGPGraphics.Create(Output);
try
// set the composition mode to copy
Graphics.SetCompositingMode(CompositingModeSourceCopy);
// set high quality rendering modes
Graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);
Graphics.SetPixelOffsetMode(PixelOffsetModeHighQuality);
Graphics.SetSmoothingMode(SmoothingModeHighQuality);
// draw the input image on the output in modified size
Graphics.DrawImage(Input, 0, 0, Output.GetWidth, Output.GetHeight);
finally
Graphics.Free;
end;
// get encoder and encode the output image
if GetEncoderClsid('image/png', Encoder) <> -1 then
Output.Save('C:\OutputImage.png', Encoder)
else
raise Exception.Create('Failed to get encoder.');
finally
Output.Free;
end;
finally
Input.Free;
end;
end;
I don't think using of GetThumbnailImage
method is the correct approach. Why?
The main use of GetThumbnailImage
method is getting a thumbnail that you can use as a preview of some higher resolution image.
Therefore I assume the algorithm that is used behind is developed to be as fast as possible but it probably doesn't care about end result quality much. So using of this method can lead to resized images with pretty bad quality.
Now if you are realy interested in image manipulation using Delphi then you should definitely check the Graphics32 library (http://graphics32.org/wiki/).
It supports all Delphi versions from Delphi 7 and up. It provides many advanced image manipulation algorithms. And best of all it does support hardware acceleration meaning that it can actually make use of your GPU processing power to make those image manipulations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With