【发布时间】:2021-11-10 11:21:47
【问题描述】:
我正在使用 Delphi 10.4.2,我正在尝试找到一种方法来缩放图像,以保持图像质量并且不请求外部库。
这是我试过的,你可以在{$REGION}找到两个测试:
procedure TFrmTestGenImg.Test;
var
LOldWidth, LOldHeight, LNewWidth, LNewHeight: integer;
LImageNameIn, LImageNameOut, LExt: string;
LClass: TGraphicClass;
LImageIn, LImageOut: TGraphic;
LBitmap, LResized: TBitmap;
begin
// Original image: 1366 x 768
LOldWidth := 1366;
LOldHeight := 768;
LNewWidth := 800;
LNewHeight := 449;
LImageNameIn := 'C:\temp\Input.png';
LImageNameOut := 'C:\temp\Output_' + FormatDateTime('yyyy.mm.dd hh.nn.ss.zzz', Now) + '.png';
LExt := TPath.GetExtension(LImageNameIn);
Delete(LExt, 1, 1);
if (CompareText(LExt, 'bmp') = 0) then
LClass := TBitmap
else if (CompareText(LExt, 'gif') = 0) then
LClass := TGIFImage
else
LClass := TWICImage;
LImageIn := LClass.Create;
try
LImageOut := LClass.Create;
try
LImageIn.Transparent := True;
LImageIn.LoadFromFile(Trim(LImageNameIn));
LBitmap := TBitmap.Create;
try
LBitmap.PixelFormat := pf24bit;
LBitmap.Assign(LImageIn);
{$REGION '1st test'}
LBitmap.Canvas.StretchDraw(
Rect(0, 0, LNewWidth, LNewHeight),
LImageIn); // -> poor quality
LBitmap.SetSize(LNewWidth, LNewHeight);
LImageOut.Assign(LBitmap);
{$ENDREGION}
{$REGION '2nd test'}
LResized := TBitmap.Create;
try
LResized.Assign(LBitmap);
LResized.Width := LNewWidth;
LResized.Height := LNewHeight;
GraphUtil.ScaleImage(LBitmap, LResized, (LNewWidth/LOldWidth)); // -> empty image
LResized.SetSize(LNewWidth, LNewHeight);
LImageOut.Assign(LResized);
finally
LResized.Free;
end;
{$ENDREGION}
if LImageIn is TWICImage then
begin
if (CompareText(LExt, 'jpg') = 0) or (CompareText(LExt, 'jpeg') = 0) then
TWICImage(LImageOut).ImageFormat := wifJpeg
else
TWICImage(LImageOut).ImageFormat := TWICImage(LImageIn).ImageFormat;
end;
LImageOut.SaveToFile(LImageNameOut);
finally
LBitmap.Free;
end;
finally
LImageOut.Free;
end;
finally
LImageIn.Free;
end;
end;
如您所见,第二次测试我使用了GraphUtil.ScaleImage,但输出的是一个空图像,所以我不确定我是否正确使用它,不幸的是我还没有找到这种方法的任何示例..
【问题讨论】:
-
你基本上想要vector graphics,而不是raster graphics。您无法“保持”质量,因为抖动更改或重新编码是不可避免的。
-
@AmigoJack 我知道图像质量不能完全相同,但
StretchDraw产生的 png 质量非常低。我尝试使用 Image Magick 并且输出很好,但如果可以的话,我'd rater 使用 Delphi 代码 -
GraphUtil.ScaleImage是我会使用的。删除行LResized.Assign(LBitmap);并添加LResized.PixelFormat := pf24bit; -
@TomBrunberg 谢谢!这样
ScaleImage终于产生了输出。虽然它的质量仍然很低..
标签: delphi image-scaling delphi-10.4-sydney delphi-10.4.2