1. 程式人生 > >騰訊技術分享:GIF動圖技術詳解及手機QQ動態表情壓縮技術實踐

騰訊技術分享:GIF動圖技術詳解及手機QQ動態表情壓縮技術實踐

表示 pack iii 技巧總結 fff 設備 思路 表情包 作用

本文來自騰訊前端開發工程師“ wendygogogo”的技術分享,作者自評:“在Web前端摸爬滾打的碼農一枚,對技術充滿熱情的菜鳥,致力為手Q的建設添磚加瓦。”

1、GIF格式的歷史

GIF ( Graphics Interchange Format )原義是“圖像互換格式”,是 CompuServe 公司在1987年開發出的圖像文件格式,可以說是互聯網界的老古董了。

GIF 格式可以存儲多幅彩色圖像,如果將這些圖像((https://www.qcloud.com/document/ ... w.59167.59167.59167)連續播放出來,就能夠組成最簡單的動畫。所以常被用來存儲“動態圖片”,通常時間短,體積小,內容簡單,成像相對清晰,適於在早起的慢速互聯網上傳播。

本來,隨著網絡帶寬的拓展和視頻技術的進步,這種圖像已經漸漸失去了市場。可是,近年來流行的表情包文化,讓老古董 GIF 圖有了新的用武之地。

技術分享圖片 技術分享圖片

表情包通常來源於手繪圖像,或是視頻截取,目前有很多方便制作表情包的小工具。

這類圖片通常具有文件體積小,內容簡單,兼容性好(無需解碼工具即可在各類平臺上查看),對畫質要求不高的特點,剛好符合 GIF 圖的特性。

所以,老古董 GIF 圖有了新的應用場景。

學習交流:

- 即時通訊開發交流3群:185926912[推薦]

- 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM》

(本文同步發布於:http://www.52im.net/thread-2032-1-1.html)

2、相關文章

《騰訊技術分享:社交網絡圖片的帶寬壓縮技術演進之路》

《QQ音樂團隊分享:Android中的圖片壓縮技術詳解(上篇)》

《QQ音樂團隊分享:Android中的圖片壓縮技術詳解(下篇)》

《騰訊原創分享(一):如何大幅提升移動網絡下手機QQ的圖片傳輸速度和成功率》

《騰訊技術分享:騰訊是如何大幅降低帶寬和網絡流量的(圖片壓縮篇)》

《全面掌握移動端主流圖片格式的特點、性能、調優等》

《基於社交網絡的Yelp是如何實現海量用戶圖片的無損壓縮的?》

3、技術需求場景

新的應用場景帶來新的需求,本文所要探究的技術和要解決的問題來源於某個真實的業務場景下——即為用戶批量推送GIF表情包的功能需求。

一批圖像大約有200-500張,以縮略圖列表的形式展示在客戶端。

根據我們使用測試數據進行的統計 GIF 圖表情包的尺寸大部分在200k-500k之間,批量推送的一個重要問題就是數據量太大,因此,我們希望能夠在列表裏展示體積較小的縮略圖,用戶點擊後,再單獨拉取原圖。

傳統的 GIF 縮略圖是靜態的,通常是提取第一幀,但在表情包的情形下,這種方式不足以表達出圖片中信息。

比如下面的例子:

技術分享圖片 技術分享圖片

(左為原始GIF動態圖,右為GIF的第一幀)

第一幀完全看不出重點啊!

所以,我們希望縮略圖也是動態的,並盡可能和原圖相似。

對於傳統圖片來說,文件大小一般和圖片分辨率(尺寸)正相關,所以,生成縮略圖最直觀的思路就是縮小尺寸,resize大法。

但是在 GIF 圖的場合,這個方式不再高效,因為 GIF 圖的文件大小還受到一個重要的因素制約——幀數

以這張柴犬表情為例,原圖寬度200,尺寸1.44M,等比縮放到150之後,尺寸還是1.37M,等比縮放到100,相當於尺寸變為原來的四分之一,體積還是749K。

技術分享圖片 技術分享圖片 技術分享圖片

可見,resize大法的壓縮率並不理想,收效甚微。

而且,我們所得到的大部分表情圖素材,分辨率已經很小了,為了保證客戶端展示效果,不能夠過度減少尺寸,不然圖片會變得模糊。

所以,想要對GIF圖進行壓縮,只能從別的方向入手。

4、GIF技術詳解:拆解GIF格式

4.1 基本

想要壓縮一個文件,首先要了解它是如何存儲的。畢竟,編程的事,萬變不離其宗嘛。

技術分享圖片

作為一種古老的格式,GIF的存儲規則也相對簡單,容易理解。

一個GIF文件主要由以下幾部分組成:

1)文件頭;

2)圖像幀信息;

3)註釋。

下面我們來分別探究每個部分。

4.2 文件頭

GIF格式文件頭和一般文件頭差別不大,也包含有:

1)格式聲明;

2)邏輯屏幕描述塊;

3)全局調色盤;

格式聲明:

技術分享圖片

Signature 為“GIF”3 個字符;Version 為“87a”或“89a”3 個字符。

邏輯屏幕描述塊:

技術分享圖片

前兩字節為像素單位的寬、高,用以標識圖片的視覺尺寸。

Packet裏是調色盤信息,分別來看:

1)Global Color Table Flag為全局顏色表標誌,即為1時表明全局顏色表有定義;

2)Color Resolution 代表顏色表中每種基色位長(需要+1),為111時,每個顏色用8bit表示,即我們熟悉的RGB表示法,一個顏色三字節;

3)Sort Flag 表示是否對顏色表裏的顏色進行優先度排序,把常用的排在前面,這個主要是為了適應一些顏色解析度低的早期渲染器,現在已經很少使用了;

4)Global Color Table 表示顏色表的長度,計算規則是值+1作為2的冪,得到的數字就是顏色表的項數,取最大值111時,項數=256,也就是說GIF格式最多支持256色的位圖,再乘以Color Resolution算出的字節數,就是調色盤的總長度。

這四個字段一起定義了調色盤的信息。

Background color Index 定義了圖像透明區域的背景色在調色盤裏的索引。

Pixel Aspect Ratio 定義了像素寬高比,一般為0。

什麽是調色盤?我們先考慮最直觀的圖像存儲方式,一張分辨率M×N的圖像,本質是一張點陣,如果采用Web最常見的RGB三色方式存儲,每個顏色用8bit表示,那麽一個點就可以由三個字節(3BYTE = 24bit)表達,比如0xFFFFFF可以表示一個白色像素點,0x000000表示一個黑色像素點。

如果我們采用最原始的存儲方式,把每個點的顏色值寫進文件,那麽我們的圖像信息就要占據就是3×M×N字節,這是靜態圖的情況,如果一張GIF圖裏有K幀,點陣信息就是3×M×N×K。

下面這張兔子snowball的表情有18幀,分辨率是200×196,如果用上述方式計算,文件尺寸至少要689K。

技術分享圖片

但實際文件尺寸只有192K,它一定經歷過什麽……

我們可以使用命令行圖片處理工具gifsicle來看看它的信息:

gifsicle -I snowball.gif > snowball.txt

我們得到下面的文本:

5.gif 19 images

logical screen 200x196

global color table (128)

background 93

loop forever

extensions 1

+ image #0 200x196 transparent 93

disposal asis delay 0.04s

+ image #1 200x188 transparent 93

disposal asis delay 0.04s

........

可以看到,global color table 128就是它的調色盤,長度128。

為了確認,我們再用二進制查看器查看一下它的文件頭:

技術分享圖片

可以看到Packet裏的字段的確符合我們的描述。

在實際情況中,GIF圖具有下面的特征:

1)一張圖像最多只會包含256個RGB值;

2)在一張連續動態GIF裏,每一幀之間信息差異不大,顏色是被大量重復使用的。

在存儲時,我們用一個公共的索引表,把圖片中用到的顏色提取出來,組成一個調色盤,這樣,在存儲真正的圖片點陣時,只需要存儲每個點在調色盤裏的索引值。

如果調色盤放在文件頭,作為所有幀公用的信息,就是公共(全局)調色盤,如果放在每一幀的幀信息中,就是局部調色盤。GIF格式允許兩種調色盤同時存在,在沒有局部調色盤的情況下,使用公共調色盤來渲染。

技術分享圖片

這樣,我們可以用調色盤裏的索引來代表實際的顏色值。

一個256色的調色盤,24bit的顏色只需要用9bit就可以表達了。

調色盤還可以進一步減少,128色,64色,etc,相應的壓縮率就會越來越大……

還是以兔子為例,我們還可以嘗試指定它的調色盤大小,對它進行重壓縮:

gifsicle --colors=64 5.gif > 5-64.gif

gifsicle --colors=32 5.gif > 5-32.gif

gifsicle --colors=16 5.gif > 5-16.gif

gifsicle --colors=2 5.gif > 5-2.gif

......

依然使用gifsicle工具,colors參數就是調色盤的長度,得到的結果:

技術分享圖片 技術分享圖片 技術分享圖片 技術分享圖片

註意到了2的時候,圖像已經變成了黑白二值圖。

居然還能看出是個兔子……

所以我們得出結論——如果可以接受犧牲圖像的部分視覺效果,就可以通過減色來對圖像做進一步壓縮。

文件頭所包含的對我們有用的信息就是這些了,我們繼續往後看。

4.3 幀信息描述

幀信息描述就是每一幀的圖像信息和相關標誌位,在逐項了解它之前,我們首先探究一下幀的存儲方式。

我們已經知道調色盤相關的定義,除了全局調色盤,每一幀可以擁有自己的局部調色盤,渲染順序更優先,它的定義方式和全局調色盤一致,只是作用範圍不同。

直觀地說,幀信息應該由一系列的點陣數據組成,點陣中存儲著一系列的顏色值。點陣數據本身的存儲也是可以進行壓縮的,GIF圖所采用的是LZW壓縮算法。

這樣的壓縮和圖像本身性質無關,是字節層面的,文本信息也可以采用(比如常見的gzip,就是LZW和哈夫曼樹的一個實現)。

基於表查詢的無損壓縮是如何進行的?基本思路是,對於原始數據,將每個第一次出現的串放在一個串表中,用索引來表示串,後續遇到同樣的串,簡化為索引來存儲(串表壓縮法)。

舉一個簡單的例子來說明LZW算法的核心思路。

有原始數據:ABCCAABCDDAACCDB

可以看出,原始數據裏只包括4個字符A,B,C,D,四個字符可以用2bit的索引來表示,0-A,1-B,2-C,3-D。

原始字符串存在重復字符,比如AB,CC,都重復出現過。用4代表AB,5代表CC,上面的字符串可以替代表示為45A4CDDAA5DB

這樣就完成了壓縮,串長度從16縮減到12。對原始信息來說,LZW壓縮是無損的。

除了采用LZW之外,幀信息存儲過程中還采取了一些和圖像相關的優化手段,以減小文件的體積,直觀表述就是——公共區域排除、透明區域疊加

這是ImageMagick官方範例裏的一張GIF圖:

技術分享圖片

根據直觀感受,這張圖片的每一幀應該是這樣的:

技術分享圖片

但實際上,進行過壓縮優化的圖片,每一幀是這樣的:

技術分享圖片

首先,對於各幀之間沒有變化的區域進行了排除,避免存儲重復的信息。

其次,對於需要存儲的區域做了透明化處理,只存儲有變化的像素,沒變化的像素只存儲一個透明值。

這樣的優化在表情包中也是很常見的,舉個栗子:

技術分享圖片

上面這個表情的文件大小是278KB,幀數是14

我們試著用工具將它逐幀拆開,這裏使用另一個命令行圖像處理工具ImageMagick:

gm convert source.gif target_%d.gif

技術分享圖片

可以看出,除了第一幀之外,後面的幀都做了不同程度的處理,文件體積也比第一幀小。

這樣的壓縮處理也是無損的,帶來的壓縮比和原始圖像的具體情況有關,重復區域越多,壓縮效果越好,但相應地,也需要存儲一些額外的信息,來告訴引擎如何渲染。

具體包括:

幀數據長寬分辨率,相對整圖的偏移位置;

透明彩色索引——填充透明點所用的顏色;

Disposal Method——定義該幀對於上一幀的疊加方式;

Delay Time——定義該幀播放時的停留時間。

其中值得額外說明的是Disposal Method,它定義的是幀之間的疊加關系,給定一個幀序列,我們用怎樣的方式把它們渲染成起來。

詳細參數定義,可以參考該網站的範例:http://www.theimage.com/animation/pages/disposal.html

Disposal Method和透明顏色一起,定義了幀之間的疊加關系。在實際使用中,我們通常把第一幀當做基幀(background),其余幀向前一幀對齊的方式來渲染,這裏不再贅述。

理解了上面的內容,我們再來看幀信息的具體定義,主要包括:

1)幀分隔符;

2)幀數據說明;

3)點陣數據(它存儲的不是顏色值,而是顏色索引);

4)幀數據擴展(只有89a標準支持)。

1和3比較直觀,第二部分和第四部分則是一系列的標誌位,定義了對於“幀”需要說明的內容。

幀數據說明:

技術分享圖片

除了上面說過的字段之外,還多了一個Interlace Flag,表示幀點陣的存儲方式,有兩種,順序和隔行交錯,為 1 時表示圖像數據是以隔行方式存放的。最初 GIF 標準設置此標誌的目的是考慮到通信設備間傳輸速度不理想情況下,用這種方式存放和顯示圖像,就可以在圖像顯示完成之前看到這幅圖像的概貌,慢慢的變清晰,而不覺得顯示時間過長。

幀數據擴展是89a標準增加的,主要包括四個部分。

1)程序擴展結構(Application Extension):主要定義了生成該gif的程序相關信息

技術分享圖片

2)註釋擴展結構(Comment Extension):一般用來儲存圖片作者的簽名信息

技術分享圖片

3)圖形控制擴展結構(Graphic Control Extension):這部分對圖片的渲染比較重要

技術分享圖片

除了前面說過的Dispose Method、Delay、Background Color之外,User Input用來定義是否接受用戶輸入後再播放下一幀,需要圖像解碼器對應api的配合,可以用來實現一些特殊的交互效果。

4)平滑文本擴展結構(Plain Text Control Extension):

技術分享圖片

89a標準允許我們將圖片上的文字信息額外儲存在擴展區域裏,但實際渲染時依賴解碼器的字體環境,所以實際情況中很少使用。

以上擴展塊都是可選的,只有Label置位的情況下,解碼器才會去渲染。

5、將技術理論付諸應用——給表情包減負

說完了基本原理,用剛才了解到的技術細節來分析一下我們的實際問題。

給大量表情包生成縮略圖,在不損耗原畫質的前提下,盡可能減少圖片體積,節省用戶流量。

之前說過,單純依靠resize大法不能滿足我們的要求,沒辦法,只能損耗畫質了。

主要有兩個思路:減少顏色和減少幀數:

1)減少顏色——圖片情況各異,標準難以控制,而且會造成縮略圖和原圖視覺差異比較明顯。

2)減少幀數——通過提取一些間隔幀,比如對於一張10幀的動畫,提取其中的提取1,3,5,7,9幀。來減少圖片的整體體積,似乎更可行。

先看一個成果,就拿文章開頭的圖做栗子吧:

技術分享圖片 技術分享圖片

看上去連貫性不如以前,但是差別不大,作為縮略圖的視覺效果可以接受,由於幀數減小,體積也可以得到明顯的優化。體積從428K縮到了140K。

但是,在開發初期,我們嘗試暴力間隔提取幀,把幀重新連接壓成新的GIF圖,這時,會得到這樣的圖片:

技術分享圖片

主要有兩個問題:

1)幀數過快;

2)能看到明顯的殘留噪點。

分析我們上面的原理,不難找到原因,正是因為大部分GIF存儲時采用了公共區域排除和透明區域疊加的優化,如果我們直接間隔抽幀,再拼起來,就破壞了原來的疊加規則,不該露出來的幀露出來了,所以才會產生噪點。

所以,我們首先要把原始信息恢復出來。

兩個命令行工具,gifsicle和ImageMagick都提供這樣的命令:

gm convert -coalesce source.gif target_%d.gif

gifsicle --unoptimize source.gif > target.gif

技術分享圖片

還原之後抽幀,重建新的GIF,就可以解決問題2了。

註意重建的時候,可以應用工具再進行對透明度和公共區域的優化壓縮。

至於問題1,也是因為我們沒有對幀延遲參數Delay Time做處理,直接取原幀的參數,幀數減少了,速度一定會加快。

所以,我們需要把抽去的連續幀的總延時加起來,作為新的延遲數據,這樣可以保持縮略圖和原圖頻率一致,看起來不會太過鬼畜,也不會太過遲緩。

提取出每一幀的delay信息,也可以通過工具提供的命令來提取:

gm identify -verbose source.gif

gifsicle -I source.gif

在實際應用中,抽幀的間隔gap是根據總幀數frame求出的:

frame<8 gap=1

frame>40 gap=5

delay值的計算還做了歸一化處理,如果新生成縮略圖的幀間隔平均值大於200ms,則統一加速到均值200ms,同時保持原有節奏,這樣可以避免極端情況下,縮略圖過於遲緩。

6、具體的代碼實踐

本文介紹的算法已經應用於手Q熱圖功能的後臺管理系統等,使用Nodejs編寫。ImageMagick是一個較為常用的圖像處理工具,除了gif還可以處理各類圖像文件,有node封裝的版本可以使用。gifsicle只有可執行版本,在服務器上重新編譯源碼後,采用spawn調起子進程的方式實現。

ImageMagick對於圖片信息的解析較為方便,可以直接得到結構化信息。gifsicle支持命令管道級聯,處理圖片速度較快。實際生產過程中,同時采用了兩個工具。

const {spawn} = require(‘child_process‘);

const image = gm("src2/"+file)

image.identify((err, val) => {

if(!val.Scene){

console.log(file+" has err:"+err)

return

}

let frames_count = val.Scene[0].replace(/\d* of /, ‘‘) * 1

let gap = countGap(frames_count)

let delayList = [];

let totaldelay = 0

if(val.Delay!=undefined){

let iii

for(iii = 0; iii < val.Delay.length; iii ++) {

delayList[iii] = val.Delay[iii].replace(/x\d*/, ‘‘) * 1

totaldelay+=delayList[iii]

}

for(; iii < val.Scene.length; iii ++) {

delayList[iii] = 8

totaldelay+=delayList[iii]

}

}else{

for(let iii = 0; iii < val.Scene.length; iii ++) {

delayList[iii] = 8

totaldelay+=delayList[iii]

}

}

let totalFrame = parseInt(frames_count/gap)

//判斷是否速度過慢,需要進行歸一加速處理

if(totaldelay/totalFrame>20){

let scale =(totalFrame*1.0*20)/totaldelay

for(let iii = 0; iii < delayList.length; iii ++) {

delayList[iii] = parseInt(delayList[iii] * scale)

}

}

let params=[]

params.push("--colors=255")

params.push("--unoptimize")

params.push("src2/"+file)

let tempdelay = delayList[0]

for(let iii = 1; iii < frames_count; iii ++) {

if(i%gap==0){

params.push("-d"+tempdelay)

params.push("#"+(iii-gap))

tempdelay=0

}

tempdelay += delayList[iii]

}

params.push("--optimize=3")

params.push("-o")

params.push("src2/"+file+"gap-keepdelay.gif")

spawn("gifsicle", params, { stdio: ‘inherit‘})

})

測試時,采用該算法隨機選擇50張gif圖進行壓縮,原尺寸15.5M被壓縮到6.0M,壓縮比38%,不過由於該算法的壓縮比率和具體圖片質量、幀數、圖像特征有關,測試數據僅供參考。

本文到這裏就結束了,原來看似簡單的表情包,也有不少文章可做。

謝謝觀看,希望文中介紹的知識和研究方法對你有所啟發。

附錄:來自即時通訊大廠的分享

[1] QQ、微信團隊原創技術文章:

《微信朋友圈千億訪問量背後的技術挑戰和實踐總結》

《騰訊技術分享:騰訊是如何大幅降低帶寬和網絡流量的(圖片壓縮篇)》

《騰訊技術分享:騰訊是如何大幅降低帶寬和網絡流量的(音視頻技術篇)》

《微信團隊分享:微信移動端的全文檢索多音字問題解決方案》

《騰訊技術分享:Android版手機QQ的緩存監控與優化實踐》

《微信團隊分享:iOS版微信的高性能通用key-value組件技術實踐》

《微信團隊分享:iOS版微信是如何防止特殊字符導致的炸群、APP崩潰的?》

《騰訊技術分享:Android手Q的線程死鎖監控系統技術實踐》

《微信團隊原創分享:iOS版微信的內存監控系統技術實踐》

《讓互聯網更快:新一代QUIC協議在騰訊的技術實踐分享》

《iOS後臺喚醒實戰:微信收款到賬語音提醒技術總結》

《騰訊技術分享:社交網絡圖片的帶寬壓縮技術演進之路》

《微信團隊分享:視頻圖像的超分辨率技術原理和應用場景》

《微信團隊分享:微信每日億次實時音視頻聊天背後的技術解密》

《QQ音樂團隊分享:Android中的圖片壓縮技術詳解(上篇)》

《QQ音樂團隊分享:Android中的圖片壓縮技術詳解(下篇)》

《騰訊團隊分享:手機QQ中的人臉識別酷炫動畫效果實現詳解》

《騰訊團隊分享 :一次手Q聊天界面中圖片顯示bug的追蹤過程分享》

《微信團隊分享:微信Android版小視頻編碼填過的那些坑》

《微信手機端的本地數據全文檢索優化之路》

《企業微信客戶端中組織架構數據的同步更新方案優化實戰》

《微信團隊披露:微信界面卡死超級bug“15。。。。”的來龍去脈》

《QQ 18年:解密8億月活的QQ後臺服務接口隔離技術》

《月活8.89億的超級IM微信是如何進行Android端兼容測試的》

《以手機QQ為例探討移動端IM中的“輕應用”》

《一篇文章get微信開源移動端數據庫組件WCDB的一切!》

《微信客戶端團隊負責人技術訪談:如何著手客戶端性能監控和優化》

《微信後臺基於時間序的海量數據冷熱分級架構設計實踐》

《微信團隊原創分享:Android版微信的臃腫之困與模塊化實踐之路》

《微信後臺團隊:微信後臺異步消息隊列的優化升級實踐分享》

《微信團隊原創分享:微信客戶端SQLite數據庫損壞修復實踐》

《騰訊原創分享(一):如何大幅提升移動網絡下手機QQ的圖片傳輸速度和成功率》

《騰訊原創分享(二):如何大幅壓縮移動網絡下APP的流量消耗(下篇)》

《騰訊原創分享(三):如何大幅壓縮移動網絡下APP的流量消耗(上篇)》

《微信Mars:微信內部正在使用的網絡層封裝庫,即將開源》

《如約而至:微信自用的移動端IM網絡層跨平臺組件庫Mars已正式開源》

《開源libco庫:單機千萬連接、支撐微信8億用戶的後臺框架基石 [源碼下載]》

《微信新一代通信安全解決方案:基於TLS1.3的MMTLS詳解》

《微信團隊原創分享:Android版微信後臺保活實戰分享(進程保活篇)》

《微信團隊原創分享:Android版微信後臺保活實戰分享(網絡保活篇)》

《Android版微信從300KB到30MB的技術演進(PPT講稿) [附件下載]》

《微信團隊原創分享:Android版微信從300KB到30MB的技術演進》

《微信技術總監談架構:微信之道——大道至簡(演講全文)》

《微信技術總監談架構:微信之道——大道至簡(PPT講稿) [附件下載]》

《如何解讀《微信技術總監談架構:微信之道——大道至簡》》

《微信海量用戶背後的後臺系統存儲架構(視頻+PPT) [附件下載]》

《微信異步化改造實踐:8億月活、單機千萬連接背後的後臺解決方案》

《微信朋友圈海量技術之道PPT [附件下載]》

《微信對網絡影響的技術試驗及分析(論文全文)》

《一份微信後臺技術架構的總結性筆記》

《架構之道:3個程序員成就微信朋友圈日均10億發布量[有視頻]》

《快速裂變:見證微信強大後臺架構從0到1的演進歷程(一)》

《快速裂變:見證微信強大後臺架構從0到1的演進歷程(二)》

《微信團隊原創分享:Android內存泄漏監控和優化技巧總結》

《全面總結iOS版微信升級iOS9遇到的各種“坑”》

《微信團隊原創資源混淆工具:讓你的APK立減1M》

《微信團隊原創Android資源混淆工具:AndResGuard [有源碼]》

《Android版微信安裝包“減肥”實戰記錄》

《iOS版微信安裝包“減肥”實戰記錄》

《移動端IM實踐:iOS版微信界面卡頓監測方案》

《微信“紅包照片”背後的技術難題》

《移動端IM實踐:iOS版微信小視頻功能技術方案實錄》

《移動端IM實踐:Android版微信如何大幅提升交互性能(一)》

《移動端IM實踐:Android版微信如何大幅提升交互性能(二)》

《移動端IM實踐:實現Android版微信的智能心跳機制》

《移動端IM實踐:WhatsApp、Line、微信的心跳策略分析》

《移動端IM實踐:谷歌消息推送服務(GCM)研究(來自微信)》

《移動端IM實踐:iOS版微信的多設備字體適配方案探討》

《信鴿團隊原創:一起走過 iOS10 上消息推送(APNS)的坑》

《騰訊信鴿技術分享:百億級實時消息推送的實戰經驗》

《IPv6技術詳解:基本概念、應用現狀、技術實踐(上篇)》

《IPv6技術詳解:基本概念、應用現狀、技術實踐(下篇)》

《騰訊TEG團隊原創:基於MySQL的分布式數據庫TDSQL十年鍛造經驗分享》

《微信多媒體團隊訪談:音視頻開發的學習、微信的音視頻技術和挑戰等》

《了解iOS消息推送一文就夠:史上最全iOS Push技術詳解》

《騰訊技術分享:微信小程序音視頻技術背後的故事》

《騰訊資深架構師幹貨總結:一文讀懂大型分布式系統設計的方方面面》

《微信多媒體團隊梁俊斌訪談:聊一聊我所了解的音視頻技術》

《騰訊音視頻實驗室:使用AI黑科技實現超低碼率的高清實時視頻聊天》

《騰訊技術分享:微信小程序音視頻與WebRTC互通的技術思路和實踐》

《手把手教你讀取Android版微信和手Q的聊天記錄(僅作技術研究學習)》

《微信技術分享:微信的海量IM聊天消息序列號生成實踐(算法原理篇)》

《微信技術分享:微信的海量IM聊天消息序列號生成實踐(容災方案篇)》

《騰訊技術分享:GIF動圖技術詳解及手機QQ動態表情壓縮技術實踐》

>> 更多同類文章 ……

[2] 有關QQ、微信的技術故事:

《技術往事:微信估值已超5千億,雷軍曾有機會收編張小龍及其Foxmail》

《QQ和微信兇猛成長的背後:騰訊網絡基礎架構的這些年》

《閑話即時通訊:騰訊的成長史本質就是一部QQ成長史》

《2017微信數據報告:日活躍用戶達9億、日發消息380億條》

《騰訊開發微信花了多少錢?技術難度真這麽大?難在哪?》

《技術往事:創業初期的騰訊——16年前的冬天,誰動了馬化騰的代碼》

《技術往事:史上最全QQ圖標變遷過程,追尋IM巨人的演進歷史》

《技術往事:“QQ群”和“微信紅包”是怎麽來的?》

《開發往事:深度講述2010到2015,微信一路風雨的背後》

《開發往事:微信千年不變的那張閃屏圖片的由來》

《開發往事:記錄微信3.0版背後的故事(距微信1.0發布9個月時)》

《一個微信實習生自述:我眼中的微信開發團隊》

《首次揭秘:QQ實時視頻聊天背後的神秘組織》

《為什麽說即時通訊社交APP創業就是一個坑?》

《微信七年回顧:歷經多少質疑和差評,才配擁有今天的強大》

《前創始團隊成員分享:盤點微信的前世今生——微信成功的必然和偶然》

《即時通訊創業必讀:解密微信的產品定位、創新思維、設計法則等》

《QQ的成功,遠沒有你想象的那麽順利和輕松》

《QQ現狀深度剖析:你還認為QQ已經被微信打敗了嗎?》

《[技術腦洞] 如果把14億中國人拉到一個微信群裏技術上能實現嗎?》

>> 更多同類文章 ……

(本文同步發布於:http://www.52im.net/thread-2032-1-1.html)

騰訊技術分享:GIF動圖技術詳解及手機QQ動態表情壓縮技術實踐