16

Delphi 2009を使用していますが、使用可能なスペースに合わせて画像を拡大縮小したいと思います。画像は常に元の画像よりも小さく表示されます。問題は、TImage Stretchプロパティがうまく機能せず、画像の読みやすさを損なうことです。

醜い方法
(出典:xrw.bc.ca

代わりに、次のようにスケーリングされることを確認したいと思います。

より良い方法
(出典:xrw.bc.ca

これを行うための最善の方法はありますか?JVCLを試しましたが、この機能がないようです。無料のライブラリがあればいいのですが、これだけを実行する低コストのライブラリもあるかもしれません。

4

4 に答える 4

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フィルターを使用しています。上記の例はあなたのために働くはずです。

于 2009-12-29T18:39:09.070 に答える
17

Win32 API呼び出しの使用に戻る場合は、SetStretchBltModeを使用してHALFTONEを実行し、 StretchBltを使用できます。これがデフォルトのDelphi呼び出しを使用して提供されているかどうかはわかりませんが、これが私が一般的にこの問題を解決する方法です。

更新(2014-09)ちょうど今、私は(再び)同様の状況にあり、フォーム上でさらに多くのことが行われているTScrollBoxにTImageがあり、本当にImage1.Stretch:=true;ハーフトーンを実行したいと思っていました。Robが指摘しているように、TBitmap.DrawHALFTONE、宛先キャンバスが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;
于 2009-12-29T19:33:10.130 に答える
12

GraphUtilの組み込みのDelphiScaleImageを試すことができます

于 2009-12-30T08:11:33.410 に答える
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をバンドルする必要があります。

于 2010-01-01T10:22:15.430 に答える