![]() |
[gelöst] TBitmap drehen
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
![]() 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:
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.
// 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; Wo liegt mein Fehler? |
AW: TBitmap drehen
Vielleicht ist die Schleife einfach komplett falsch (P wird falsch gesetzt und falsch erhöht => Copy&Paste Fehler):
Delphi-Quellcode:
Das sollte imho funktionieren (ungestestet)
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; |
AW: TBitmap drehen
Zitat:
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:
:dp:
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; |
AW: [gelöst] TBitmap drehen
He he: stimmt (mit dem Spiegeln)...
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:05 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 by Thomas Breitkreuz