如何使用 GDI+ 调整带有 Alpha 通道的 PNG 图像?
How to resize PNG image with Alpha channels using GDI+?
在寻找调整 TPngObject 大小并保持透明度 + alpha 通道无济于事的方法后,我尝试使用 GDI+
这是我的代码,似乎工作正常。它将 down/up 缩放 PNG。
到目前为止在 XP 上测试:
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;
我的问题:使用 GetThumbnailImage
是执行此操作的正确方法吗?我没有找到任何其他方法。
我不认为使用 GetThumbnailImage
方法是正确的方法。为什么?
GetThumbnailImage
方法的主要用途是获取可用作某些更高分辨率图像预览的缩略图。
因此我假设后面使用的算法开发得尽可能快,但它可能不太关心最终结果的质量。所以使用这种方法会导致调整后的图像质量很差。
现在,如果您真的对使用 Delphi 进行图像处理感兴趣,那么您一定要查看 Graphics32 库 (http://graphics32.org/wiki/)。
它支持 Delphi 7 及更高版本的所有 Delphi 版本。它提供了许多高级图像处理算法。最重要的是,它确实支持硬件加速,这意味着它实际上可以利用您的 GPU 处理能力来进行这些图像处理。
我认为 GetThumbnailImage
方法不是一个好方法,因为我怀疑您能否获得高质量的重采样图像。在 this article you can find how to rescale the image. They're using the DrawImage
方法中,我也会这样做。就在那之前,我还会设置高质量图形模式以获得高质量输出。这是一个例子:
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;
在寻找调整 TPngObject 大小并保持透明度 + alpha 通道无济于事的方法后,我尝试使用 GDI+
这是我的代码,似乎工作正常。它将 down/up 缩放 PNG。 到目前为止在 XP 上测试:
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;
我的问题:使用 GetThumbnailImage
是执行此操作的正确方法吗?我没有找到任何其他方法。
我不认为使用 GetThumbnailImage
方法是正确的方法。为什么?
GetThumbnailImage
方法的主要用途是获取可用作某些更高分辨率图像预览的缩略图。
因此我假设后面使用的算法开发得尽可能快,但它可能不太关心最终结果的质量。所以使用这种方法会导致调整后的图像质量很差。
现在,如果您真的对使用 Delphi 进行图像处理感兴趣,那么您一定要查看 Graphics32 库 (http://graphics32.org/wiki/)。
它支持 Delphi 7 及更高版本的所有 Delphi 版本。它提供了许多高级图像处理算法。最重要的是,它确实支持硬件加速,这意味着它实际上可以利用您的 GPU 处理能力来进行这些图像处理。
我认为 GetThumbnailImage
方法不是一个好方法,因为我怀疑您能否获得高质量的重采样图像。在 this article you can find how to rescale the image. They're using the DrawImage
方法中,我也会这样做。就在那之前,我还会设置高质量图形模式以获得高质量输出。这是一个例子:
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;