AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

[gelöst] TBitmap drehen

Ein Thema von Schwedenbitter · begonnen am 24. Nov 2014 · letzter Beitrag vom 24. Nov 2014
Antwort Antwort
Schwedenbitter

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

[gelöst] TBitmap drehen

  Alt 24. Nov 2014, 00: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 14:22 Uhr) Grund: Problem gelöst, Danke!
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#2

AW: TBitmap drehen

  Alt 24. Nov 2014, 07:39
Vielleicht ist die Schleife einfach komplett falsch (P wird falsch gesetzt und falsch erhöht => Copy&Paste Fehler):
Delphi-Quellcode:
 P := Memory;
 For J:=0 To Pred(H) Do // <- funktioniert leider nicht :-(
 Begin
   rowOut:=Bitmap.ScanLine[Pred(H) - J];
   For I:=Pred(W) Downto 0 Do
   Begin
     rowOut[I]:=p^.rgb;
     Inc(P);
   End;
 End;
Das sollte imho funktionieren (ungestestet)
  Mit Zitat antworten Zitat
Schwedenbitter

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

AW: TBitmap drehen

  Alt 24. Nov 2014, 14:21
Vielleicht ist die Schleife einfach komplett falsch (P wird falsch gesetzt und falsch erhöht => Copy&Paste Fehler)
...
Das sollte imho funktionieren (ungestestet)
Tausend Dank!
War also doch ein Denkfehler, weil P zeilenweise erhöht werden muss. Der (ungetestete) Code spiegelt das Ganze - sieht lustig aus und merke ich mir vor, falls ich es mal brauche! Aber wenn man dann noch den Zeilen-Zähler anpasst, passt es perfekt.
Delphi-Quellcode:
         rdUpturn   :   Begin
                        P:=Memory;                  // reset pointer
                        For J:=0 To Pred(H) Do
                        Begin
                           rowOut:=Bitmap.ScanLine[J];
                           For I:=Pred(W) Downto 0 Do
                           Begin
                              rowOut[I]:=p^.rgb;
                              Inc(P);
                           End;
                        End;
                     End;
Alex Winzer
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#4

AW: [gelöst] TBitmap drehen

  Alt 24. Nov 2014, 14:25
He he: stimmt (mit dem Spiegeln)...
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz