|
Hongliang さん
ありがとうございます。
VBの限界とかではなくて、単にImageAnimatorがよろしくなかったのですね…
仰る通り、自前でフレーム管理を行うことにします。
こちらの方が、逆再生や再生速度の変化などもいじれますし、何より早かったです。助かりました。
(ImageAnimatorは、GIFアニメのための一般的なクラスだと思っていましたが、どうもそうでもないようですね…落ちるし)
ただ、質問に挙げた、
2:一部のGIFを再生すると、GDI+がエラーを起こす
については、やはり同じ部分でエラーが出るようです。
しかしこちらは必ずキャッチが可能なようですので、大きな問題にはならなさそうです。
(GIFのフォーマットを詳細に調べれば、なんとかなるのでしょうけど… 今後の課題とします)
蛇足ですが、以下に私が試したソースを載せておきます。
Public Class Form3
Private ReadOnly FrameDelay As Integer = Convert.ToInt32("0x5100", System.Globalization.NumberStyles.AllowParentheses)
Private ReadOnly Frames As Integer = Convert.ToInt32("0x5101", System.Globalization.NumberStyles.AllowParentheses)
''' <summary>
''' GIFイメージのディメンジョンデータ
''' </summary>
''' <remarks></remarks>
Dim Dimension As Drawing.Imaging.FrameDimension
''' <summary>
''' ディレイ値のプロパティアイテム
''' </summary>
''' <remarks></remarks>
Dim PItemDelay As Drawing.Imaging.PropertyItem
''' <summary>
''' ディレイ値のバイト数
''' </summary>
''' <remarks></remarks>
Dim PItemLenDelay As Integer
''' <summary>
''' ディレイ値を収めた配列。1/100秒単位
''' </summary>
''' <remarks></remarks>
Dim FrameDelays() As Integer
''' <summary>
''' ループカウントのプロパティアイテム
''' </summary>
''' <remarks></remarks>
Dim PItemLoopCnt As Drawing.Imaging.PropertyItem
''' <summary>
''' ループカウントのバイト数
''' </summary>
''' <remarks></remarks>
Dim PItemLenLoop As Integer
''' <summary>
''' ループカウントを収めたShort型
''' </summary>
''' <remarks></remarks>
Dim MaxLoopCnt As Short
''' <summary>
''' 全フレーム数のカウント
''' </summary>
''' <remarks></remarks>
Dim MaxFrameCount As Integer
Dim LoopCnt As Short = 0
Dim FrameCount As Integer = 0
Private AnimationFlg As Boolean
Private GifImage As Bitmap
Private Sub Form3_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
TextBox1.Text = "C:\Documents and Settings\Administrator.JES-TOKYO\デスクトップ\12men_w_gif\niconicomugen.gif"
Me.DoubleBuffered = True
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim I As Integer
Timer1.Enabled = False
If Not GifImage Is Nothing Then
GifImage.Dispose()
LoopCnt = 0
FrameCount = 0
AnimationFlg = False
Dimension = Nothing
End If
GifImage = New Bitmap(TextBox1.Text)
'ディメンジョン取得
Dimension = New Drawing.Imaging.FrameDimension(GifImage.FrameDimensionsList(0))
'フレーム数
MaxFrameCount = GifImage.GetFrameCount(Dimension)
ReDim FrameDelays(MaxFrameCount - 1)
'プロパティアイテム取得
PItemDelay = GifImage.GetPropertyItem(FrameDelay)
PItemLenDelay = PItemDelay.Len
PItemLoopCnt = GifImage.GetPropertyItem(Frames)
PItemLenLoop = PItemLoopCnt.Len
Debug.Print(String.Format("FrameCount:{0}", MaxFrameCount))
Debug.Print(String.Format("PItemLenDelay:{0}", PItemLenDelay))
Debug.Print(String.Format("PItemLenLoop:{0}", PItemLenLoop))
'ディレイデータ取得
For I = 0 To MaxFrameCount - 1
FrameDelays(I) = BitConverter.ToInt32(PItemDelay.Value, I * 4)
Debug.Print(String.Format("FrameDelays:{0}/{1}", I, FrameDelays(I).ToString))
Next
'ループカウント取得
MaxLoopCnt = BitConverter.ToInt16(PItemLoopCnt.Value, 0)
Debug.Print(String.Format("LoopCnt:{0}", MaxLoopCnt))
'描画
GifImage.SelectActiveFrame(Dimension, 0)
Me.PictureBox1.CreateGraphics.DrawImage(GifImage, 0, 0)
'タイマー開始
FrameCount = 1
Me.Timer1.Interval = FrameDelays(0) * 10
Me.Timer1.Enabled = True
AnimationFlg = True
End Sub
Private Sub IncreaseFrame()
If MaxLoopCnt <> 0 AndAlso LoopCnt = MaxLoopCnt AndAlso FrameCount = MaxFrameCount Then
'再生終了
Me.Timer1.Enabled = False
AnimationFlg = False
Return
End If
If FrameCount = MaxFrameCount Then
LoopCnt += 1
FrameCount = 1
Else
FrameCount += 1
End If
Try
GifImage.SelectActiveFrame(Dimension, FrameCount - 1)
Catch ex As Exception
Debug.Print(String.Format("{0}/{1}", Now, ex.Message))
End Try
Me.Timer1.Interval = FrameDelays(FrameCount - 1) * 10
Me.Invalidate(True)
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If AnimationFlg Then IncreaseFrame()
End Sub
Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
If Not GifImage Is Nothing Then
e.Graphics.DrawImage(GifImage, 0, 0)
End If
End Sub
End Class
|