Einzelnen Beitrag anzeigen

Schwedenbitter

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

[gelöst] TBitmap drehen

  Alt 23. Nov 2014, 23:09
Dieses Thema gibt es schon des öfteren hier und auch entsprechende ("langsamere") Lösungen. Allerdings soll das ganze in einem zeitkritischen Prozess ablaufen, weshalb ich nach vielfachen Tests bei diesem Code gelandet bin, der für mich schnell genug ist.

Ich möchte das ganze zu einer Funktion zusammenfassen. Aber irgendwie stelle ich mich bei der 180°-Drehung zu blöd an. Ich erhalte bei der Ausführung immer nur Datenmüll. Ich probiere jetzt schon eine Ewigkeit rum und finde meinen Fehler nicht:
Delphi-Quellcode:
// Rotiert das angegebene Bitmap in 90°-Schritten ------------------------------
Type
   TRotateDir   = (rdLeft = 0, rdRight, rdUpturn);

Procedure RotateBitmap(Const Bitmap: TBitmap;
   Const RotateDir: TRotateDir = rdLeft);
Type
   TRGBArray      = Array [0..0] Of TRGBTriple;
   pRGBArray      = ^TRGBArray;
   THelpRGB         = Packed Record
                        rgb         : TRGBTriple;
                        alpha         : Byte;
                    End;
Var
   oldPF         : TPixelFormat;
   header      : TBitmapInfo;
   dc            : hDC;
   P            :^THelpRGB;
   H, W         : Integer;
   I, J         : Integer;
   RowOut      : pRGBArray;
Begin
   oldPF:=Bitmap.PixelFormat;
   With TMemoryStream.Create Do
   Try
      SetSize(Bitmap.Height * Bitmap.Width * 4);
      Bitmap.PixelFormat:=pf24bit;
      With header.bmiHeader Do
      Begin
         biSize:= SizeOf(TBITMAPINFOHEADER);
         biWidth:= Bitmap.Width;
         biHeight:= Bitmap.Height;
         biPlanes:= 1;
         biBitCount:= 32;
         biCompression:= 0;
         biSizeimage:= Size;
         biXPelsPerMeter:=1;
         biYPelsPerMeter:=1;
         biClrUsed:= 0;
         biClrImportant:= 0;
      End;
      dc:=GetDC(0);
      P:=Memory;
      GetDIBits(dc, Bitmap.Handle, 0, Bitmap.Height, P, header, dib_RGB_Colors);
      ReleaseDC(0, dc);

      H:=Bitmap.Height;   W:=Bitmap.Width;            // Werte merken
      If (RotateDir <> rdUpturn) Then               // Falls kein 180° gewünscht
      Begin
         Bitmap.Width:= H;   Bitmap.Height:=W;         // um 90° drehen
      End;
      Case RotateDir of
         rdLeft   :   For J:=0 To Pred(W) Do
                     Begin
                        rowOut:=Bitmap.ScanLine[Pred(W) - J];
                        P:=Memory;                  // reset pointer
                        Inc(P, J);
                        For I:=Pred(H) Downto 0 Do
                        Begin
                           rowout[I]:=p^.rgb;
                           Inc(P, W);
                        End;
                     End;
         rdRight   :   For J:=0 To Pred(W) Do
                     Begin
                        rowOut:=Bitmap.ScanLine[J];
                        P:=Memory;                  // reset pointer
                        Inc(P, J);
                        For I:=0 To Pred(H) Do
                        Begin
                           rowout[I]:=p^.rgb;
                           Inc(P, W);
                        End;
                     End;
         rdUpturn   :   For J:=0 To Pred(H) Do   // <- funktioniert leider nicht :-(
                     Begin
                        rowOut:=Bitmap.ScanLine[Pred(H) - J];
                        P:=Memory;                  // reset pointer
                        Inc(P, J);
                        For I:=Pred(W) Downto 0 Do
                        Begin
                           rowOut[I]:=p^.rgb;
                           Inc(P, H);
                        End;
                     End;
      End;
   Finally
      Free;
   End;
   Bitmap.PixelFormat:=oldPF;
End;
Ich bin mir (fast) sicher, dass es nur eine Kleinigkeit ist. Nachdem ich aber jetzt schon 3h an der Sache tüfftle, sehe ich so langsam den Wald vor lauter Bäumen nicht mehr.

Wo liegt mein Fehler?
Alex Winzer

Geändert von Schwedenbitter (24. Nov 2014 um 13:22 Uhr) Grund: Problem gelöst, Danke!
  Mit Zitat antworten Zitat