2009-12-29 17 views
14

Ich benutze Delphi 2009 und ich möchte ein Bild skalieren, um den verfügbaren Platz zu passen. Das Bild wird immer kleiner als das Original angezeigt. Das Problem ist, dass TImage Stretch-Eigenschaft keine gute Arbeit leistet und die Lesbarkeit des Bildes beeinträchtigt.Skalieren Sie ein Bild in Delphi schön?

ugly way http://xrw.bc.ca/download/so/TImageStretch.gif

Ich mag es wie diese stattdessen skaliert, um zu sehen:

nicer way http://xrw.bc.ca/download/so/NicerTImageStretch.png

Irgendwelche Vorschläge, wie man am besten, dies zu tun? JVCL versucht, aber es scheint nicht diese Fähigkeit zu haben. Eine kostenlose Bibliothek wäre nett, aber vielleicht gibt es eine billige Bibliothek, die "nur" das tut, wäre auch gut.

Antwort

14

Wenn Sie Win32-API-Aufrufe verwenden, können Sie SetStretchBltMode zu HALFTONE verwenden und StretchBlt verwenden. Ich bin nicht sicher, ob dies mit Standard-Delphi-Aufrufen bereitgestellt wird, aber das ist die Art und Weise, wie ich dieses Problem im Allgemeinen löse.

Update (2014-09) Gerade jetzt war ich in einer ähnlichen Situation (wieder) und hatte eine TImage in einem TScrollBox mit viel mehr auf dem Formular los und wollte wirklich Image1.Stretch:=true; Halbton zu tun. Wie Rob darauf hinweist, TBitmap.Draw verwendet HALFTONE nur, wenn die Ziel-Leinwand 8 Bits pro Pixel oder niedriger ist und die Quelle Canvas mehr ... Also habe ich es mit der Zuweisung Image1.Picture.Bitmap zu einer dieser stattdessen:

'fixiert'
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; 
+0

danke; Dies bot eine gute Balance zwischen Geschwindigkeit und Qualität. –

+3

Delphi setzt den Stretch-Modus automatisch auf Halbton, wenn die Anzahl der Bits pro Pixel des Ziel-Canvas kleiner oder gleich 8 ist und die Bit-pro-Pixel-Anzahl der Quell-Bitmap größer ist als die des Ziels. Andernfalls verwendet es Stretch_DeleteScans für Farb-Bitmaps. –

+0

danke rauben. Ich brauchte es, um HALFTONE immer zu benutzen. BTW, danke für so viel gutes Zeug auf Stapelüberlauf. –

31

Sie wirklich, wirklich wollenGraphics32 verwenden.

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; 

Sie haben verschiedene Methoden und Filter zu wählen, wenn ein Bild Resampling. Das obige Beispiel verwendet einen Kernel-Resampler (ein bisschen langsam, aber mit großartigen Ergebnissen) und einen Lanczos Filter als Rekonstruktionskernel. Das obige Beispiel sollte für Sie funktionieren.

+1

es ist ein cooles Werkzeug, aber ich fand es zu langsam für genau das, was ich brauchte. Jetzt, da ich es habe, bin ich sicher, dass ich es für etwas anderes verwenden werde. Danke! –

+0

Großartig - aber wenn Sie es langsam finden, bin ich meistens geneigt zu denken, dass etwas anderswo nicht stimmt. Wie auch immer, froh, dass Sie eine gute Lösung für Ihr Problem gefunden haben! –

+2

Vielleicht war es langsam für ihn, weil er jede Sekunde schnelle Updates machte? Ich hatte das gleiche Performance-Problem und das war auf einem Intel Quad Core I5 ​​mit viel Speicher.Ich wechselte von einem Kernel-Resampler zu einem Draft-Resampler (TDraftResampler) und das Performance-Problem verschwand. Im Fall meiner Anwendung habe ich ein Bild mit 1100 W x 1100 h 20 Mal pro Sekunde aktualisiert und dann das Downsampling durchgeführt, und der Lanczos-Kernel war zu langsam, um Schritt zu halten. Danke für den Hinweis zur Graphics32-Bibliothek. Es ist ein echter Segen, und es hat wirklich dazu beigetragen, das Aussehen meines Downsampling-Bildes zu verbessern. –

6

Sie konnten die eingebaute in Delphi Scaleimage von GraphUtil versuchen

+0

danke für den Tipp - ich wusste nicht über ScaleImage! –

3

I GDIPOB.pas der TGPGraphics Klasse

wenn Canvas TGPGraphics verwenden ist, Bounds ist TGPRectF und NewImage ist TGPImage Beispiel:

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

Sie die Qualität VS Geschwindigkeitsfaktor wählen

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

und smooting Modus den Interpolationsmodus durch Änderung:

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

Hinweis: Dies würde XP benötigen oder später oder das Bündeln der gdiplus.dll in Ihrem Installer.