分享
 
 
 

.net 显示/播放 Gif动画

王朝c#·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

New Page 1

'=================================说明======================================

'一、原理说明:

'这只是一个简单的Gif图片播放控件

'原理其实很简单Gif文件是由三部分构成

'1、头文件

'2、帧

'3、文件结束标志

'头文件前五个字母固定由Gif89构成,借此可以判断是否为Gif文件

'头文件、帧与帧之间固定由标志 &H21 & HF9

连接,

'从&H21开始的第四个字节表示帧之间的延迟。

'由此就可以由每一帧、头文件和文件结束标志

&H3B 来构成单帧Gif文件

'由程序一帧帧的来显示

'===============================/说明==========================================

Imports

System.IO

Imports System.Drawing

Imports System.Threading

Imports System.ComponentModel

<ToolboxBitmap("E:\Gif_Project\gif.ico"),

DefaultProperty("GifImage"), DefaultEvent("Stoped")>

_

Public Class

GifAnimation

Inherits

System.Windows.Forms.UserControl

Const

GifBz1 As Byte

= 33 '帧标志 &H21

Const

GifBz2 As Byte

= 249 '帧标志 &HF9

Const

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 Then

If Not

(components Is

Nothing) Then

components.Dispose()

End If

End If

MyBase.Dispose(disposing)

End Sub

'Windows

窗体设计器所必需的

Private

components As

System.ComponentModel.IContainer

'注意: 以下过程是

Windows 窗体设计器所必需的

'可以使用 Windows

窗体设计器修改此过程。

'不要使用代码编辑器修改它。

Private WithEvents

PictureBox1 As

System.Windows.Forms.PictureBox

Friend WithEvents

Timer1 As

System.Windows.Forms.Timer

<System.Diagnostics.DebuggerStepThrough()> Private

Sub

InitializeComponent()

Me.components

= New

System.ComponentModel.Container

Me.PictureBox1

= New

System.Windows.Forms.PictureBox

Me.Timer1

= New

System.Windows.Forms.Timer(Me.components)

Me.SuspendLayout()

'

'PictureBox1

'

Me.PictureBox1.BorderStyle

= System.Windows.Forms.BorderStyle.FixedSingle

Me.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.CenterImage

Me.PictureBox1.TabIndex

= 0

Me.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

= True

Private

mintCurrentPosition As

Integer '当前播放位置

Private

mimgGif As

Image

Private

mth As

Thread

Public Event

Stoped(ByVal

sender As Object)

'停止事件

Public WriteOnly

Property

GifFile() As

String

Set(ByVal

Value As String)

If Value Is

Nothing Then

Exit Property

mimgGif = Image.FromFile(Value)

m_col_Gif = FormatGIF(Value)

If

m_col_Gif Is

Nothing OrElse

m_col_Gif.Count = 0 Then

Me.PictureBox1.Image

= Nothing

mimgGif = Nothing

Exit Property

End If

SetPicToPicturbox(CType(m_col_Gif.Item(1),

GifFrame).Frame)

End Set

End Property

Public Property

SizeModel() As

PictureBoxSizeMode

Get

Return Me.PictureBox1.SizeMode

End Get

Set(ByVal

Value As

PictureBoxSizeMode)

Me.PictureBox1.SizeMode

= Value

End Set

End Property

Public Property

BorderStyle() As

BorderStyle

Get

Return Me.PictureBox1.BorderStyle

End Get

Set(ByVal

Value As

BorderStyle)

Me.PictureBox1.BorderStyle

= Value

End Set

End Property

Public Property

GifImage() As

Image

Get

Return

mimgGif

End Get

Set(ByVal

Value As

Image)

If Value Is

Nothing Then

Exit Property

mimgGif = Value

m_col_Gif = FormatGIF(Value)

If

m_col_Gif Is

Nothing OrElse

m_col_Gif.Count = 0 Then

Me.PictureBox1.Image

= Nothing

Exit Property

End If

SetPicToPicturbox(CType(m_col_Gif.Item(1),

GifFrame).Frame)

End Set

End Property

Public Sub

StopView()

mblnStop = True

End Sub

Private Sub

Start()

Dim i As

Integer

Dim gif As

GifFrame

Do Until

mblnStop = True

i += 1

If i >

m_col_Gif.Count Then

i = 1

End If

gif = m_col_Gif.Item(i)

Thread.Sleep(gif.Invert * 10) '帧与帧之间的延迟

'显示图像

SetPicToPicturbox(gif.Frame)

Loop

SetPicToPicturbox(CType(m_col_Gif.Item(1),

GifFrame).Frame)

RaiseEvent

Stoped(Me)

End Sub

Public Sub

StartView(Optional

ByVal

useTimer As Boolean

= True)

If

m_col_Gif Is

Nothing Then

Exit Sub

If

m_col_Gif.Count = 0 Then

Exit Sub

mblnStop = False

If

useTimer Then

If

m_col_Gif Is

Nothing Then

Exit Sub

If

m_col_Gif.Count = 0 Then

Exit Sub

mblnStop = False

Timer1.Enabled = True

Else

mth = New

Thread(AddressOf

Start)

mth.Priority = ThreadPriority.Normal

mth.Start()

End If

End 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.Length

Dim

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

Collection

Dim col As

New

Collection

'创建一个内存流

Dim sr As

New

MemoryStream

'将图像写入到流

GifImage.Save(sr, GifImage.RawFormat.Gif)

Dim buff As

Byte()

'将图像转换成字节数组

buff = sr.ToArray

Return

FormatGIF(buff)

End Function

'从一个字节数组获得帧信息

Private Function

FormatGIF(ByVal

buff() As Byte)

As

Collection

Dim col As

New

Collection

Dim

Index1 As Long

Dim

Index2 As Long

Dim

IndexTmp As Long

Dim

intTime As Integer

Dim

buffHead() As

Byte

Dim

buffBody() As

Byte

Dim img As

Image

If

buff.Length < 3 Then

Return col

'将头三字节转换成字符串

Dim tmp As

String =

System.Text.Encoding.Default.GetString(buff, 0, 3).ToLower

'是否是Gif文件

If tmp

<> "gif" Then

Throw New

Exception("图片格式错误!必须是Gif文件")

End If

Do

'查找第一个标志 &H21

Index1 = buff.IndexOf(buff, GifBz1, Index1 + 1)

If Index1

< 0 Or

Index1 >= buff.Length - 1 Then

Return col

'查找第二个标志 &H21

Index2 = buff.IndexOf(buff, GifBz2, Index1)

'两个标志是否连续

If Index2

- Index1 = 1 Then

Exit Do

Loop

IndexTmp = Index1

'创建一个缓冲

buffHead = buffHead.CreateInstance(GetType(System.Byte),

Index1)

'获得头部信息

buff.Copy(buff, buffHead, Index1) 'read

gifhead

Do

Do

Index1 = buff.IndexOf(buff, GifBz1, Index1 + 1)

If Index1

< 0 Or

Index1 >= buff.Length - 1 Then

Exit Do

Index2 = buff.IndexOf(buff, GifBz2, Index1)

If Index2

- Index1 = 1 Then

Exit Do

Loop

'是否是最后一帧

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 = Index1

Loop

'最后一帧

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

col

End Function

'创建一个帧图像

Private Function

CreateImage(ByVal

gifHead() As

Byte, ByVal

gifBody() As

Byte, Optional

ByVal AddEnd

As Boolean

= True) As

Image

'创建一个内存流

Dim sm As

New

MemoryStream

Dim 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

img

End Function

'显示一个帧图像

Private Sub

SetPicToPicturbox(ByVal

img As

Image)

Me.PictureBox1.Image

= img

PictureBox1.Top = 0

PictureBox1.Left = 0

If

PictureBox1.SizeMode <> PictureBoxSizeMode.AutoSize Then

Exit Sub

Me.Width

= Me.PictureBox1.Width

Me.Height

= Me.PictureBox1.Height

End Sub

Private Sub

Timer1_Tick(ByVal

sender As Object,

ByVal e As

System.EventArgs) Handles

Timer1.Tick

If

mintCurrentPosition < m_col_Gif.Count Then

mintCurrentPosition = mintCurrentPosition + 1

Else

mintCurrentPosition = 1

End If

'获取当前帧

Dim gif As

GifFrame = m_col_Gif.Item(mintCurrentPosition)

SetPicToPicturbox(gif.Frame) '显示帧图像

Timer1.Interval = gif.Invert * 10 '帧延迟

If

mblnStop = True

Then

Timer1.Enabled = False

SetPicToPicturbox(CType(m_col_Gif.Item(1),

GifFrame).Frame)

RaiseEvent

Stoped(Me) '触发事件

End If

End Sub

Private Sub

GifAnimation_BackColorChanged(ByVal

sender As Object,

ByVal e As

System.EventArgs) Handles

MyBase.BackColorChanged

PictureBox1.BackColor = Me.BackColor

End Sub

Private Sub

GifAnimation_Resize(ByVal

sender As Object,

ByVal e As

System.EventArgs) Handles

MyBase.Resize

PictureBox1.Top = 0

PictureBox1.Left = 0

If

PictureBox1.SizeMode <> PictureBoxSizeMode.AutoSize Then

PictureBox1.Width = Me.Width

PictureBox1.Height = Me.Height

Else

Me.Width

= PictureBox1.Width

Me.Height

= PictureBox1.Height

End If

End Sub

Private Sub

GifAnimation_Disposed(ByVal

sender As Object,

ByVal e As

System.EventArgs) Handles

MyBase.Disposed

Try

Me.mblnStop

= True

If Not

mth Is Nothing

Then

'停止线程

mth.Abort()

End If

Catch ex As

Exception

End Try

End Sub

'帧对象

'用以储存每帧的信息:帧延迟、图像

Private Class

GifFrame

Public

Frame As

Image '帧图像

Public

Invert As Integer

'帧延迟

Public Sub

New(ByVal

img As

Image, ByVal

time As Integer)

Frame = img

Invert = time

End Sub

End Class

End Class

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有