gif 格式
現(xiàn)在使用gif的場(chǎng)景有很多,很多老師喜歡在課件添加 gif 圖片
在開(kāi)始講gif之前,先告訴大家 gif 的格式。
請(qǐng)看圖片,gif 圖分為圖片文件頭(File Header),gif信息(GIF Data Stream)和文件結(jié)尾(Trailer)三個(gè)部分,最主要的是 gif 信息。gif信息是由控制塊(Control Block)和數(shù)據(jù)塊(Data Sub-blocks)組成的。
文件頭包括了GIF文件署名(Signature)和版本號(hào)(Version),文件署名就是“gif”字符串,版本號(hào)有 87a 和 89a 兩個(gè)。表示提出的時(shí)間,但是現(xiàn)在使用的圖片格式有很多,很難說(shuō)有支持現(xiàn)在全部格式的庫(kù)。
gif 信息
gif 信息包括邏輯屏幕標(biāo)識(shí)符(Logical Screen Descriptor),全局顏色列表(Global Color Table),圖片塊
邏輯屏幕標(biāo)識(shí)符
邏輯屏幕標(biāo)識(shí)符定義了 gif 圖片的邏輯屏幕寬度、邏輯屏幕高度,顏色深度,背景色有無(wú)全局顏色列表(Global Color Table)和顏色列表的索引數(shù)(Index Count),請(qǐng)看下表
需要知道,圖片的位是反過(guò)來(lái)寫(xiě)的,也就是從屏幕標(biāo)識(shí)符的第5個(gè)byte開(kāi)始,第0-2位表示的是pixel( 全局顏色列表大小,pixel+1確定顏色列表的索引數(shù)(2的pixel+1次方)),第3位是 s 分類(lèi)標(biāo)志(Sort Flag),如果置位表示全局顏色列表分類(lèi)排列。然后就是 cr ,顏色深度(Color ResoluTion),cr+1確定圖象的顏色深度。m - 全局顏色列表標(biāo)志(Global Color Table Flag),當(dāng)置位時(shí)表示有全局顏色列表,pixel值有意義。
全局顏色列表
全局顏色列表必須緊跟在邏輯屏幕標(biāo)識(shí)符后面,每個(gè)顏色列表索引條目由三個(gè)字節(jié)組成,按R、G、B的順序排列。
看到名字可以想到,有全局顏色列表也有局部顏色表,因?yàn)橐粡垐D像最多只會(huì)包含256個(gè)RGB值,在一張連續(xù)動(dòng)態(tài)GIF里,每一幀之間信息差異不大,顏色是被大量重復(fù)使用的。在存儲(chǔ)時(shí),我們用一個(gè)公共的索引表,把圖片中用到的顏色提取出來(lái),這就是顏色列表,所以可以減少存放的數(shù)據(jù),因?yàn)轭伾枰褂?4 個(gè) byte 來(lái)放。
假如一個(gè)圖片使用了3個(gè)顏色 x0、x1、x2 ,如果沒(méi)有使用全局顏色列表,圖片長(zhǎng)度1000,寬度1000那么每個(gè)點(diǎn)都存放顏色,一個(gè)顏色需要 4 byte (rbg和透明),存放的空間就為 1000*1000*4 ,而有顏色表就直接指定顏色表的位置就可以,可以剩下3倍的空間。
圖片塊
這里就是gif 的數(shù)據(jù),可以有很多張圖片,圖片之間存儲(chǔ)連續(xù),圖片里面包括控制塊和圖片數(shù)據(jù)。
這里的圖片叫幀,他的信息包括:
幀分隔符
幀數(shù)據(jù)說(shuō)明
點(diǎn)陣數(shù)據(jù)(它存儲(chǔ)的不是顏色值,而是顏色索引)
幀數(shù)據(jù)擴(kuò)展(只有89a標(biāo)準(zhǔn)支持)
圖片的控制塊包括圖片的圖象標(biāo)識(shí)符、圖象的性質(zhì),一共需要10字節(jié),請(qǐng)看下面
m - 局部顏色列表標(biāo)志(Local Color Table Flag) 置位時(shí)標(biāo)識(shí)緊接在圖象標(biāo)識(shí)符之后有一個(gè)局部顏色列表,供緊跟在它之后的一幅圖象使用;值否時(shí)使用全局顏色列表,忽略pixel值。
i - 交織標(biāo)志(Interlace Flag),置位時(shí)圖象數(shù)據(jù)使用連續(xù)方式排列,否則使用順序排列。
s - 分類(lèi)標(biāo)志(Sort Flag),如果置位表示緊跟著的局部顏色列表分類(lèi)排列.
r - 保留,必須初始化為0.
pixel - 局部顏色列表大小(Size of Local Color Table),pixel+1就為顏色列表的位數(shù)
和全局顏色列表不相同的,局部顏色列表需要有 x 方向偏移、y 方向偏移、圖象寬度、圖象高度
圖片塊包括圖片數(shù)據(jù)和圖形控制擴(kuò)展。
圖形控制擴(kuò)展(Graphic Control Extension)
包括
擴(kuò)展塊標(biāo)識(shí) Extension Introducer - 標(biāo)識(shí)這是一個(gè)擴(kuò)展塊,固定值0x21
圖形控制擴(kuò)展標(biāo)簽 Graphic Control Label - 標(biāo)識(shí)這是一個(gè)圖形控制擴(kuò)展塊,固定值0xF9
塊大小 Block Size - 不包括塊終結(jié)器,固定值4
處置方法
i - 用戶(hù)輸入標(biāo)志(Use Input Flag):指出是否期待用戶(hù)有輸入之后才繼續(xù)進(jìn)行下去,置位表示期待,值否表示不期待。用戶(hù)輸入可以是按回車(chē)鍵、鼠標(biāo)點(diǎn)擊等,可以和延遲時(shí)間一起使用,在設(shè)置的延遲時(shí)間內(nèi)用戶(hù)有輸入則馬上繼續(xù)進(jìn)行,或者沒(méi)有輸入直到延遲時(shí)間到達(dá)而繼續(xù)
t - 透明顏色標(biāo)志(Transparent Color Flag):置位表示使用透明顏色
延遲時(shí)間 Delay Time - 單位1/100秒,如果值不為1,表示暫停規(guī)定的時(shí)間后再繼續(xù)往下處理數(shù)據(jù)流
透明色索引 Transparent Color Index - 透明色索引值
塊終結(jié)器 Block Terminator - 標(biāo)識(shí)塊終結(jié),固定值0
處置方法(Disposal Method):指出處置圖形的方法,當(dāng)值為:
0 - 不使用處置方法
1 - 不處置圖形,把圖形從當(dāng)前位置移去
2 - 回復(fù)到背景色
3 - 回復(fù)到先前狀態(tài)
4-7 - 自定義
處置方法、i、t 在一個(gè)byte,其中第0bit為t,bit1為i,bit2-4處置方法
所有的控制都可以這樣跳過(guò),先讀byte0,是否是擴(kuò)展塊,固定值0x21,然后讀取byte1,可以知道是什么控制。接著就是讀取長(zhǎng)度byte2,跳過(guò)他就可以拿到下一個(gè)數(shù)據(jù)塊或控制。如果拿到數(shù)據(jù)塊,那么數(shù)據(jù)塊byte0就是表示數(shù)據(jù)長(zhǎng)度,跳過(guò)他就可以拿到下一個(gè)數(shù)據(jù)塊或控制。
byte0 擴(kuò)展塊
byte1 信息
byte2 信息長(zhǎng)度
byte n n的大小為信息長(zhǎng)度+2,這是塊終結(jié)器。
讀取到 byte n 下一個(gè)就可以重復(fù)判斷是擴(kuò)展塊還是數(shù)據(jù)。
圖片數(shù)據(jù)
圖片數(shù)據(jù)如下
編碼長(zhǎng)度 LZW Code Size - LZW壓縮的編碼長(zhǎng)度,也就是要壓縮的數(shù)據(jù)的位數(shù)
… 數(shù)據(jù)塊開(kāi)始
塊大小 數(shù)據(jù)塊,如果需要可重復(fù)多次
編碼數(shù)據(jù)
… 數(shù)據(jù)塊結(jié)束
塊終結(jié)器 - 一個(gè)圖象的數(shù)據(jù)編碼結(jié)束,固定值0
因?yàn)間if使用lzw壓縮算法,所以解析gif需要先解析lzw,然后就可以得到圖片的數(shù)據(jù)。
gif 會(huì)把相同的圖片作為索引,放在lzw,之后相同的數(shù)據(jù)就使用索引拿到,這樣可以減少文件大小。
關(guān)于 lzw,請(qǐng)看 http://blog.csdn.net/abcjennifer/article/details/7995426
本文的格式大部分參考 http://www.cnblogs.com/think/archive/2006/04/12/372942.html
關(guān)于 gif 解析請(qǐng)看
wpf 如何使用 Magick.NET 播放 gif 圖片
wpf GifBitmapDecoder 解析 gif 格式
gif的故事:解剖表情動(dòng)圖的構(gòu)成
一個(gè) gif 解析的方法 https://github.com/vurdalakov/abandoned/tree/master/gifdotnet/src/GifDotNet
我搭建了自己的博客 https://blog.lindexi.com/ 歡迎大家訪(fǎng)問(wèn),里面有很多新的博客。只有在我看到博客寫(xiě)成熟之后才會(huì)放在csdn或博客園,但是一旦發(fā)布了就不再更新
如果在博客看到有任何不懂的,歡迎交流,我搭建了 dotnet 職業(yè)技術(shù)學(xué)院 歡迎大家加入
本作品采用知識(shí)共享署名-非商業(yè)性使用-相同方式共享 4.0 國(guó)際許可協(xié)議進(jìn)行許可。歡迎轉(zhuǎn)載、使用、重新發(fā)布,但務(wù)必保留文章署名林德熙(包含鏈接:http://blog.csdn.net/lindexi_gd ),不得用于商業(yè)目的,基于本文修改后的作品務(wù)必以相同的許可發(fā)布。如有任何疑問(wèn),請(qǐng)與我聯(lián)系。
總結(jié)
- 上一篇: nextcloud开放注册-添加注册功能
- 下一篇: 码元、符号、波特率、比特率等概念的了解