Einzelnen Beitrag anzeigen

Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#23

AW: Resample oder Resize mit GDI+

  Alt 2. Dez 2010, 17:53
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
Alex Winzer
  Mit Zitat antworten Zitat