中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#實現合并多個圖像文件為一個動態GIF

發布時間:2020-06-23 21:06:36 來源:網絡 閱讀:2548 作者:cnn237111 欄目:編程語言

GIF簡介

要實現合并為GIF文件,首先要對GIF文件格式有所了解。GIF由 CompuServe在1987年提出,官方文檔gif89a標準將GIF分成很多區塊,并給出的GIF語法格式如下:

<GIF Data Stream> ::=     Header <Logical Screen> <Data>* Trailer

<Logical Screen> ::=      Logical Screen Descriptor [Global Color Table]

<Data> ::=                <Graphic Block>  |
                          <Special-Purpose Block>

<Graphic Block> ::=       [Graphic Control Extension] <Graphic-Rendering Block>

<Graphic-Rendering Block> ::=  <Table-Based Image>  |
                               Plain Text Extension

<Table-Based Image> ::=   Image Descriptor [Local Color Table] Image Data

<Special-Purpose Block> ::=    Application Extension  |
                               Comment Extension

有人用圖片的形式整理了語法,看起來更直觀:

C#實現合并多個圖像文件為一個動態GIF

其中很多區塊是可以重復的,它的圖像數據模塊采用了LZW算法,LZW壓縮算法是Compuserv所開發的一種免費算法,然而詭異的是這種算法忽然成了Unisys公司的專利,據Unisys公司稱,他們已注冊了LZW算法中的W部分。如果要開發生成(或顯示)圖像互換格式文件的程序,則需向該公司支付版稅。Unisys公司的行為曾引起部份開放源代碼社區發起“Burn all GIFs”的運動抵制使用GIF。因此,這刺激CompuServe 公司開發了PNG(Portable Network Graphics,便攜網絡圖形)標準,它一方面滿足了市場對更少的法規限制的需要,另一方面也帶來了更少的技術上的限制,如顏色的數量等。

已有實現

在CodeProject上,有人已經實現了C#版本的GIF圖片生成器,代碼很多,也很好用。但是對于GIF格式標準不熟悉的人,是看不懂代碼的。它的實現完全是采用文件流的方式,根據GIF格式編碼語法,生成文件流,甚至還實現了LZW算法來壓縮圖像。因此這個程序是非常好的學習參考資料。

GDI實現

微軟的GDI(Graphics Device Interface)是一套很好的圖像開發類庫,因此本人覺得為啥那麻煩要用純文件流的方式去創建GIF,直接用GDI方法去創建GIF不就可以了,微軟應該提供這方面的接口的。于是網上找到一些示例代碼。實現動態GIF,有個方法就是Image.SaveAdd,它可以實現在現有圖片上再加一幀,可是難點在于設置延時時間。對于第一幀的延時的設置很容易實現,但是對于第二幀的延時,一直無效。百思不得其解。

后去Stackoverflow問了一下,得到的回復是微軟GDI不支持這種GIF延時,同樣百思不得其解。

于是只好土洋結合,對于生成好的GIF,修改其二進制數據,以此實現延時。

用GDI實現設置循環次數和加入幀的代碼,不算復雜。C#中可以通過代碼修改圖片的一些GIF屬性,但是不了解GIF編碼格式的人還是寫不出來的,主要是不知道如何賦值,因為微軟官方文檔也沒給出這部分說明。

比如代碼

PropertyItem LoopCount = img.GetPropertyItem(0x5101);//循環次數 //可以去http://msdn.microsoft.com/en-us/library/system.drawing.imaging.propertyitem.id.aspx/css查詢
LoopCount.Value = BitConverter.GetBytes(loopCount);
img.SetPropertyItem(LoopCount);

0x5101根據文檔是循環次數的屬性。該屬性設置循環次數。GIF文檔中,該屬性在應用擴展塊中,占2個字節16位,按低位高位的順序排列,是一個無符號的整型。如果01 00表示16進制的0x0001,如果設成00 00 則表示0,循環無限次。

循環次數可以使用GDI控制,但是延時時間在第二幀后就失效了。因此手動更改。

延時時間的屬性在圖像控制擴展塊,對于每一幀圖像,都有對應的圖像控制擴展塊,修改其中的字節即可。圖像控制擴展塊以21 F9開頭,在緊挨著的第三第四字節就是設置延時時間的,單位是百分之一秒。同樣的這2個字節也是按低位高位順序排列的,比如是C8 00,則表示0x00C8=200,也就是延時2秒。

根據以上理論就可以容易的寫出設置延時時間的代碼。

byte[] bytes = File.ReadAllBytes(savefile);
byte[] delaybyte = BitConverter.GetBytes(delay);//轉成16位無符號字節數組。該數組肯定只有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方式,比較簡單,偷懶,使用微軟做好的現成代碼,再稍稍改動就可以了。

參考資料

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
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

庆云县| 基隆市| 康定县| 揭西县| 临夏县| 江北区| 桑日县| 根河市| 卓尼县| 万年县| 四子王旗| 韶关市| 交口县| 宁国市| 昭苏县| 五寨县| 定远县| 闽侯县| 包头市| 娄烦县| 古交市| 喀喇沁旗| 云阳县| 荆门市| 佳木斯市| 黄山市| 望都县| 荥阳市| 平顺县| 个旧市| 始兴县| 朝阳区| 双流县| 宝山区| 宾川县| 开原市| 玉山县| 鄂托克前旗| 黑河市| 遵义县| 民和|