Grafik rotieren in TImage
-
Ich hab' in 'ner Komponente zur Anzeige von Graphiken (enthaelt ein TImage) Animationen programmiert. Eine Art ist, ueber das alte Bild beim Laden eines neuen Bildes dieses schrittweise gedreht darueberzukopieren.
void __fastcall TripleRotate(const TPoint Points[], TPoint ResPoints[], int Fix, float Angle); void __fastcall TripleRotate(const TPoint Points[], TPoint ResPoints[], int Fix, float Angle) { for (int i=0;i<4;i++) { if (i!=Fix) { ResPoints[i].x=Points[Fix].x + (Points[i].x - Points[Fix].x) * cos(Angle) + (Points[i].y - Points[Fix].y) * sin(Angle); ResPoints[i].y=Points[Fix].y + (Points[i].y - Points[Fix].y) * cos(Angle) - (Points[i].x - Points[Fix].x) * sin(Angle); } else { ResPoints[i].x=Points[Fix].x; ResPoints[i].y=Points[Fix].y; } } } void __fastcall TImageZoomScrollBoxAni::AniRotate(TImage *AniImg, Graphics::TBitmap *BM_New, int Mode, int Step) { float Angle; float DAngle; int Res; TPoint Points[4],TempPoints[4]; Points[0].x=0; //LiOb Points[0].y=0; Points[1].x=BM_New->Width; //ReOb Points[1].y=0; Points[2].x=0; //LiUn Points[2].y=BM_New->Height; //Nur intern verwendet!!! Points[3].x=BM_New->Width; //ReUn Points[3].y=BM_New->Height; if (Mode<0) Angle=Pi / 2; else Angle=-Pi / 2; DAngle=-Angle / Step; for (;(Angle*DAngle)<0;Angle+=DAngle) { TripleRotate(Points,TempPoints,abs(Mode)-1,Angle); Res=PlgBlt( AniImg->Canvas->Handle,// handle to destination device context TempPoints, // vertices of destination parallelogram BM_New->Canvas->Handle,// handle to source device context 0, // x-coord. of upper-left corner of source rect. 0, // y-coord. of upper-left corner of source rect. BM_New->Width,// width of source rectangle BM_New->Height,// height of source rectangle NULL, // handle to bitmask 0, // x-coord. of upper-left corner of bitmask rect. 0 // y-coord. of upper-left corner of bitmask rect. ); AniImg->Refresh(); } }
AniImg = zu aenderndes TImage
BM_New = gleichgrosses Bitmap mit neuem Bild
Mode -4 .. -1; 1 .. 4 legt fest, ueber welche Ecke das Bild 'reingedreht wird
Step = Anzahl Winkelschritte fuer 90°- DrehungTripleRotate(..) berechnet Punkte gedreht fuer Kopierfunktion.
Das ganze geht mit PlgBlt etwas langsam!!! Besonders bei bildschirmfuellenden Bildern.
Kennt einer 'ne schnellere Methode zum Zeichnen?
PS: mit Pixels und Scanlines geht's noch viel langsamer!
-
Ähmm ... off-screen zeichnen und das Ergebniss auf die Ausgabefläche kopieren?
Ansonsten ist das wohl eher ein Fall für DirectDraw o.ä.
-
Bei Powerpoint gibts ja auch Animationen, dort wird aber nicht jede Pixelbewegung stur nachgezeichnet, sondern ggf. x-Bewegungsschritte übersprungen.
Um die Bewegungs-Schrittweite (oder bei Dir den "Step") zu ermitteln, der auf dem PC möglich ist (bzw. in Abhängigkeit der darzustellenen Grafik), müßtest Du die Zeit messen, die beim ersten Durchlauf benötigt wird und diese Zeit in Relation zur Gesamtdauer der Animation setzen.
Ähnliches kennt man ja auch z.B. bei MPEG2 Playern. Im Zweifel überspringt der Player halt ein paar Bilder, aber das Bild bleibt synchron zum Ton.
-
JFK schrieb:
Bei Powerpoint gibts ja auch Animationen, dort wird aber nicht jede Pixelbewegung stur nachgezeichnet, sondern ggf. x-Bewegungsschritte übersprungen.
Seh ich auch so ...
-
Danke erstmal fuer Eure Tips.
Offscreen bringt nicht sehr viel (hab' ich schon probiert!). Das Zeit- Problem kommt aus der Berechnung der Drehung selbst - geht in Offscreen- Bitmap unwesentlich schneller als direkt in's Image. Kennst Du ein gutes Tut zu DirectDraw - damit hab' ich noch nix gemacht. Was brauch ich, um DirectDraw zu nutzen? - hab' nur BCB 4.0.
@JFK:
Das mit Bildern weg lassen geht schlecht. Ich kann so schon nur 5 - 10 Schritte pro 90° Rotation berechnen lassen, sonst braucht der zu lange (mein PC hat nur 1.7 GHz und 'ne 'lausige Standardgrafikkarte - is'n Laptop). Synchron zu Sound muss der nicht sein - noch nicht!
Da werd ich wohl doch mal nach DirectDraw sehen muessen.
Trotzdem Dank an Euch.
-
DerAltenburger schrieb:
Was brauch ich, um DirectDraw zu nutzen? - hab' nur BCB 4.0.
ddraw.h? Zumindest seit BCB5 gibt's im \examples-Verzeichnis ein paar DDraw-Beispiele.
-
Danke fuer den Tip.
ddraw.h ist auch im BCB 4.0 da! Da<hat's auch Beispiele. Das werd ich mal probieren!
Thx
DerAltenburger
-
Die Speibiele von Borland sind echt Sch*****!!! Sinnlose Bildschirmeffekte, Abstuerze ...
Hab' mir mal die Komponenten von Wischik vorgenommen. Die Demos funktionieren sauber!
Aber das Ganze nuetzt nicht viel! Das Darstellen von Bildern in TImage geht (im Moment) schnell genug. Das Problem ist nur die Berechnung der Rotation mit PlgBlt(). 20 Schritte barucht's als Minimum fuer Ruckelfreien Ablauf. Da braucht's aber ca. 2 sec fuer die Berechnung - selbst wenn nichts angezeigt wird(nur in Offscreen- Bitmap rotiert). Fuer die gedrehte Darstellung kann ich aber in DDraw nichts finden, muss also bei PlgBlt() bleiben.
Kennt nicht einer 'ne schnellere Berechnung fuer die Rotation von Bitmaps?
-
Oder Du berechnest alle Bilder vor und zeigst sie dann nacheinander an.
-
So, bin wieder da. Hatte die Woche kein Internet im Aussendienst.
@F98:
Das werd' ich wohl so machen muessen. Bilder berechnen, in Stream schreiben und dann schnell aus Stream laden / anzeigen. Ist nur 'n Problem mit dem Speicherplatz!
F 'fluessige, fliessende' Anzeige der Rotation braucht's mindestens 20 - 30 Bilder. Alle Bildschirmfuellend - 1024 - 1280 Pixel breit! (3 - 4 MB pro Bild, 200 -400 kB als JPEG).
Das ist mir etwas viel fuer TMemStream, und auf FileStream roedelt die HD sich zu Tode!.
Ich werd' das mit TMemStream 'mal testen!
Trotzdem Danke
DerAltenburger