Hi Leute. Hab die Suche grade ne Stunde lang bemüht und hab tatsächlich was gefunden:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117:
| procedure RotateBitmapA(var Bitmap: TBitmap; const ADegrees: Cardinal; const clBack: TColor); const MaxPixelCount = 32768;
type pRGBArray = ^TRGBArray; TRGBArray = array [0..MaxPixelCount-1] of TRGBTriple;
var cosTheta : DOUBLE; i : INTEGER; iRotationAxis : INTEGER; iOriginal : INTEGER; iPrime : INTEGER; iPrimeRotated : INTEGER; j : INTEGER; jRotationAxis : INTEGER; jOriginal : INTEGER; jPrime : INTEGER; jPrimeRotated : INTEGER; RowOriginal : pRGBArray; RowRotated : pRGBArray; sinTheta : DOUBLE; Theta : DOUBLE; OldHeight : INTEGER; OldWidth : INTEGER; NewWidth : INTEGER; NewHeight : INTEGER; BitmapRotated : TBitmap; Back : RGBTriple; begin Back.rgbtBlue := GetBValue(clBack); Back.rgbtGreen := GetGValue(clBack); Back.rgbtRed := GetRValue(clBack);
Theta := ADegrees * PI /180; sinTheta := Sin(Theta); cosTheta := Cos(Theta);
OldWidth := Bitmap.Width; OldHeight := Bitmap.Height;
NewWidth := Abs(Round(OldHeight * sinTheta)) + Abs(Round(OldWidth * cosTheta)); NewHeight := Abs(Round(OldWidth * sinTheta)) + Abs(Round(OldHeight * cosTheta));
BitmapRotated := TBitmap.Create; BitmapRotated.Width := NewWidth; BitmapRotated.Height := NewHeight; BitmapRotated.PixelFormat := pf24bit; BitmapRotated.Canvas.Brush.Color := clBack; BitmapRotated.Canvas.FillRect(Rect(0, 0, NewWidth, NewHeight));
iRotationAxis := OldWidth div 2; jRotationAxis := OldHeight div 2;
for J := BitmapRotated.Height - 1 downto 0 do begin RowRotated := BitmapRotated.Scanline[J]; jPrime := 2*(J - (NewHeight - OldHeight) div 2 - jRotationAxis) + 1 ;
for I := NewWidth - 1 downto 0 do begin iPrime := 2*(I - (NewWidth - OldWidth) div 2 - iRotationAxis) + 1;
iPrimeRotated := Round(iPrime * CosTheta - jPrime * sinTheta); jPrimeRotated := Round(iPrime * sinTheta + jPrime * cosTheta);
iOriginal := (iPrimeRotated - 1) div 2 + iRotationAxis; jOriginal := (jPrimeRotated - 1) div 2 + jRotationAxis;
if (iOriginal >= 0) and (iOriginal <= Bitmap.Width - 1) and (jOriginal >= 0) and (jOriginal <= Bitmap.Height - 1) then begin RowOriginal := Bitmap.Scanline[jOriginal]; RowRotated[I] := RowOriginal[iOriginal] end end; end; Bitmap.Assign(BitmapRotated); BitmapRotated.Free; end; |
Na Klasse. Nach vielem Rumprobieren, bei dem ich des öfteren nur leere Images bekommen habe (Image1.Canvas.Draw(1,1,bit) wobei bit eine eigentlich gedrehte Bitmap ist), habe ich nun Folgendes getippselt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm1.Button1Click(Sender: TObject); var bit:TBitmap; begin bit:=TBitmap.Create; bit.LoadFromFile('C:\bildchen.bmp'); Rotatebitmapa(bit,50,clWhite); bit.SaveToFile('C:\bildchen.bmp'); bit.Free; end; |
klappt ganz gut, nur... das ergebnis. wenns am anfang sowas ist:
passiert das:
einmal drehen:
zweimal drehen:
10 mal drehen:
jayy.de/10mal.JPG(ist zu groß...)
Ihr seht: Die Bitmap wird größer und ganz grieselig. Was kann man da machen?? gibt es keinen Algorithmus, der mir ein Ergebnis liefert, das genauso groß ist wie das alte, und auch nach mehrmaligem Drehen gleich bleibt? gut, das mehrmalige drehen ließe sich umgehen in dem man immer von ursprünglichen Image ausgeht und eine andere gradzahl benutzt, anders wirds wohl eh nicht gehen.
Zusammenfassung: Was ich brauche: Eine kleine Spielfigur in einer Image komponente oder ähnlichem Drehen. Was nicht klappt: Figur wird griselig, und nicht auf dem Image angezeigt, Image wird leer.
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.