GIF簡介
成都創(chuàng)新互聯(lián)公司成立于2013年,先為任丘等服務建站,任丘等地企業(yè),進行企業(yè)商務咨詢服務。為任丘企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務解決您的所有建站問題。要實現(xiàn)合并為GIF文件,首先要對GIF文件格式有所了解。GIF由 CompuServe在1987年提出,官方文檔gif89a標準將GIF分成很多區(qū)塊,并給出的GIF語法格式如下:
::= Header * Trailer ::= Logical Screen Descriptor [Global Color Table] ::= |
::= [Graphic Control Extension]
::= | Plain Text Extension ::= Image Descriptor [Local Color Table] Image Data ::= Application Extension | Comment Extension
有人用圖片的形式整理了語法,看起來更直觀:
其中很多區(qū)塊是可以重復的,它的圖像數(shù)據(jù)模塊采用了LZW算法,LZW壓縮算法是Compuserv所開發(fā)的一種免費算法,然而詭異的是這種算法忽然成了Unisys公司的專利,據(jù)Unisys公司稱,他們已注冊了LZW算法中的W部分。如果要開發(fā)生成(或顯示)圖像互換格式文件的程序,則需向該公司支付版稅。Unisys公司的行為曾引起部份開放源代碼社區(qū)發(fā)起“Burn all GIFs”的運動抵制使用GIF。因此,這刺激CompuServe 公司開發(fā)了PNG(Portable Network Graphics,便攜網(wǎng)絡圖形)標準,它一方面滿足了市場對更少的法規(guī)限制的需要,另一方面也帶來了更少的技術上的限制,如顏色的數(shù)量等。
已有實現(xiàn)
在CodeProject上,有人已經實現(xiàn)了C#版本的GIF圖片生成器,代碼很多,也很好用。但是對于GIF格式標準不熟悉的人,是看不懂代碼的。它的實現(xiàn)完全是采用文件流的方式,根據(jù)GIF格式編碼語法,生成文件流,甚至還實現(xiàn)了LZW算法來壓縮圖像。因此這個程序是非常好的學習參考資料。
GDI實現(xiàn)
微軟的GDI(Graphics Device Interface)是一套很好的圖像開發(fā)類庫,因此本人覺得為啥那麻煩要用純文件流的方式去創(chuàng)建GIF,直接用GDI方法去創(chuàng)建GIF不就可以了,微軟應該提供這方面的接口的。于是網(wǎng)上找到一些示例代碼。實現(xiàn)動態(tài)GIF,有個方法就是Image.SaveAdd,它可以實現(xiàn)在現(xiàn)有圖片上再加一幀,可是難點在于設置延時時間。對于第一幀的延時的設置很容易實現(xiàn),但是對于第二幀的延時,一直無效。百思不得其解。
后去Stackoverflow問了一下,得到的回復是微軟GDI不支持這種GIF延時,同樣百思不得其解。
于是只好土洋結合,對于生成好的GIF,修改其二進制數(shù)據(jù),以此實現(xiàn)延時。
用GDI實現(xiàn)設置循環(huán)次數(shù)和加入幀的代碼,不算復雜。C#中可以通過代碼修改圖片的一些GIF屬性,但是不了解GIF編碼格式的人還是寫不出來的,主要是不知道如何賦值,因為微軟官方文檔也沒給出這部分說明。
比如代碼
PropertyItem LoopCount = img.GetPropertyItem(0x5101);//循環(huán)次數(shù) //可以去http://msdn.microsoft.com/en-us/library/system.drawing.imaging.propertyitem.id.aspx/css查詢 LoopCount.Value = BitConverter.GetBytes(loopCount); img.SetPropertyItem(LoopCount);
0x5101根據(jù)文檔是循環(huán)次數(shù)的屬性。該屬性設置循環(huán)次數(shù)。GIF文檔中,該屬性在應用擴展塊中,占2個字節(jié)16位,按低位高位的順序排列,是一個無符號的整型。如果01 00表示16進制的0x0001,如果設成00 00 則表示0,循環(huán)無限次。
循環(huán)次數(shù)可以使用GDI控制,但是延時時間在第二幀后就失效了。因此手動更改。
延時時間的屬性在圖像控制擴展塊,對于每一幀圖像,都有對應的圖像控制擴展塊,修改其中的字節(jié)即可。圖像控制擴展塊以21 F9開頭,在緊挨著的第三第四字節(jié)就是設置延時時間的,單位是百分之一秒。同樣的這2個字節(jié)也是按低位高位順序排列的,比如是C8 00,則表示0x00C8=200,也就是延時2秒。
根據(jù)以上理論就可以容易的寫出設置延時時間的代碼。
byte[] bytes = File.ReadAllBytes(savefile); byte[] delaybyte = BitConverter.GetBytes(delay);//轉成16位無符號字節(jié)數(shù)組。該數(shù)組肯定只有2個元素 for (int i = 0; i < bytes.Length - 1; i++) { if (bytes[i] == 0x21 && bytes[i + 1] == 0xf9)//GraphicsControlExtension 開始標志 { bytes[i + 4] = delaybyte[0];//這兩位就是定義延遲時間的,修改就可以了。 bytes[i + 5] = delaybyte[1]; } }
采用GDI方式,比較簡單,偷懶,使用微軟做好的現(xiàn)成代碼,再稍稍改動就可以了。
參考資料
http://www.matthewflickinger.com/lab/whatsinagif/bits_and_bytes.asp
http://www.w3.org/Graphics/GIF/spec-gif89a.txt
http://www.codeproject.com/Articles/11505/NGif-Animated-GIF-Encoder-for-NET
http://en.wikipedia.org/wiki/Graphics_Device_Interface
http://www.cnblogs.com/zhengye/articles/2193006.html
《多媒體技術基礎》 林福宗
附件:http://down.51cto.com/data/2363255另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。