Windowsフォーム(c#)でアニメーションGIFを表示する方法


142

かなり長いプロセスの実行中に進行状況メッセージを表示するフォームがあります。これはWebサービスの呼び出しなので、進行状況バーに完全なパーセンテージを意味のある形で実際に表示することはできません。(プログレスバーのマーキープロパティは特に好きではありません)

アニメーションGIFを表示して、プロセスにアクティビティの感触を与えたいと思います(たとえば、Windowsコピープロセスのように、あるコンピューターから別のコンピューターにファイルが飛んでいる)。

これどうやってやるの?


アニメーション画像の場合、このコントローラーを使用できます。codeproject.com/Tips/1004624/Gif-viewer-Snipper-control
xwpedram

回答:


249

難しいことではありません。

  1. 画像ボックスをフォームにドロップします。
  2. .gifファイルを画像として画像ボックスに追加します。
  3. ロードするときにピクチャーボックスを表示します。

考慮すべき事項:

  • ピクチャボックスを無効にすると、gifがアニメーション化されなくなります。

アニメーションGIF:

アニメーションGIFを探している場合は、生成することができます。

AjaxLoad-Ajax Loading gifジェネレーター

それを行う別の方法:

私が見つけたもう1つの方法は、コードプロジェクトで見つけた非同期ダイアログコントロールです。


5
恥ずかしいほど簡単!私の最初の「グーグル」はこれを示しませんでした-多分それはあまりにも明白です。ありがとう。
スチュアートヘルヴィヒ2008年

1
ただし、画像ボックスは、プロセスの実行中に更新(再描画)されません。
LarryBud、2015年

ダラー、誤って背景画像に設定してしまいました。背景画像は、当然、アニメーションをサポートしていません。前景画像にはあります。
neminem

@neminem:ここも同じです!それが私がここにいる理由です。しばらく、pictureBoxはfox gifをサポートしていないと思っていました(初めて使用したとき)
Jack

@LarryBudプロセスの実行中に更新(再描画)させるには、を呼び出しますApplication.DoEvents();。可能なアプローチ:何かが部分的に行われたときにビジネスロジックがイベントを発生させ、Application.DoEvents()を使用してプロパティ(たとえば、進行状況バーやパーセンテージ)を更新し、アニメーションを更新できます
Do-do-new

12

同じ問題がありました。バックグラウンドでの長時間の操作のため、フォーム全体(gifを含む)が再描画を停止します。これが私がこれをどのように解決したかです。

  private void MyThreadRoutine()
  {
   this.Invoke(this.ShowProgressGifDelegate);
   //your long running process
   System.Threading.Thread.Sleep(5000);
   this.Invoke(this.HideProgressGifDelegate);
  }

  private void button1_Click(object sender, EventArgs e)
  {
   ThreadStart myThreadStart = new ThreadStart(MyThreadRoutine);
   Thread myThread = new Thread(myThreadStart);
   myThread.Start(); 
  }

この操作を担当する別のスレッドを作成しただけです。この最初のフォームのおかげで、問題なく再描画を続けています(gifの動作を含む)。ShowProgressGifDelegateおよびHideProgressGifDelegateは、gifを含むpictureBoxのvisibleプロパティをtrue / falseに設定する形式のデリゲートです。


6

Windowsでは、伝統的にアニメーションGIFは使用せず、AVIアニメーションはほとんど使用しないことに注意してください。それらを表示するだけのWindowsネイティブコントロールがあります。アニメーション化されたGifをAVIに(そしてその逆も)変換するツールさえあります。


はい-多分それは私が尋ねるべきだったものです。ありがとう。
スチュアートヘルヴィヒ2008年

6
ツールにリンクしますか?または、ドキュメンテーションへのその他の参照、理由などは素晴らしいでしょう。ありがとう!
ジェフB

1
私は伝統的なWindowsソフトウェアを書くことを気にしません。System.Windows.Forms.PictureBoxコントロールでサポートされている場合は、アニメーションGIFを使用します。
Mike de Klerk 2013

3

あなたがPictureBoxコントロールに入れれば、それはうまくいくはずです


2
フォームを無効にしない限り;)
ジェフB

1

同じスレッドで実行しているため、すべての処理が停止するため、長い操作を遅れて開始した場合はそうなりません。


私がStackOverflowで読んでいる限り、MTAスレッドモードは最悪の解決策のようです。
ヨーグルツ

1
Public Class Form1

    Private animatedimage As New Bitmap("C:\MyData\Search.gif")
    Private currentlyanimating As Boolean = False

    Private Sub OnFrameChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)

        Me.Invalidate()

    End Sub

    Private Sub AnimateImage()

        If currentlyanimating = True Then
            ImageAnimator.Animate(animatedimage, AddressOf Me.OnFrameChanged)
            currentlyanimating = False
        End If

    End Sub

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)

        AnimateImage()
        ImageAnimator.UpdateFrames(animatedimage)
        e.Graphics.DrawImage(animatedimage, New Point((Me.Width / 4) + 40, (Me.Height / 4) + 40))

    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        BtnStop.Enabled = False

    End Sub

    Private Sub BtnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnStop.Click

        currentlyanimating = False
        ImageAnimator.StopAnimate(animatedimage, AddressOf Me.OnFrameChanged)
        BtnStart.Enabled = True
        BtnStop.Enabled = False

    End Sub

    Private Sub BtnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnStart.Click

        currentlyanimating = True
        AnimateImage()
        BtnStart.Enabled = False
        BtnStop.Enabled = True

    End Sub

End Class

0

私は同じ問題を抱えていましたが、以前はいくつかの異なる問題に直面していた実装によって、異なる解決策に出会いました。最後に、以下は、さまざまな投稿からいくつかの作品をまとめたもので、期待どおりに機能しました。

private void btnCompare_Click(object sender, EventArgs e)
{
    ThreadStart threadStart = new ThreadStart(Execution);
    Thread thread = new Thread(threadStart);
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
}

次に、PictureBoxコントロールの呼び出しも実行するExecutionメソッドを示します。

private void Execution()
{
    btnCompare.Invoke((MethodInvoker)delegate { pictureBox1.Visible = true; });
    Application.DoEvents();

    // Your main code comes here . . .

    btnCompare.Invoke((MethodInvoker)delegate { pictureBox1.Visible = false; });
}

PictureBoxは[プロパティ]ウィンドウからは見えないか、以下のようにします。

private void ComparerForm_Load(object sender, EventArgs e)
{
    pictureBox1.Visible = false;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.