Komponente für animierte GIFs gesucht

Rund um die LCL und andere Komponenten
Antworten
MitjaStachowiak
Lazarusforum e. V.
Beiträge: 395
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

Komponente für animierte GIFs gesucht

Beitrag von MitjaStachowiak »

Hallo,
ich bin auf der Suche nach einer Komponente, die animierte GIFs laden (öffnen; speichern muss nicht sein) kann, sodass ich im Speicher Zugriff auf die einzelnen Bilder und deren Timeout habe. Die Schwierigkeit: Das ganze soll in einer DLL funktionieren.
BGRABitmap etwa enthält die Unit bgraanimatedgif.pas, die schon mal sehr vielversprechend aussieht, aber wegen "uses Graphics" kann ich das nicht in 'ne DLL packen. Ich habe schon versucht, Graphics für die DLL fertig zu machen, in der Hoffnung, das liefe dann problemlos, aber irgendwo komme ich dann immer nicht weiter.

Am Ende sollen die einzelnen Bilder in Texturen für DirectX umgewandelt werden. Ich versuche also eine animierte Textur zu rendern... Bin mal gespannt, ob das klappt.
Also falls jemand weitere Units kennt, die mir da weiter helfen könnten, oder so was schon mal gemacht hat, würde ich mich freuen.

Benutzeravatar
theo
Beiträge: 10904
Registriert: Mo 11. Sep 2006, 19:01

Re: Komponente für animierte GIFs gesucht

Beitrag von theo »

Der GIF Reader im OpBitmap Paket kann das im Prinzip, und hat keine LCL Abhängigkeit.
http://www.theo.ch/lazarus/opbitmap64.zip" onclick="window.open(this.href);return false;

Hier gibt's noch Infos, was das Auslesen der spezifischen Daten betrifft:
http://www.lazarusforum.de/viewtopic.php?p=4850#p4850" onclick="window.open(this.href);return false;

Musste halt selber zusammenflicken.

MitjaStachowiak
Lazarusforum e. V.
Beiträge: 395
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

Re: Komponente für animierte GIFs gesucht

Beitrag von MitjaStachowiak »

Vielen Dank, für Deine Antwort.
Ich habe etwas getüftelt und folgenden Code zustande gebracht:

Code: Alles auswählen

uses
 direct3d9, d3dx9, gifdecoder, opbitmap, opbitmapformats;
 
var
 gif    : TGifDecoder;
 bmp    : TBMPImage;
 str    : TMemoryStream;
 
[...]
 
  gif := TGifDecoder.Create;
  bmp := TBMPImage.Create;
  str := TMemoryStream.Create;
 
  gif.readImageFile(FileName,bmp);
  bmp.SaveToStream(str);
  D3DXCreateTextureFromFileInMemory(D3DDev9,str.Memory,str.Size,Textures[0].Pic);
  Textures[0].Duration := 100;
 
  str.Free;
  bmp.Free;
  gif.Free;
Damit kann ich das erste Bild aus der Datei in meine Animation laden. Diese funktioniert schon (habe ich mit mehreren Dateien getestet). Wie man aber alle Bilder aus einer Gif-Datei laden kann, habe ich noch nicht verstanden. Ich dachte, dafür sei readNextImage da, aber wenn ich das verwende, bekomme ich einen Fehler (Exception Class >>EXTERNAL: SIGSEGV<<)...
Ich habe dafür extra ein "frisches" TBMPImage genommen, um sicher zu gehen.
Was mache ich falsch?

Benutzeravatar
theo
Beiträge: 10904
Registriert: Mo 11. Sep 2006, 19:01

Re: Komponente für animierte GIFs gesucht

Beitrag von theo »

Was da in deinem 3D3X passiert, weiss ich auch nicht, aber folgender Code funzt bei mir, um ein AniGif in mehrere Windows Bitmaps zu speichern.

Code: Alles auswählen

uses gifdecoder, gif, opbitmapformats;                                                           
 
procedure TForm1.Button1Click(Sender: TObject);
const BasePath='/home/theo/lazarus/';
FileName=BasePath+'ATT00005.gif';
var bm:TBMPImage;
 gif: TGifDecoder;
 Image:TBMPImage;
 fDisposalMethod: integer;
 count:integer;
begin
  try
      count:=0;
      Image := TBMPImage.Create;
      gif := TGifDecoder.Create;
      gif.Verbose := false;
      gif.MultiImageMode := true;
      gif.Reset; ;
      gif.ReadImageFile(FileName, image);
      while gif.moreImages and gif.MultiImageMode  do
      begin
        gif.readNextImage(image);
        fDisposalMethod := DisposalMethod(gif.GraphicCtrlBlock);
        image.SaveToFile(BasePath+inttostr(count)+'.bmp');
        inc(count);
      end;
  finally
    image.Destroy;
    gif.Destroy;
  end;
end;

MitjaStachowiak
Lazarusforum e. V.
Beiträge: 395
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

Re: Komponente für animierte GIFs gesucht

Beitrag von MitjaStachowiak »

Ah, dieser Code ist echt Gold wert :mrgreen:
Ich habe es jetzt so geschafft:

Code: Alles auswählen

gif := TGifDecoder.Create;
  gif.Verbose := false;
  gif.MultiImageMode := true;
  gif.Reset;
  bmp := TBMPImage.Create;
  str := TMemoryStream.Create;
 
  SetLength(Textures,1);
  gif.readImageFile(FileName,bmp);
  bmp.SaveToStream(str);
  D3DXCreateTextureFromFileInMemory(D3DDev9,str.Memory,str.Size,Textures[0].Pic);
  Textures[0].Duration := gif.GraphicCtrlBlock.delay_time * 10;
  while (gif.MoreImages) and (gif.MultiImageMode) do begin
   i := Length(Textures);
   SetLength(Textures,i+1);
   gif.readNextImage(bmp);
   bmp.SaveToStream(str);
   D3DXCreateTextureFromFileInMemory(D3DDev9,str.Memory,str.Size,Textures[i].Pic);
   Textures[i].Duration := gif.GraphicCtrlBlock.delay_time * 10;
  end;
 
  str.Free;
  bmp.Free;
  gif.Free;
Ich habe gesehen, dass es in D3DXCreateTextureFromFileInMemoryEx auch eine Einstellung für TransparentColor gibt. Mit den richtigen Render-Flags wird es damit dann wohl noch Transparent. Für mich reicht es aber erstmal so.
Vielen Dank für die Hilfe.

[Edit:]
Der Umweg mit dem MemoryStream ist nicht unbedingt der schnellste. Es ist akzeptabel, aber wenn jemand noch einen schnelleren Weg findet, würde ich mich freuen, davon zu hören 8)

Benutzeravatar
theo
Beiträge: 10904
Registriert: Mo 11. Sep 2006, 19:01

Re: Komponente für animierte GIFs gesucht

Beitrag von theo »

MitjaStachowiak hat geschrieben: Der Umweg mit dem MemoryStream ist nicht unbedingt der schnellste. Es ist akzeptabel, aber wenn jemand noch einen schnelleren Weg findet, würde ich mich freuen, davon zu hören 8)
Das hängt davon ab, welche Varianten von D3DXCreateTextureXXX es noch gibt.
Das Memory-Format von OPBitmap ist recht kompatibel, d.h. oft kann man einen Zeiger darauf an ein Toolkit übergeben.
Aber wenn Windows BMP gefragt ist, muss man streamen.

Antworten