![]() |
AW: Resample oder Resize mit GDI+
Zitat:
Delphi-Quellcode:
verkleinere.
StretchBlt()
Außerdem drucken wir auch. Die Drucker arbeiten alle mit 600 dpi, so dass das Bild vergrößern muss. Und da ich "Blut geleckt habe", möchte ich auch die Vergrößerung optimieren. Ansonsten wäre ich mit StretchBlt() und Halftone schon fertig gewesen. Das sieht nämlich ganz passabel aus und geht (auch) schnell. Zitat:
|
AW: Resample oder Resize mit GDI+
Wieder eine gute Tat für Heute :)
Heheheeee.. gruss |
AW: Resample oder Resize mit GDI+
So. Ich habe mir jetzt mal ausgehend von
![]() ![]()
Delphi-Quellcode:
Das Verkleinern funktioniert insoweit einwandfrei. Das vergrößern denknotwendiger Weise nicht. Denn ich muss vor dem Vergrößern den notwendigen Platz schaffen, indem ich Width und Height schon setze. Dann vergrößert er aber nichts mehr und ich habe weiter den weißen Rand, was auch logisch ist.
Procedure StretchGdip(Var Bitmap: TBitmap; Const NewWidth, NewHeight: Integer;
Smoothing : SmoothingMode = SmoothingModeNone; Interpolation: InterpolationMode = InterpolationModeDefault; PixelOffset : PixelOffsetMode = PixelOffsetModeNone; CompositingQuality: CompositingQualityMode = CompositingQualityDefault; CompositingMode: CompositingModeMode = CompositingModeSourceOver); Var ScaleDown : Boolean; W, H : Single; oldW, oldH : Single; graphics : Cardinal; str : TStream; image : Cardinal; Begin If (Bitmap.Empty) Or ((NewWidth = 0) And (NewHeight = 0)) Or ((NewWidth = Bitmap.Width) And (NewHeight = Bitmap.Height)) Then Exit; W:=NewWidth; H:=NewHeight; oldW:=Bitmap.Width; oldH:=Bitmap.Height; If (W = 0) Then W:=H * oldW / oldH; If (H = 0) Then H:=W * oldH / oldW; ScaleDown:=((W < oldW) Or (H < oldH)); If GdipCreateFromHDC(Bitmap.Canvas.Handle, graphics) = 0 Then Begin GdipSetSmoothingMode( graphics, Smoothing); GdipSetInterpolationMode( graphics, Interpolation); GdipSetPixelOffsetMode( graphics, PixelOffset); GdipSetCompositingQuality( graphics, CompositingQuality); GdipSetCompositingMode( graphics, CompositingMode); str:=TMemoryStream.Create; Try Bitmap.SaveToStream(str); str.Position:=0; If (Not ScaleDown) Then Begin Bitmap.Width:= Round(W); Bitmap.Height:=Round(H); End; If GdipLoadImageFromStreamICM(TStreamAdapter.Create(str), image) = 0 Then GdipDrawImageRect(graphics, image, 0, 0, W, H); If (ScaleDown) Then // überflüssige Ränder abschneiden Begin Bitmap.Width:= Round(W); Bitmap.Height:=Round(H); End; Finally str.Free; End; GdipDeleteGraphics(graphics); End; End; Ich wollte aber für die Ausgabe auf dem 600dpi-Drucker die 200dpi-Bilder entsprechend vergrößern. Bei meiner Version mit GDI (ohne "+") gibt es da keine Probleme, weil ich über
Delphi-Quellcode:
die alte und neue Größe angeben kann.
StretchBlt(self.Canvas.Handle,
0, 0, W, H, self.Canvas.Handle, 0, 0, oldW, oldH, SRCCOPY); Ich komme mit den weiteren Parametern bei
Delphi-Quellcode:
nicht klar. Gibt es dafür noch irgend eine Alternative?
GdipDrawImageRectRect
Gruß, Alex |
AW: Resample oder Resize mit GDI+
Du mußt graphics vorher neu erstellen
und dann kenn ich nur GdipDrawImageRectRectI :) Sample!
Delphi-Quellcode:
EDIT:
if GdipCreateFromHDC(hDCdest, Graphics) = 0 then
begin GdipCreateBitmapFromHBITMAP(hBM2, 0, Pointer(Img)); GdipSetInterpolationMode(Graphics, 2); GdipDrawImageRectRectI(Graphics, Img, xDest, yDest, xWidth, yHeight, 0, 0, xDiv, yDiv, 2, nil, False, nil); GdipDeleteGraphics(Graphics); GdipDisposeImage(Img); end; skDeleteObject(hBM2); DeleteDC(hDC2); Definition von GdipDrawImageRectRectI ist.. GdipDrawImageRectRectI Graphics, Img, 0, 0, newwidth, newheight, 0, 0, origwidth, origheight, UnitPixel gruss |
AW: Resample oder Resize mit GDI+
Daß Du hier nach Printer.BeginDoc
direkt auf auf das Printercanvas gehen kannst weißt Du schon, oder?
Delphi-Quellcode:
GdipCreateFromHDC(Printer.Canvas.Handle .....
|
AW: Resample oder Resize mit GDI+
@Schwedenbitter:
Auch wenn das Ganze schon uralt ist. Der oben abgebildete Source Code funktioniert so nur bedingt. Sobald die Ergebnis-Bitmap größer als die Ursprungs-Bitmap wird, bekommt man eine schöne Windows Exception präsentiert. Das liegt daran, dass die Routine GdipDrawImageRect nicht prüft, ob die Destination auch genügend Speicherplatz bietet. Eine möglich Lösung wäre: 1. Zuerst das Image GDI Objekt erstellen 2. Bitmap mit SetSize entsprechend der Ergebnisgröße setzen 3. Erst danach dipDrawImageRect(graphics, image, 0, 0, W, H) aufrufen! Gruß, Katte |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:57 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz