Entwickler-Ecke

Open Source Units - BMP (Bitmap) Animator


Tropby - Di 02.06.09 23:51
Titel: BMP (Bitmap) Animator
Der BMP (Bitmap) Animator

Aktuelle Version : 0.3

Da häufig mal verlangt wurde, dass es kleine Animationen in Programmen geben sollte und ich da keine Lust hatte mir immer was neues einfallen zu lassen habe ich diese Unit geschrieben.


Diese Unit ist im Stande ein Format, ich habe es jetzt mal ".anibmp" genannt, einzulesen und die Bilddaten zu animieren. In dieser Version der Unit fehlen noch ein paar Fehlerabfragen jedoch ist sie so schon in einigen Programmen getestet. Da die Zeitberechnung der Animation in einen Thread ausgelagert ist und die Callback-Funktion nur einen Pointer zu den Bilddaten bekommt, ist die Animation, wenn man sie noch mit Suche in der Entwickler-Ecke BITBLT benutzt, auch bei schnellen Animationen flüssig. Wie das ganze aussieht wenn viele Animationen zur gleichen Zeit laufen habe ich noch nicht getestet.


Mit einem beiligendem Tool namens "BMP Animator.exe" können diese ".anibmp"-Dateien erstellt werden. Als Ausgangsbasis dienen hierbei normale Bitmaps. Der "BMP Animator" kann auch die erstellten Dateien sofort abspielen um zu sehen ob Fehler aufgetreten sind.


Die Klasse kann:
  1. Animationen abspielen
  2. Animationen pausieren
  3. Animationen rückwärtsablaufen lassen


Funktions-Beschreibungen

Constructor:

Delphi-Quelltext
1:
constructor TAniBMP.Create(); Overload;                    

Dies sind die Constructor der TAniBMP-Class.

Animation Laden:

Delphi-Quelltext
1:
2:
procedure TAniBMP.LoadFromFile(const Filename : String);
procedure TAniBMP.LoadFromStream(const Stream : TStream);

Hiermit kann die Animation die das Objekt machen soll geändert werden.

Einen Frame Extrahieren:

Delphi-Quelltext
1:
function TAniBMP.GetFrame(FrameID : Integer; var bmp : TBitmap) : Integer;                    

Wenn die Funktion erfolgreich ist liefert sie 0 zurück und bmp ist mit dem angegeben Frame gefüllt.

Animation starten:

Delphi-Quelltext
1:
function TAniBMP.start(CallbackID : Integer = 0) : Boolean;                    

Startet die Animation mit der angegeben CallbackID.

Animation stoppen:

Delphi-Quelltext
1:
procedure TAniBMP.stop(CallbackID : Integer = 0);                    

Stoppt die Animation mit der angegeben CallbackID.


Animation stoppen:

Delphi-Quelltext
1:
2:
procedure TAniBMP.pause(Pause : Boolean; CallbackID : Integer = 0);
function TAniBMP.IstPausiert(CallbackID : Integer = 0) : Boolean;

Pausiert eine Animation.


Eigenschafts-Beschreibungen


Delphi-Quelltext
1:
TAniBMP.OnAnimate = procedure(ID : Integer; P: Pointer);                    

OnAnimate wird für jedes Frame aufgerufen.




Delphi-Quelltext
1:
TAniBMP.Interval : Integer;                    

Zeit in Millisekunden in denen die Frames geredert werden sollen.



Delphi-Quelltext
1:
TAniBMP.StartFrame : Integer;                    

Das erste Frame, des zu der Animation gehört.



Delphi-Quelltext
1:
TAniBMP.EndFrame : Integer;                    

Das letzte Frame, des zu der Animation gehört.



Delphi-Quelltext
1:
TAniBMP.AnzFrames : Integer; (readonly)                    

Anzahl der Frames, die die Animation besitzt.



Delphi-Quelltext
1:
TAniBMP.Backward : Boolean;                    

Soll die Animation vorwärts oder rückwärts abgespielt werden?
TRUE = Rückwärts



Delphi-Quelltext
1:
TAniBMP.Exceptions : Boolean;                    

Sollen Execptions ausgegeben werden.



Delphi-Quelltext
1:
TAniBMP.LastError : String;                    

Last Error beinhaltet die letzte Errornachricht.
Ist ganz nützlich wenn Exceptions ausgeschaltet sind.


Changelog:

Version 0.3



Version 0.2



Ich habe die Unit gestestet und zur Zeit keine Fehler gefunden (Rechtschreibfehler ausgenommen).
Trotzdem kann ich nicht garantieren, dass es Fehler gibt und es zu Datenverlust führen kann :P


Tropby - Do 04.06.09 16:56

Hallo,
ich habe die Klasse nochmal komplett überarbeitet, wie in DP [http://www.delphipraxis.net/post1044243.html#1044243] vorgeschlagen, und noch ein paar schöne kleine Funktionen hinzugefügt.


Sinspin - Do 04.06.09 19:03

Warum verwendest du in der Callback Procedure einen Pointer aus das Bitmap? Eine Object Referenz ist doch nichts anderes, nur schöner. Das wäre ja der Hammer wenn bei einem Procedure Aufruf das gesammte Object kopiert werden würde. Und das der Hammer wäre ist es nicht so. Es wird lediglich der Zeiger auf das Object übergeben.

Ich muss sagen das es ganz schön fix geht und die CPU nicht quählt. Schaut von daher also schonmal ganz gut aus.
Was ich aber noch etwas änderungsbedürftig finde ist das Bildformat. Könntest du da nicht auf PNG wechseln? Oder zumindest verschiedene Formate zulassen?
Eine interne ZIP Komression der Animationsdatei (RLE ginge zur not auch noch) wäre aber schonmal ein guter Anfang. So wie es jetzt ist, ist es ganz schöne Speicherverschwendung.
Im RAM wäre es zwar trotzdem unkomprimiert, aber selbst dort ließe sich noch was machen wenn man es auf die Spitze treiben will.

Kritik? Ja, der beste Beweis dafür das ich mich dafür interessiere.


Tropby - Do 04.06.09 19:12

Bei dem Pointer weiß ich selber nicht mehr warum ich das gemacht hatte :shock: ist mir garnicht mehr so aufgefallen das ich da einen wirklichen Pointer benutzt hatte.

An der Kompremierung arbeite ich zur Zeit noch. Da werde ich aber wohl noch etwas länger dran sitzten... Das will einfach noch nicht so ganz^^

Andere Formate werde ich mir auch mal ansehen.


Ich finde es aber schön, dass sich jemand dafür intressiert :wink: