Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Animierte gif in Stringgridzelle (https://www.delphipraxis.net/193573-animierte-gif-stringgridzelle.html)

Danny92 16. Aug 2017 15:04

Animierte gif in Stringgridzelle
 
Ich möchte eine animierte GIF in eine StringGrid-Zelle laden.
Das Laden an sich hab ich mit Image1.Picture.Graphic schon hinbekommen. Auch die Transparenz in Image1 ist da.
Aber wenn ich das im OnDrawCell-Ereignis des StringGrids1 mit StringGrid1.Canvas.Draw(Rect.Left, Rect.Top, Image1.Picture.Graphic) einfüge,
ist die GIF im Standbild, statt animiert, außerdem ist es in den Zellen nicht mehr transparent. Also in Image1 ist es animiert und transparent, aber in den einzelnen Zellen weder noch..

Delphi-Quellcode:
procedure TForm1.FormClick(Sender: TObject);
var
  GIFimg: TGIFImage;
begin
  GIFImageDefaultAnimate := True;
  GIFimg:= TGIFImage.Create;
  gifimg.AnimationSpeed:=1000;
  try
    GIFimg.LoadFromFile('C:\Users\Danny\Google Drive\Schiffe versenken\sound\explosion.gif');
    Image1.Picture.Assign(GIFimg);
  finally
    GIFimg.Free;
  end;
  (Image1.Picture.Graphic as TGIFImage).Animate := True;
  //feldplayer.Repaint;
  FeldPlayer.Repaint;
end;
Delphi-Quellcode:
procedure TForm1.FeldPlayerDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
   (Image1.Picture.Graphic as TGIFImage).Animate := True;
  FeldPlayer.Canvas.Draw(Rect.Left,Rect.Top,Image1.Picture.Graphic);
  (Image1.Picture.Graphic as TGIFImage).Animate := True;
  //FeldPlayer.Canvas.StretchDraw(Rect,Image1.Picture.Bitmap);
end;
Weiß da jemand schnell Abhilfe, wie sich das (schnell & einfach) realisieren lässt? Danke!

Blup 16. Aug 2017 16:10

AW: Animierte gif in Stringgridzelle
 
Zitat:

Zitat von Danny92 (Beitrag 1378859)
Weiß da jemand schnell Abhilfe, wie sich das (schnell & einfach) realisieren lässt? Danke!

Nein, schnell und einfach geht das nicht.

Für die Transparenz musst du den kompletten Zelleninhalt selbst zeichnen.
1. Hintergrund (z.B. weiß)
2. eine Bild des Gif in der jeweils gültigen Animationsphase
3. Den Zelleninhalt (in der Regel Text)

Um die Animation darzustellen wird ein Timer benötigt und die Information, welche Animationsphase als nächstes zu zeichnen ist.
Im OnTimer können alle Zellenbereiche, in denen eine Animation dargestellt wird, mit InvalidateRect der Region zum Neuzeichnen hinzugefügt werden.
Das OnPaint-Ereignis wird danach automatisch durch Windows ausgelöst.

Danny92 16. Aug 2017 16:49

AW: Animierte gif in Stringgridzelle
 
Geht das auch einfacher?
Zum Beispiel das Image1 vor dem StringGrid1 stehen zu lassen?

Geht das mit einem DrawGrid einfacher?
Oder auch eine Idee wäre, das Image im Vordergrund zu haben, über dem StringGrid an irgendeiner Stelle. Geht das einfacher? Wie soll ich denn sonst die gif in ihre einzelnen Bilder aufdröseln? im Timer1-Intervall-Ereignis hab ich Image1.Picture.Assign(gifimg.Images[2]) schon versucht...

Blup 18. Aug 2017 10:43

AW: Animierte gif in Stringgridzelle
 
TImage ist eine sichtbare Komponente und dient als Container für eine beliebige darzustellende Grafik.
Wenn diese Funktionalität aber nicht benötigt wird, ist es sinnvoller direkt das TGifImage zu benutzen.

So könnte ich mir das vorstellen, vereinfacht, ungetestet:
Delphi-Quellcode:
TForm1 = class(TForm)
{...}
  procedure FormCreate(Sender: TObject);
  procedure FormDestroy(Sender: TObject);
  procedure DoTimer(Sender: TObject);
private
  FImgExplosion: TGifImage;
  FImgExplosionIndex: Cardinal;
  procedure DrawCellText(ACanvas: TCanvas; ARect: TRect; AText: String);
end;

implementation

procedure TForm1.FormCreate(Sender: TObject);
begin
  FImgExplosion := TGIFImage.Create;
  FImgExplosion.LoadFromFile('C:\Users\Danny\Google Drive\Schiffe versenken\sound\explosion.gif');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FImgExplosion.Free;
end;

procedure TForm1.DoTimer(Sender: TObject);
begin
  Inc(FImgExplosionIndex);
  if FImgExplosionIndex >= FImgExplosion.Images.Count then
    FImgExplosionIndex := 0;

  FeldPlayer.Invalidate; // ToDo: nur Bereiche die neu zu zeichnen sind - InvalidateRect
end;

procedure TForm1.DrawCellText(ACanvas: TCanvas; ARect: TRect; AText: String);
var
  X, Y: Integer;
begin
  {links ausgerichtet}
  X := ARect.Left + ACanvas.TextWidth(' ');
  {vertikal zentriert}
  Y := (ARect.Top + ARect.Bottom - ACanvas.TextHeight(AText)) div 2;
  ACanvas.TextRect(ARect, X + 1, Y + 1, AText);
end;

procedure TForm1.FeldPlayerDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  {Hintergrund}
  FeldPlayer.Canvas.FillRect(Rect);
  {Text}
  DrawCellText(FeldPlayer.Canvas, ARect, FeldPlayer.Cells[ACol, ARow]);
  {Animation}
  if FImgExplosionIndex < FImgExplosion.Images.Count then
    FImgExplosion.Images[FImgExplosionIndex].Draw(FeldPlayer.Canvas, Rect, True, True);
end;
TDrawGrid ist TStringGrid vorzuziehen wenn man entweder keine Text anzuzeigen hat oder der Text z.B. in DatenObjekten gespeichert ist und das Grid nur die Anzeige und Bearbeitung übernimmt.

Danny92 18. Aug 2017 10:48

AW: Animierte gif in Stringgridzelle
 
Ja das sieht schon ganz gut aus. Nur das Problem ist: ich will die Datei, die GIF, nicht von der Platte laden müssen. Am Ende darf nur noch die Hauptanwendung übrig bleiben. Das heißt ich hab die Datei in der Resource schon eingebunden. Aber so ähnlich mit einem Timer und dann alle paar Millisekunden ins StringGrid reinladen - so hab ich das auch gelöst. Es ging ja nicht anders. Danke!

Blup 18. Aug 2017 13:10

AW: Animierte gif in Stringgridzelle
 
Das ist schon wieder ein ganz anderes Problem. Dafür könnte man z.B. eine Resourcedatei erstellen, ins Projekt einbinden und die Grafiken mit LoadFromResource laden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:29 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz