'=================================说明======================================
'一、原理说明:
'这只是一个简单的Gif图片播放控件
'原理其实很简单Gif文件是由三部分构成
'1、头文件
'2、帧
'3、文件结束标志
'头文件前五个字母固定由Gif89构成,借此可以判断是否为Gif文件
'头文件、帧与帧之间固定由标志 &H21 & HF9 连接,
'从&H21开始的第四个字节表示帧之间的延迟。
'由此就可以由每一帧、头文件和文件结束标志 &H3B 来构成单帧Gif文件
'由程序一帧帧的来显示
'===============================/说明==========================================
Imports System.IO
Imports
System.Drawing
Imports
System.Threading
Imports
System.ComponentModel
1<toolboxbitmap("e:\gif_project\gif.ico"), defaultevent("stoped")="" defaultproperty("gifimage"),=""> _
2
3Public
4
5Class GifAnimation
6
7Inherits System.Windows.Forms.UserControl
8
9Const GifBz1 As Byte = 33 '帧标志 &H21
10
11Const GifBz2 As Byte = 249 '帧标志 &HF9
12
13Const GifEnd As Byte = 179 '结尾标志 &H3B
14
15#
16
17Region " Windows 窗体设计器生成的代码 "
18
19Public Sub New ()
20
21MyBase .New()
22
23'该调用是 Windows 窗体设计器所必需的。
24
25InitializeComponent()
26
27'在 InitializeComponent() 调用之后添加任何初始化
28
29End Sub
30
31'UserControl 重写 dispose 以清理组件列表。
32
33Protected Overloads Overrides Sub Dispose( ByVal disposing As Boolean )
34
35If disposing Then
36
37If Not (components Is Nothing ) Then
38
39components.Dispose()
40
41End If
42
43End If
44
45MyBase .Dispose(disposing)
46
47End Sub
48
49'Windows 窗体设计器所必需的
50
51Private components As System.ComponentModel.IContainer
52
53'注意: 以下过程是 Windows 窗体设计器所必需的
54
55'可以使用 Windows 窗体设计器修改此过程。
56
57'不要使用代码编辑器修改它。
58
59Private WithEvents PictureBox1 As System.Windows.Forms.PictureBox
60
61Friend WithEvents Timer1 As System.Windows.Forms.Timer
62
63<system.diagnostics.debuggerstepthrough()>
64
65Private Sub InitializeComponent()
66
67Me .components = New System.ComponentModel.Container
68
69Me .PictureBox1 = New System.Windows.Forms.PictureBox
70
71Me .Timer1 = New System.Windows.Forms.Timer( Me .components)
72
73Me .SuspendLayout()
74
75'
76
77'PictureBox1
78
79'
80
81Me .PictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
82
83Me .PictureBox1.Location = New System.Drawing.Point(4, 1)
84
85Me .PictureBox1.Name = "PictureBox1"
86
87Me .PictureBox1.Size = New System.Drawing.Size(72, 70)
88
89Me .PictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage
90
91Me .PictureBox1.TabIndex = 0
92
93Me .PictureBox1.TabStop = False
94
95'
96
97'Timer1
98
99'
100
101'
102
103'GifAnimation
104
105'
106
107Me .Controls.Add( Me .PictureBox1)
108
109Me .Name = "GifAnimation"
110
111Me .Size = New System.Drawing.Size(77, 72)
112
113Me .ResumeLayout( False )
114
115End Sub
116
117#
118
119End Region
120
121'集合用以获取每帧信息
122
123Private m_col_Gif As Collection
124
125'停止标志
126
127Private mblnStop As Boolean = True
128
129Private mintCurrentPosition As Integer '当前播放位置
130
131Private mimgGif As Image
132
133Private mth As Thread
134
135Public Event Stoped( ByVal sender As Object ) '停止事件
136
137Public WriteOnly Property GifFile() As String
138
139Set ( ByVal Value As String )
140
141If Value Is Nothing Then Exit Property
142
143mimgGif = Image.FromFile(Value)
144
145m_col_Gif = FormatGIF(Value)
146
147If m_col_Gif Is Nothing OrElse m_col_Gif.Count = 0 Then
148
149Me .PictureBox1.Image = Nothing
150
151mimgGif =
152
153Nothing
154
155Exit Property
156
157End If
158
159SetPicToPicturbox(
160
161CType (m_col_Gif.Item(1), GifFrame).Frame)
162
163End Set
164
165End Property
166
167Public Property SizeModel() As PictureBoxSizeMode
168
169Get
170
171Return Me .PictureBox1.SizeMode
172
173End Get
174
175Set ( ByVal Value As PictureBoxSizeMode)
176
177Me .PictureBox1.SizeMode = Value
178
179End Set
180
181End Property
182
183Public Property BorderStyle() As BorderStyle
184
185Get
186
187Return Me .PictureBox1.BorderStyle
188
189End Get
190
191Set ( ByVal Value As BorderStyle)
192
193Me .PictureBox1.BorderStyle = Value
194
195End Set
196
197End Property
198
199Public Property GifImage() As Image
200
201Get
202
203Return mimgGif
204
205End Get
206
207Set ( ByVal Value As Image)
208
209If Value Is Nothing Then Exit Property
210
211mimgGif = Value
212
213m_col_Gif = FormatGIF(Value)
214
215If m_col_Gif Is Nothing OrElse m_col_Gif.Count = 0 Then
216
217Me .PictureBox1.Image = Nothing
218
219Exit Property
220
221End If
222
223SetPicToPicturbox(
224
225CType (m_col_Gif.Item(1), GifFrame).Frame)
226
227End Set
228
229End Property
230
231Public Sub StopView()
232
233mblnStop =
234
235True
236
237End Sub
238
239Private Sub Start()
240
241Dim i As Integer
242
243Dim gif As GifFrame
244
245Do Until mblnStop = True
246
247i += 1
248
249If i > m_col_Gif.Count Then
250
251i = 1
252
253End If
254
255gif = m_col_Gif.Item(i)
256
257Thread.Sleep(gif.Invert * 10)
258
259'帧与帧之间的延迟
260
261'显示图像
262
263SetPicToPicturbox(gif.Frame)
264
265Loop
266
267SetPicToPicturbox(
268
269CType (m_col_Gif.Item(1), GifFrame).Frame)
270
271RaiseEvent Stoped( Me )
272
273End Sub
274
275Public Sub StartView( Optional ByVal useTimer As Boolean = True )
276
277If m_col_Gif Is Nothing Then Exit Sub
278
279If m_col_Gif.Count = 0 Then Exit Sub
280
281mblnStop =
282
283False
284
285If useTimer Then
286
287If m_col_Gif Is Nothing Then Exit Sub
288
289If m_col_Gif.Count = 0 Then Exit Sub
290
291mblnStop =
292
293False
294
295Timer1.Enabled =
296
297True
298
299Else
300
301mth =
302
303New Thread( AddressOf Start)
304
305mth.Priority = ThreadPriority.Normal
306
307mth.Start()
308
309End If
310
311End Sub
312
313'从文获得帧信息
314
315Private Function FormatGIF( ByVal GifFile As String ) As Collection
316
317'打开图片文件
318
319Dim fs As New FileStream(GifFile, FileMode.Open, FileAccess.Read)
320
321'文件长度
322
323Dim fileLen As Long = fs.Length
324
325Dim br As New BinaryReader(fs)
326
327Dim buff As Byte ()
328
329'将图片信息全部读入一个字节数组
330
331buff = br.ReadBytes(fileLen)
332
333Return FormatGIF(buff)
334
335End Function
336
337'从Image对象获取帧信息
338
339Private Function FormatGIF( ByVal GifImage As Image) As Collection
340
341Dim col As New Collection
342
343'创建一个内存流
344
345Dim sr As New MemoryStream
346
347'将图像写入到流
348
349GifImage.Save(sr, GifImage.RawFormat.Gif)
350
351Dim buff As Byte ()
352
353'将图像转换成字节数组
354
355buff = sr.ToArray
356
357Return FormatGIF(buff)
358
359End Function
360
361'从一个字节数组获得帧信息
362
363Private Function FormatGIF( ByVal buff() As Byte ) As Collection
364
365Dim col As New Collection
366
367Dim Index1 As Long
368
369Dim Index2 As Long
370
371Dim IndexTmp As Long
372
373Dim intTime As Integer
374
375Dim buffHead() As Byte
376
377Dim buffBody() As Byte
378
379Dim img As Image
380
381If buff.Length < 3 Then Return col
382
383'将头三字节转换成字符串
384
385Dim tmp As String = System.Text.Encoding.Default.GetString(buff, 0, 3).ToLower
386
387'是否是Gif文件
388
389If tmp <> "gif" Then
390
391Throw New Exception("图片格式错误!必须是Gif文件")
392
393End If
394
395Do
396
397'查找第一个标志 &H21
398
399Index1 = buff.IndexOf(buff, GifBz1, Index1 + 1)
400
401If Index1 < 0 Or Index1 >= buff.Length - 1 Then Return col
402
403'查找第二个标志 &H21
404
405Index2 = buff.IndexOf(buff, GifBz2, Index1)
406
407'两个标志是否连续
408
409If Index2 \- Index1 = 1 Then Exit Do
410
411Loop
412
413IndexTmp = Index1
414
415'创建一个缓冲
416
417buffHead = buffHead.CreateInstance(
418
419GetType (System.Byte), Index1)
420
421'获得头部信息
422
423buff.Copy(buff, buffHead, Index1)
424
425'read gifhead
426
427Do
428
429Do
430
431Index1 = buff.IndexOf(buff, GifBz1, Index1 + 1)
432
433If Index1 < 0 Or Index1 >= buff.Length - 1 Then Exit Do
434
435Index2 = buff.IndexOf(buff, GifBz2, Index1)
436
437If Index2 \- Index1 = 1 Then Exit Do
438
439Loop
440
441'是否是最后一帧
442
443If Index1 < 0 Or Index1 >= buff.Length - 1 Then Exit Do
444
445'创建缓冲
446
447buffBody = buffBody.CreateInstance(
448
449GetType ( Byte ), Index1 - IndexTmp)
450
451'获取帧信息
452
453buffBody.Copy(buff, IndexTmp, buffBody, 0, Index1 - IndexTmp)
454
455' 获取每帧的间隔时间
456
457intTime = Val(buff(IndexTmp + 4))
458
459'重建每帧图像
460
461img = CreateImage(buffHead, buffBody)
462
463'创建一个帧对象
464
465Dim gif As New GifFrame(img, intTime)
466
467'添加到集合
468
469col.Add(gif)
470
471IndexTmp = Index1
472
473Loop
474
475'最后一帧
476
477buffBody = buffBody.CreateInstance(
478
479GetType ( Byte ), buff.Length - IndexTmp)
480
481buffBody.Copy(buff, IndexTmp, buffBody, 0, buff.Length - IndexTmp)
482
483'获取每帧的间隔时间
484
485intTime = Val(buff(IndexTmp + 4))
486
487img = CreateImage(buffHead, buffBody,
488
489False )
490
491Dim gifs As New GifFrame(img, intTime)
492
493col.Add(gifs)
494
495Return col
496
497End Function
498
499'创建一个帧图像
500
501Private Function CreateImage( ByVal gifHead() As Byte , ByVal gifBody() As Byte , Optional ByVal AddEnd As Boolean = True ) As Image
502
503'创建一个内存流
504
505Dim sm As New MemoryStream
506
507Dim img As Image
508
509'写入头部信息
510
511sm.Write(gifHead, 0, gifHead.Length)
512
513'写入帧信息
514
515sm.Write(gifBody, 0, gifBody.Length)
516
517'如果不是最后一帧则写入结束标志
518
519If AddEnd Then sm.WriteByte( Me .GifEnd)
520
521'创建图形
522
523img = Image.FromStream(sm)
524
525'关闭流
526
527sm.Close()
528
529Return img
530
531End Function
532
533'显示一个帧图像
534
535Private Sub SetPicToPicturbox( ByVal img As Image)
536
537Me .PictureBox1.Image = img
538
539PictureBox1.Top = 0
540
541PictureBox1.Left = 0
542
543If PictureBox1.SizeMode <> PictureBoxSizeMode.AutoSize Then Exit Sub
544
545Me .Width = Me .PictureBox1.Width
546
547Me .Height = Me .PictureBox1.Height
548
549End Sub
550
551Private Sub Timer1_Tick( ByVal sender As Object , ByVal e As System.EventArgs) Handles Timer1.Tick
552
553If mintCurrentPosition < m_col_Gif.Count Then
554
555mintCurrentPosition = mintCurrentPosition + 1
556
557Else
558
559mintCurrentPosition = 1
560
561End If
562
563'获取当前帧
564
565Dim gif As GifFrame = m_col_Gif.Item(mintCurrentPosition)
566
567SetPicToPicturbox(gif.Frame)
568
569'显示帧图像
570
571Timer1.Interval = gif.Invert * 10
572
573'帧延迟
574
575If mblnStop = True Then
576
577Timer1.Enabled =
578
579False
580
581SetPicToPicturbox(
582
583CType (m_col_Gif.Item(1), GifFrame).Frame)
584
585RaiseEvent Stoped( Me ) '触发事件
586
587End If
588
589End Sub
590
591Private Sub GifAnimation_BackColorChanged( ByVal sender As Object , ByVal e As System.EventArgs) Handles MyBase .BackColorChanged
592
593PictureBox1.BackColor =
594
595Me .BackColor
596
597End Sub
598
599Private Sub GifAnimation_Resize( ByVal sender As Object , ByVal e As System.EventArgs) Handles MyBase .Resize
600
601PictureBox1.Top = 0
602
603PictureBox1.Left = 0
604
605If PictureBox1.SizeMode <> PictureBoxSizeMode.AutoSize Then
606
607PictureBox1.Width =
608
609Me .Width
610
611PictureBox1.Height =
612
613Me .Height
614
615Else
616
617Me .Width = PictureBox1.Width
618
619Me .Height = PictureBox1.Height
620
621End If
622
623End Sub
624
625Private Sub GifAnimation_Disposed( ByVal sender As Object , ByVal e As System.EventArgs) Handles MyBase .Disposed
626
627Try
628
629Me .mblnStop = True
630
631If Not mth Is Nothing Then
632
633'停止线程
634
635mth.Abort()
636
637End If
638
639Catch ex As Exception
640
641End Try
642
643End Sub
644
645'帧对象
646
647'用以储存每帧的信息:帧延迟、图像
648
649Private Class GifFrame
650
651Public Frame As Image '帧图像
652
653Public Invert As Integer '帧延迟
654
655Public Sub New ( ByVal img As Image, ByVal time As Integer )
656
657Frame = img
658
659Invert = time
660
661End Sub
662
663End Class
664
665End
666
667Class</system.diagnostics.debuggerstepthrough()></toolboxbitmap("e:\gif_project\gif.ico"),>