標籤:

多幀圖片的數據存儲的問題?

想問一下動態圖片的數據在程序里存儲的形式。為每一幀的圖片存儲數據么?我有好幾張圖片如果連起來做動態效果,我自己要為每一張圖片單獨存一份數據感覺佔用內存蠻多的。有API是能夠讀入多張圖片,然後直接可以設置播放,並且佔用內存還比較小的么。。小白求解。

--------update---------------

看了評論之後我疑問更多了,因為看概念上的解答有點難理解。

gif,apng,sprite實現方案這些,在網上找了一下。

gif,apng這些格式我一直理解為他們是為了方便傳輸所以使用了一些壓縮演算法存到了文件里。

首先給一個具體的場景例子吧:

對於100x100的32位3張圖片,使用3個byte數組,存了3張圖片的數據,大小就是100x100x4x3,約等於120KB(之前寫錯sorry)。

3張圖片已經120kb了。如果是使用了一些演算法形成了一個格式,難道我每次使用這些數據的時候都需要解壓一遍嗎。。好吧apng格式,說是使用了特殊編碼標記了重複的像素,那麼我每次取像素肯定要重複解析這個編碼格式吧。

可能有人會說,你只要解壓一遍不就已經拿到數據了嗎。是的,解壓了一遍之後,相當於我使用120kb來存儲這些數據,然後去使用它們,相當我依然還是使用120k來存儲它們。。。

我的意思是程序運行時,需要大量的圖片數據,如果是壓縮成某種格式的話,解壓時必定有時間消耗。額,並不像用很多內存來存儲,又糾結解壓帶來的時間消耗。。我是不是想多了。

再問一下spirte這個東西,遊戲里2D這個spirte它如果是多幀的它是怎麼做的呢。如果它也是直接存了圖片數據,那麼它也會很佔用內存啊。如果它是壓縮成了更小的數據,那每次這個sprite被繪製的時候應該會在解壓數據上有很多時間消耗啊??不是這樣的么- - 難道中間還有什麼玄機??求解。

---update-----

寫這個提問的,自己隨便假設了一個圖片大小,沒有認真思考就直接寫了,這個是我的失誤,可能有的人沒有注意,很感謝很細心的回答者。但是,指出錯誤的時候注意用語啊!@蕭井陌。


請認真一點

看圖,明明是117k怎麼到你那裡變成120M了?。。。。。。。

真懷疑你怎麼學編程的。。。。

壓縮圖片進顯卡的時候會被解壓,沒錯,就是原始數據多大就佔用多大顯存,額外的,現在的gpu都會對材質有要求,因此無論什麼形狀的圖都是佔用2^n顯存。也就是說100*100實際是128*128,100*1000實際是1024*1024

真的,你現在這樣的水平,根本遠不到擔心什麼時間消耗的地步啊。。。。。

multi-frame sprite stores all frames in memory, 這是當然的了,不然還能存哪?

你對內存的誤區來自於你完全算錯了單位以及完全對內存佔用沒概念。。。

腳踏實地好好學習不要瞎想

sigh......


GIF


WebP


明顯GIF....


除了輪子哥的GIF,還可以考慮做成MP4…(twitter就這麼乾的,似乎體積更小)


確認需求:

1.多張圖片是點陣圖而不是矢量圖形

2.需要連續按順序播放而不是隨機單張顯示

如果滿足以上兩點,那麼最合適的就是把圖像序列編碼成mpeg系列的編碼流,比如h264或者h265。因為該系列編碼演算法用到了幀內編碼和幀間編碼,可以大幅度優化單幀數據量。代價是付出解碼時間。


大約看了下問題。描述的還是不是太清楚。

我估計題主的問題應該是連續多張圖片存儲的時候,除了壓縮減小空間以外,有沒有更加省資源的辦法(解壓耗時)。

壓縮方案的話一般選擇Gif或者Mjpeg編碼。除去這兩個以外,給出幾個簡單我覺得可能適合題主的方案:

1. 內存當中不存儲解壓後的數據,只存儲解壓前的原始數據,等到需要使用該幀的時候再去解壓,這樣內存消耗小,但是在使用某張圖片的時候會有解壓額外耗時。

簡單的處理方法是:你使用第1張圖,假設你知道這張圖後面你需要用那張,則在渲染前者的時候,開始解壓後者,這樣在調用的時候不用額外耗時解壓。

這個方案的話,內存當中一般只有少數幾幀需要調用的幀是解壓後數據,其他圖片保持壓縮前的數據。

2. 我不知道題主內存當中需要存具體多少張圖片。如果數量不是非常大的話,可以更改圖像的採樣格式。比如題主現在用的32位,假設為RGBA格式的採樣。可以簡單的採樣成RGB格式,A通道在需要的時候另外賦值,這樣可以減少1/4的空間。如果改用YUV420的採樣方式,那麼可以省掉5/8的空間,相對來說更改成YUV420採樣的這個轉換時間比壓縮成Mjpeg或者gif要快的多。YUV420和RGB還有RGBA題主自己可以去了解下。

3. 進行簡單的編碼。例如對相鄰像素間的差分,或者兩幀間對應像素的差分進行編碼(如果相鄰幀圖像上看起來差別不大)。類似於DPCM的方法(自行百度),這些不需要頻域轉換和分塊處理,演算法上實現比較簡單。

以上。

如果你需要更高大上的方法可以@vczh問下他在gaclib裡面是怎麼處理大量圖片在內存中的存儲的。


GIF

APNG

MP4

2D遊戲里的Sprite方案

Pixiv的動圖也有開源實現,見金釗立的pixiv的動圖項目的背後 - 二次元雜談 - 知乎專欄


推薦閱讀:

從項目管理上來說,C++ 是否適合做大的項目?
學編程主要是學習什麼(學習重點是什麼?)
國外很多遊戲服務端遊戲邏輯部分用c++開發,上線後沒辦法熱更,他們是怎麼考慮的?
本人有一定的C++基礎,想哪一些項目練手熟練C++,怎麼開始呢?有什麼建議?
有沒有C++的web伺服器?

TAG:C | Direct2D |