2016-05-23 9 views
-2

Wie der Titel sagt, habe ich eine PictureBox mit einem GIF-Bild.Wie erkennt man den Zustand von GIF

Sagen wir, dass es 5 Bilder besteht. Wie kann ich das aktuelle Bild erkennen? Ich habe versucht, diesen Effekt zu erreichen, indem ich ein Array von Bildern benutze und es mit einem Timer durchlaufe, aber es sieht überhaupt nicht gut aus, also suche ich nach einer anderen Lösung.

+0

Ich weiß, Sie können festlegen, welche Rahmen Sie anzeigen möchten, und eine Liste aller Rahmen erhalten , aber ich glaube nicht, dass Sie feststellen können, welcher Frame tatsächlich angezeigt wird. Sie könnten das GIF in seine einzelnen Frames aufteilen und nacheinander anzeigen. Wenn Sie es so machen, können Sie den Frame selbst bestimmen. Wenn Sie das tun möchten, kann ich eine Antwort mit einem kleinen Beispiel geben. – gmiley

+0

Wie ich in meiner Frage erwähnt habe, habe ich das schon ausprobiert, aber wenn das die einzige Möglichkeit wäre, würde ich es trotzdem falsch machen. – PreqlSusSpermaOhranitel

+2

Das GIF innerhalb der PictureBox wird von einem privaten ImageAnimator-Objekt animiert PictureBox verwendet. Es ist privat. PictureBox ist nicht gerade Raketenwissenschaft, Sie können leicht Ihre eigenen erstellen, indem Sie von Control ableiten und einen Blick auf die Referenzquelle werfen, um zu wissen, was zu tun ist. Sie haben also Ihren eigenen ImageAnimator. –

Antwort

1

Es gibt wirklich keine einfache Möglichkeit, Ihren aktuellen Rahmen leider zu bestimmen.

Wahrscheinlich, von dem, was Sie in Ihrer Frage gesagt haben, haben Sie wahrscheinlich eine ähnliche Lösung. Es ist nicht schön, aber es sollte Ihnen im Grunde Zugriff geben, um festzustellen, welchen Frame Sie gerade anzeigen.

Dies kann ein wenig Debugging erfordern, aber es ist nur ein schnelles Mock-up. Es sollte vor allem wenn funktionieren, kann aber einen Thread oder Objektverweis Ausnahme auslösen, wenn Sie das Formular mit dem Bild Spiel verlassen:

public partial class frmGifPlayer : Form 
{ 
    List<Image> images = new List<Image>(); 
    int imageIdx = 0; 
    bool playing = false; 
    public frmGifPlayer() 
    { 
     InitializeComponent(); 
    } 

    private void btnLoadGIF_Click(object sender, EventArgs e) 
    { 
     OpenFileDialog file = new OpenFileDialog(); 
     if (file.ShowDialog(this) != System.Windows.Forms.DialogResult.OK) 
     { 
      return; 
     } 
     Image img = Image.FromFile(file.FileName); 

     lock (images) 
     { 
      // Load your images into a List<Image> collection... 
      images.Clear(); 
      for (int i = 0; i < img.GetFrameCount(System.Drawing.Imaging.FrameDimension.Time); i++) 
      { 
       img.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Time, i); 
       images.Add(new Bitmap(img)); 
      } 
     } 


    } 

    private void PlayImages(List<Image> images) 
    { 
     // Cycle through the images in a thread... 
     ThreadPool.QueueUserWorkItem(new WaitCallback((o) => 
      { 
       List<Image> img = (List<Image>)o; 
       int curIdx = 0; 
       do 
       { 
        lock (images) 
        { 
         // Update your variables then callback to the form to change the image. 
         imageIdx = curIdx; 
         pbGif.Image = img[imageIdx]; 
         Invoke(new Action(() => 
         { 
          txtCurFrame.Text = imageIdx.ToString(); 
         })); 
         curIdx++; 
         if (curIdx >= img.Count) 
          curIdx = 0; 
        } 
        Thread.Sleep(TimeSpan.FromSeconds(.5)); 
       } while (playing); 
      }), images); 
    } 


    private void btnStartStop_Click(object sender, EventArgs e) 
    { 
     lock (images) 
     { 
      playing = !playing; 
     } 
     if (playing) 
     { 
      btnStartStop.Text = "Stop"; 
      PlayImages(images); 
     } 
     else 
      btnStartStop.Text = "Start"; 
    } 
} 
+0

Danke für die Antwort genau was ich wollte, nur eine Frage wie kann ich die gesperrten 'images' freigeben oder den laufenden Thread abbrechen? – PreqlSusSpermaOhranitel

+0

Nun, da der Thread als Hintergrund-Worker gestartet wird, wird "loop" im Thread abgebrochen und zurückgegeben, sobald "playing" auf "false" gesetzt ist. Der Thread wird sich selbst entsorgen. Setzen Sie die Variable einfach auf false und lassen Sie sie sich selbst beenden. – gmiley

+0

Ich habe derzeit die 'lock'-Anweisung in einen' try/catch'-Block gehüllt, weil manchmal, wenn ich den Knopf zu schnell drücke, die Ausnahme ausgelöst wird, dass das Objekt woanders verwendet wird, in diesem Fall 'return'. Gibt es dafür eine bessere Lösung? – PreqlSusSpermaOhranitel

Verwandte Themen