Хорошо масштабировать изображение в Delphi?

Я использую Delphi 2009, и я хотел бы масштабировать изображение, чтобы соответствовать доступному пространству. изображение всегда отображается меньше оригинала. проблема в том, что свойство Timage Stretch не делает хорошую работу и вредит удобочитаемости изображения.

уродливый путь http://xrw.bc.ca/download/so/TImageStretch.gif

Я бы хотел, чтобы он был масштабирован следующим образом:

приятней http://xrw.bc.ca/download/so/NicerTImageStretch.png

любые предложения, как лучше всего это сделать? Пробовал JVCL, но, похоже, у него нет этой способности. Бесплатная библиотека была бы хорошей, но, возможно, есть недорогая библиотека, которая делает "только" это было бы хорошо.

4 ответов


если вы вернетесь к использованию вызовов Win32 API, вы можете использовать SetStretchBltMode полутона и использовать сбой stretchblt. Я не уверен, что это предусмотрено с помощью вызовов Delphi по умолчанию, но так я обычно решаю эту проблему.

обновление (2014-09) только что я был в аналогичной ситуации (снова) и имел TImage в TScrollBox с большим количеством больше происходит на форме, и действительно хотел Image1.Stretch:=true; сделать полутонов. Как указывает Роб,TBitmap.Draw использует Полутон только когда целевой холст составляет 8 бит на пиксель или ниже, а исходный холст имеет больше... Так я норм с назначением Image1.Picture.Bitmap к одному из них вместо этого:

TBitmapForceHalftone=class(TBitmap)
protected
  procedure Draw(ACanvas: TCanvas; const Rect: TRect); override;
end;

{ TBitmapForceHalftone }

procedure TBitmapForceHalftone.Draw(ACanvas: TCanvas; const Rect: TRect);
var
  p:TPoint;
  dc:HDC;
begin
  //not calling inherited; here!
  dc:=ACanvas.Handle;
  GetBrushOrgEx(dc,p);
  SetStretchBltMode(dc,HALFTONE);
  SetBrushOrgEx(dc,p.x,p.y,@p);
  StretchBlt(dc,
    Rect.Left,Rect.Top,
    Rect.Right-Rect.Left,Rect.Bottom-Rect.Top,
    Canvas.Handle,0,0,Width,Height,ACanvas.CopyMode);
end;

вы действительно, действительно хочу!--3--> использовать 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;

у вас есть несколько методов и фильтров для обработки изображения. В приведенном выше примере используется ресамплер ядра (медленный, но с отличными результатами) и Ланцоша фильтр как ядро восстановления. Приведенный выше пример должен работать на вас.


вы можете попробовать встроенный Delphi ScaleImage из GraphUtil


Я использую GDIPOB.класс TGPGraphics pas

Если Canvas - TGPGraphics, Bounds - tgprectf, а NewImage-экземпляр tgpimage:

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

вы можете выбрать качество против фактора скорости, изменив режим интерполяции

InterpolationModeDefault             = QualityModeDefault;
InterpolationModeLowQuality          = QualityModeLow;
InterpolationModeHighQuality         = QualityModeHigh;
InterpolationModeBilinear            = 3;
InterpolationModeBicubic             = 4;
InterpolationModeNearestNeighbor     = 5;
InterpolationModeHighQualityBilinear = 6;
InterpolationModeHighQualityBicubic  = 7;

и режим smooting:

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

Примечание: это потребует XP или более поздней или bundeling в gdiplus.dll в установщике.