顯示GIF動畫

來源:互聯網
上載者:User
 

顯示GIF動畫'=================================說明====================================== '一、原理說明:'這隻是一個簡單的Gif圖片播放控制項'原理其實很簡單Gif檔案是由三部分構成'1、標頭檔'2、幀'3、檔案結束標誌'標頭檔前五個字母固定由Gif89構成,藉此可以判斷是否為Gif檔案'標頭檔、幀與幀之間固定由標誌 &H21 & HF9 串連,'從&H21開始的第四個位元組表示幀之間的延遲。'由此就可以由每一幀、標頭檔和檔案結束標誌 &H3B 來構成單幀Gif檔案'由程式一幀幀的來顯示'===============================/說明========================================== Imports System.IO Imports System.DrawingImports System.ThreadingImports System.ComponentModel<ToolboxBitmap("E:/Gif_Project/gif.ico"), DefaultProperty("GifImage"), DefaultEvent("Stoped")> _Public Class GifAnimationInherits System.Windows.Forms.UserControlConst GifBz1 As Byte = 33 '幀標誌 &H21Const GifBz2 As Byte = 249 '幀標誌 &HF9Const GifEnd As Byte = 179 '結尾標誌 &H3B#Region " Windows 表單設計器產生的程式碼 "Public Sub New()MyBase.New()'該調用是 Windows 表單設計器所必需的。InitializeComponent()'在 InitializeComponent() 調用之後添加任何初始化End Sub'UserControl 重寫 dispose 以清理組件列表。Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)If disposing ThenIf Not (components Is Nothing) Thencomponents.Dispose()End IfEnd IfMyBase.Dispose(disposing)End Sub'Windows 表單設計器所必需的Private components As System.ComponentModel.IContainer'注意: 以下過程是 Windows 表單設計器所必需的'可以使用 Windows 表單設計器修改此過程。'不要使用代碼編輯器修改它。Private WithEvents PictureBox1 As System.Windows.Forms.PictureBoxFriend WithEvents Timer1 As System.Windows.Forms.Timer<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()Me.components = New System.ComponentModel.ContainerMe.PictureBox1 = New System.Windows.Forms.PictureBoxMe.Timer1 = New System.Windows.Forms.Timer(Me.components)Me.SuspendLayout()''PictureBox1'Me.PictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingleMe.PictureBox1.Location = New System.Drawing.Point(4, 1)Me.PictureBox1.Name = "PictureBox1"Me.PictureBox1.Size = New System.Drawing.Size(72, 70)Me.PictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImageMe.PictureBox1.TabIndex = 0Me.PictureBox1.TabStop = False''Timer1'''GifAnimation'Me.Controls.Add(Me.PictureBox1)Me.Name = "GifAnimation"Me.Size = New System.Drawing.Size(77, 72)Me.ResumeLayout(False)End Sub#End Region'集合用以擷取每幀資訊Private m_col_Gif As Collection'停止標誌Private mblnStop As Boolean = TruePrivate mintCurrentPosition As Integer '當前播放位置Private mimgGif As ImagePrivate mth As ThreadPublic Event Stoped(ByVal sender As Object) '停止事件 Public WriteOnly Property GifFile() As StringSet(ByVal Value As String)If Value Is Nothing Then Exit PropertymimgGif = Image.FromFile(Value)m_col_Gif = FormatGIF(Value)If m_col_Gif Is Nothing OrElse m_col_Gif.Count = 0 ThenMe.PictureBox1.Image = NothingmimgGif = NothingExit PropertyEnd IfSetPicToPicturbox(CType(m_col_Gif.Item(1), GifFrame).Frame)End SetEnd PropertyPublic Property SizeModel() As PictureBoxSizeModeGetReturn Me.PictureBox1.SizeModeEnd GetSet(ByVal Value As PictureBoxSizeMode)Me.PictureBox1.SizeMode = ValueEnd SetEnd PropertyPublic Property BorderStyle() As BorderStyleGetReturn Me.PictureBox1.BorderStyleEnd GetSet(ByVal Value As BorderStyle)Me.PictureBox1.BorderStyle = ValueEnd SetEnd PropertyPublic Property GifImage() As ImageGetReturn mimgGifEnd GetSet(ByVal Value As Image)If Value Is Nothing Then Exit PropertymimgGif = Valuem_col_Gif = FormatGIF(Value)If m_col_Gif Is Nothing OrElse m_col_Gif.Count = 0 ThenMe.PictureBox1.Image = NothingExit PropertyEnd IfSetPicToPicturbox(CType(m_col_Gif.Item(1), GifFrame).Frame)End SetEnd PropertyPublic Sub StopView()mblnStop = TrueEnd SubPrivate Sub Start()Dim i As IntegerDim gif As GifFrameDo Until mblnStop = Truei += 1If i > m_col_Gif.Count Theni = 1End Ifgif = m_col_Gif.Item(i)Thread.Sleep(gif.Invert * 10) '幀與幀之間的延遲'顯示映像SetPicToPicturbox(gif.Frame)LoopSetPicToPicturbox(CType(m_col_Gif.Item(1), GifFrame).Frame)RaiseEvent Stoped(Me)End SubPublic Sub StartView(Optional ByVal useTimer As Boolean = True)If m_col_Gif Is Nothing Then Exit SubIf m_col_Gif.Count = 0 Then Exit SubmblnStop = FalseIf useTimer ThenIf m_col_Gif Is Nothing Then Exit SubIf m_col_Gif.Count = 0 Then Exit SubmblnStop = FalseTimer1.Enabled = TrueElsemth = New Thread(AddressOf Start)mth.Priority = ThreadPriority.Normalmth.Start()End IfEnd Sub'從文獲得幀資訊Private Function FormatGIF(ByVal GifFile As String) As Collection'開啟圖片檔案Dim fs As New FileStream(GifFile, FileMode.Open, FileAccess.Read)'檔案長度Dim fileLen As Long = fs.LengthDim br As New BinaryReader(fs)Dim buff As Byte()'將圖片資訊全部讀入一個位元組數組buff = br.ReadBytes(fileLen)Return FormatGIF(buff)End Function'從Image對象擷取幀資訊Private Function FormatGIF(ByVal GifImage As Image) As CollectionDim col As New Collection'建立一個記憶體流Dim sr As New MemoryStream'將映像寫入到流GifImage.Save(sr, GifImage.RawFormat.Gif) Dim buff As Byte()'將映像轉換成位元組數組buff = sr.ToArrayReturn FormatGIF(buff)End Function'從一個位元組數組獲得幀資訊Private Function FormatGIF(ByVal buff() As Byte) As CollectionDim col As New CollectionDim Index1 As LongDim Index2 As LongDim IndexTmp As LongDim intTime As IntegerDim buffHead() As ByteDim buffBody() As ByteDim img As ImageIf buff.Length < 3 Then Return col'將頭三位元組轉換成字串Dim tmp As String = System.Text.Encoding.Default.GetString(buff, 0, 3).ToLower'是否是Gif檔案If tmp <> "gif" ThenThrow New Exception("圖片格式錯誤!必須是Gif檔案")End If Do'尋找第一個標誌 &H21Index1 = buff.IndexOf(buff, GifBz1, Index1 + 1)If Index1 < 0 Or Index1 >= buff.Length - 1 Then Return col'尋找第二個標誌 &H21Index2 = buff.IndexOf(buff, GifBz2, Index1)'兩個標誌是否連續If Index2 - Index1 = 1 Then Exit DoLoopIndexTmp = Index1'建立一個緩衝buffHead = buffHead.CreateInstance(GetType(System.Byte), Index1)'獲得頭部資訊buff.Copy(buff, buffHead, Index1) 'read gifheadDoDoIndex1 = buff.IndexOf(buff, GifBz1, Index1 + 1)If Index1 < 0 Or Index1 >= buff.Length - 1 Then Exit DoIndex2 = buff.IndexOf(buff, GifBz2, Index1)If Index2 - Index1 = 1 Then Exit DoLoop'是否是最後一幀If Index1 < 0 Or Index1 >= buff.Length - 1 Then Exit Do'建立緩衝buffBody = buffBody.CreateInstance(GetType(Byte), Index1 - IndexTmp)'擷取幀資訊buffBody.Copy(buff, IndexTmp, buffBody, 0, Index1 - IndexTmp)' 擷取每幀的間隔時間intTime = Val(buff(IndexTmp + 4))'重建每幀映像img = CreateImage(buffHead, buffBody)'建立一個幀對象Dim gif As New GifFrame(img, intTime)'添加到集合col.Add(gif)IndexTmp = Index1Loop  '最後一幀buffBody = buffBody.CreateInstance(GetType(Byte), buff.Length - IndexTmp)buffBody.Copy(buff, IndexTmp, buffBody, 0, buff.Length - IndexTmp)'擷取每幀的間隔時間intTime = Val(buff(IndexTmp + 4))img = CreateImage(buffHead, buffBody, False) Dim gifs As New GifFrame(img, intTime)col.Add(gifs)Return colEnd Function'建立一個幀映像Private Function CreateImage(ByVal gifHead() As Byte, ByVal gifBody() As Byte, Optional ByVal AddEnd As Boolean = True) As Image'建立一個記憶體流Dim sm As New MemoryStreamDim img As Image'寫入頭部資訊sm.Write(gifHead, 0, gifHead.Length)'寫入幀資訊sm.Write(gifBody, 0, gifBody.Length)'如果不是最後一幀則寫入結束標誌If AddEnd Then sm.WriteByte(Me.GifEnd)'建立圖形img = Image.FromStream(sm)'關閉流sm.Close()Return imgEnd Function'顯示一個幀映像Private Sub SetPicToPicturbox(ByVal img As Image)Me.PictureBox1.Image = imgPictureBox1.Top = 0PictureBox1.Left = 0If PictureBox1.SizeMode <> PictureBoxSizeMode.AutoSize Then Exit SubMe.Width = Me.PictureBox1.WidthMe.Height = Me.PictureBox1.HeightEnd SubPrivate Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.TickIf mintCurrentPosition < m_col_Gif.Count ThenmintCurrentPosition = mintCurrentPosition + 1ElsemintCurrentPosition = 1End If'擷取當前幀Dim gif As GifFrame = m_col_Gif.Item(mintCurrentPosition)SetPicToPicturbox(gif.Frame) '顯示幀映像Timer1.Interval = gif.Invert * 10 '幀延遲If mblnStop = True ThenTimer1.Enabled = FalseSetPicToPicturbox(CType(m_col_Gif.Item(1), GifFrame).Frame)RaiseEvent Stoped(Me) '觸發事件End IfEnd SubPrivate Sub GifAnimation_BackColorChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.BackColorChangedPictureBox1.BackColor = Me.BackColorEnd SubPrivate Sub GifAnimation_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.ResizePictureBox1.Top = 0PictureBox1.Left = 0If PictureBox1.SizeMode <> PictureBoxSizeMode.AutoSize ThenPictureBox1.Width = Me.WidthPictureBox1.Height = Me.HeightElseMe.Width = PictureBox1.WidthMe.Height = PictureBox1.HeightEnd IfEnd SubPrivate Sub GifAnimation_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.DisposedTryMe.mblnStop = TrueIf Not mth Is Nothing Then'停止線程mth.Abort()End IfCatch ex As ExceptionEnd TryEnd Sub '幀對象'用以儲存每幀的資訊:幀延遲、映像Private Class GifFramePublic Frame As Image '幀映像Public Invert As Integer '幀延遲Public Sub New(ByVal img As Image, ByVal time As Integer)Frame = imgInvert = timeEnd SubEnd ClassEnd Class

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.