问题描述
在我的项目中,我想在 PictureBox 中播放 GIF。
我需要播放 GIF 动画包含的所有帧,然后停止动画。
我正在使用 ImageAnimator 类为 GIF 图像制作动画,我只是不知道如何停止它。
Private image As Image = My.Resources.icon_confirmation
'Private frames As Integer
Dim FDimensions As System.Drawing.Imaging.FrameDimension = New System.Drawing.Imaging.FrameDimension(image.FrameDimensionsList(0))
Dim frames As Integer = image.GetFrameCount(FDimensions)
Private Sub paintFrame(ByVal sender As Object,ByVal e As EventArgs)
If frames < 33 Then PictureBox1.Image = image Else ImageAnimator.StopAnimate(image,AddressOf StopAnim)
End Sub
Private Sub StopAnim(ByVal sender As Object,ByVal e As EventArgs)
PictureBox1.dispose()
End Sub
Private Sub PictureBox1_Paint(ByVal sender As Object,ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
If frames = 12 Then
ImageAnimator.UpdateFrames()
e.Graphics.DrawImage(image,Point.Empty)
frames -= 1
End If
End Sub
解决方法
要跟踪在您的 PictureBox 上绘制的当前帧,您需要一个 Field 来存储当前进度并将其与动画包含的帧数进行比较。
当进度到达最后一帧(或最后一帧之前的任何其他帧,无论需要什么)时,您将停止调用 ImageAnimator.StopAnimate() 的动画。
要开始动画,您首先检查是否ImageAnimator.CanAnimate()(它可能无法为您指定的图像设置动画)。如果可以,则调用 ImageAnimator.Animate(),将 Image 对象和处理 FrameChanged
事件的方法的地址传递给方法。
这个处理程序用于检查动画是否应该继续。如果满足所有条件(并非所有帧都已绘制),Invalidate() 控件用于显示动画,并在其 Paint
事件处理程序中调用 ImageAnimator.UpdateFrames() 以更改当前帧,然后 e.Graphics.DrawImage() 绘制图像(绘制现在是当前的帧)。
▶ 正如您在可视化示例中看到的,我使用按钮 (btnAnimate
) 来启动动画。如果您愿意,您可以将该代码移至 Form.Shown
事件处理程序。
▶ 我添加了一个循环计数器,以防动画应该循环多次。
视觉效果如下:
Imports System.Drawing.Imaging
' [...]
Private animation As Image = My.Resources.icon_confirmation
Private animationFrames As Integer = 0
Private currentFrame As Integer = 0
Private animationMaxLoops As Integer = 1
Private loops As Integer = 0
Private Sub btnAnimate_Click(sender As Object,e As EventArgs) Handles btnAnimate.Click
animationFrames = animation.GetFrameCount(New FrameDimension(animation.FrameDimensionsList(0)))
AnimateImage()
End Sub
Public Sub AnimateImage()
If ImageAnimator.CanAnimate(animation) Then
ImageAnimator.Animate(animation,AddressOf OnFrameChanged)
End If
End Sub
Private Sub OnFrameChanged(o As Object,e As EventArgs)
If currentFrame >= animationFrames Then
currentFrame = 0
loops += 1
If loops >= animationMaxLoops Then
animationFrames = 0
loops = 0
ImageAnimator.StopAnimate(animation,AddressOf OnFrameChanged)
End If
Else
pictureBox1.Invalidate()
currentFrame += 1
End If
End Sub
Private Sub pictureBox1_Paint(sender As Object,e As PaintEventArgs) Handles pictureBox1.Paint
If animationFrames > 0 Then
ImageAnimator.UpdateFrames()
e.Graphics.DrawImage(animation,Point.Empty)
End If
End Sub
使用项目资源中的图像执行动画的 PasteBin of a complete Form。