So. Ich habe mir jetzt mal ausgehend von
BUMMI's Änderungen am
Quellcode von EWeiss die Procedure nachgebaut.
Danke für die Tipps! Sie sieht jetzt so aus:
Delphi-Quellcode:
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;
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.
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:
StretchBlt(self.Canvas.Handle,
0, 0, W, H,
self.Canvas.Handle,
0, 0, oldW, oldH,
SRCCOPY);
die alte
und neue Größe angeben kann.
Ich komme mit den weiteren Parametern bei
GdipDrawImageRectRect
nicht klar. Gibt es dafür noch irgend eine Alternative?
Gruß, Alex