2016-05-23 8 views
-2

タイトルには、PictureBoxのGIF画像があります。GIFの状態を検出する方法

5枚の画像で構成されているとします。表示されている現在のイメージをどのように検出できますか?私は画像の配列を使用してこの効果を達成しようとしたが、タイマーを使用してiteratingしかし、それはまったくよく見えないので、私は別の解決策を探しています。

+0

私はあなたが表示したいフレームを指定し、すべてのフレームのリストを取得することができます知っていますしかし、どのフレームが実際に表示されているのかを判断することはできません。 gifを個々のフレームに分割し、それぞれを順番に表示することができます。そのようにすると、フレームを自分で追跡してフレームを判断できます。あなたがそれをしたいのであれば、私は小さな例で答えを出すことができます。 – gmiley

+0

私が私の質問で言及したように、私はすでにそれを試みましたが、あなたの実装を見たいと思う唯一の方法なら、間違っていたかもしれません。 – PreqlSusSpermaOhranitel

+2

PictureBox内のGIFはprivate ImageAnimatorオブジェクトPictureBoxが使用する。私的です。 PictureBoxは正確にはロケット科学ではありません。コントロールから派生して、参照元を覗いて何をすべきかを知ることで、自分で簡単に作成することができます。だからあなたはあなた自身のImageAnimatorを持っています。 –

答えて

1

残念ながら現在のフレームを確認する簡単な方法はありません。

おそらくあなたの質問で言ったことから、あなたはおそらくこのような解決策を持っています。これはきわめて簡単なことではありませんが、基本的には、現在表示しているフレームを判断するためのアクセス権が必要です。

これは少しデバッグが必要な場合がありますが、簡単なモックアップです。これは、主にかかわらず動作するはずですが、あなたは、画像の再生にフォームを終了すると、スレッドやオブジェクトの参照例外をスローすることがあります。

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

私は欲しかった答えをありがとう、ちょうど1つの質問は、私はロックされた '画像'をリリースするか、そこに実行されているスレッドを中止することができますか? – PreqlSusSpermaOhranitel

+0

さて、スレッドはバックグラウンドワーカーとして開始されるので、 'playing'が' false'に設定されると、スレッドのループが途絶えて戻ります。スレッドはそれ自身を処理します。変数をfalseに設定して、それを終了させて​​ください。 – gmiley

+0

私は現在、 'try/catch'ブロックに' lock'ステートメントをラップしています。なぜなら、ボタンを押しすぎるとオブジェクトが別の場所で使用されているという例外がスローされることがあるからです。これにはもっと良い解決策がありますか? – PreqlSusSpermaOhranitel

関連する問題