在Delphi中很好地缩放图像?

时间:2009-12-29 18:30:02

标签: delphi graphics image-scaling timage

我正在使用Delphi 2009,我想缩放图像以适应可用空间。图像始终显示小于原始图像。问题是TImage Stretch属性做得不好,损害了图片的可读性。

ugly way
(来源:xrw.bc.ca

我希望看到它像这样缩放:

nicer way
(来源:xrw.bc.ca

有任何建议如何最好地做到这一点?试过JVCL,但它似乎没有这种能力。一个免费的图书馆会很不错,但也许有一个低成本的图书馆“只”这样做也会很好。

4 个答案:

答案 0 :(得分:32)

真的,非常希望使用Graphics32

procedure DrawSrcToDst(Src, Dst: TBitmap32);
var
  R: TKernelResampler;  
begin
  R := TKernelResampler.Create(Src);
  R.Kernel := TLanczosKernel.Create;
  Dst.Draw(Dst.BoundsRect, Src.BoundsRect, Src);
end;

重新采样图像时,您可以选择多种方法和过滤器。上面的示例使用内核重采样器(有点慢,但效果很好)和Lanczos过滤器作为重建内核。以上示例应该适合您。

答案 1 :(得分:16)

如果您还原为使用Win32 API调用,则可以将SetStretchBltMode用于HALFTONE并使用StretchBlt。我不确定这是否是使用默认的Delphi调用提供的,但这就是我通常解决这个问题的方式。

更新(2014-09)刚才我处于类似情况(再次)并且在TScrollBox中有一个TImage,表单上有更多内容,并且真的想要{{1}做半色调。正如Rob指出的那样,当目标画布为每像素8位或更低时,Image1.Stretch:=true;仅使用HALFTONE ,并且源画布有更多...所以我通过分配'固定'它TBitmap.Draw代替其中一个:

Image1.Picture.Bitmap

答案 2 :(得分:8)

您可以尝试使用GraphUtil

中的内置Delphi ScaleImage

答案 3 :(得分:3)

我使用GDIPOB.pas的TGPGraphics类

如果Canvas是TGPGraphics,Bounds是TGPRectF,NewImage是TGPImage实例:

Canvas.SetInterpolationMode(InterpolationModeHighQualityBicubic);
Canvas.SetSmoothingMode(SmoothingModeHighQuality);
Canvas.DrawImage(NewImage, Bounds, 0, 0, NewImage.GetWidth, NewImage.GetHeight, UnitPixel);

您可以通过更改插值模式

来选择质量VS速度系数
InterpolationModeDefault             = QualityModeDefault;
InterpolationModeLowQuality          = QualityModeLow;
InterpolationModeHighQuality         = QualityModeHigh;
InterpolationModeBilinear            = 3;
InterpolationModeBicubic             = 4;
InterpolationModeNearestNeighbor     = 5;
InterpolationModeHighQualityBilinear = 6;
InterpolationModeHighQualityBicubic  = 7;

和拍摄模式:

SmoothingModeDefault     = QualityModeDefault;
SmoothingModeHighSpeed   = QualityModeLow;
SmoothingModeHighQuality = QualityModeHigh;
SmoothingModeNone        = 3;
SmoothingModeAntiAlias   = 4;

注意:这需要XP或更高版本,或者在安装程序中使用gdiplus.dll。