2010-11-02 124 views
2

我想在Android應用程序中寫入磁盤,我在一個int [](或者一個字節[]如果你喜歡的)中有一些二進制數據(像素值)。我只想使用少量的處理時間,但希望儘可能多地進行壓縮。我有什麼選擇?快速的方法來壓縮二進制數據?

在許多情況下,數組將包含很多連續的零,所以像RLE壓縮這樣簡單快速的東西可能會工作得很好。雖然我看不到任何Android API函數。如果我必須在Java中循環訪問數組,這將會非常緩慢,因爲大多數Android設備上都沒有JIT。我可以使用NDK,但如果可以的話,我寧願避免這種情況。

+1

真正的問題是什麼是折衷。一般來說,我認爲編寫原始字節會更快,因爲其他任何方法都會使用處理器時間,例如DeflaterOutputStream或GZipOutputStream,特別是對於大量數據可能需要很長時間。 – Nicholas 2010-11-02 03:28:01

+0

我想RLE的開銷會很低,但是我找不到一個API函數來爲我做RLE。在非JIT Android手機上使用Java代碼執行此操作將非常緩慢。 Deflater和GZip似乎使用更復雜的壓縮(即霍夫曼),而且處理起來會慢得多。 – RichardNewton 2010-11-02 04:02:32

+0

對於存在大量相似連續顏色(這似乎是您的情況)的每個像素,可以使用無損PNG格式非常高效地編碼像素值(如在「32位ARGB」中的int []中)接受你想要的無損)。用於無損壓縮的算法behing PNG稱爲DEFLATE(根據wiki,基本上是Huffman + LZ77)。不知道如何強大的Android設備,但編碼一個微小的(PNG屏幕尺寸真的很小,相比我的1920x1200桌面)使用PNG圖片真的不接近數字處理... – SyntaxT3rr0r 2010-11-02 19:07:07

回答

2

DeflatorOutputStream在Java中壓縮1 MB大約需要25 ms。它是一種本地方法,所以JIT應該沒有太大的區別。

你有0.2s或0.5s太慢的要求嗎?

你可以在後臺線程中做到這一點,所以用戶不會注意到需要多長時間?

GZIP基於Deflator + CRC32,因此可能會大致相同或稍慢。

平滑器有幾種模式。在Java中DEFAULT_STRATEGY是最快的,但更簡單的壓縮比如HUFFMAN_ONLY可能會更快。

2

Android有Java的DeflaterOutputStream。這會起作用嗎?

+0

僅供參考:deflate有點慢.... – JimR 2010-11-02 03:10:45

+0

我可以確認它在Android中非常慢。用deflater寫入1Mb數組大約需要0.5s,而且只需要0.01s就可以做爲原始字節! – RichardNewton 2010-11-02 03:25:00

+0

也許'GZipOutputStream'會提供更好的壓縮? – 2010-11-02 03:25:56

0

隨機想法:如果是圖像數據,請嘗試將其保存爲png。標準的java有它,我敢肯定android也會,並且可能會使用本機代碼進行優化。它具有相當不錯的壓縮效果,並且無損。

+0

我試過這個,速度很慢。至少比保存原始字節慢10倍左右。 – RichardNewton 2010-11-02 04:00:39

+0

@RichardNewton:在發表評論之後,我意識到DEFLATE已經被提出。 tulskiy:PNG正在使用DEFLATE,因此如果DEF的OPL速度太慢,這裏就不會出現奇蹟。 – SyntaxT3rr0r 2010-11-02 19:08:48

1

字節數組傳遞給
http://download.oracle.com/javase/6/docs/api/java/io/FileWriter.html
和鏈
http://download.oracle.com/javase/1.4.2/docs/api/java/util/zip/GZIPOutputStream.html

那麼當你需要做反向讀取數據回 http://download.oracle.com/javase/1.4.2/docs/api/java/io/FileReader.html
和鏈
http://download.oracle.com/javase/1.4.2/docs/api/java/util/zip/GZIPInputStream.html

根據文件的大小,您的sa ving你會看到一些壓縮Gzip就是這樣,如果你沒有看到使用緩衝寫入器(這應該是最快的)未壓縮的數據的貿易。此外,如果您使用緩衝作家讀取器進行gzip,也可以加快速度。

1

我不得不在另一個平臺上解決基本相同的問題,我的解決方案是使用修改的LZW壓縮。首先,在32bpp圖像上進行一些差異過濾(類似於PNG)。如果有大面積的普通顏色,這會使大部分圖像變成黑色。然後使用通用的GIF壓縮算法處理濾波後的圖像,就好像它是8bpp一樣。你會得到體面的壓縮,它的工作速度非常快。這將需要在本機代碼(NDK)中運行。在Android上使用本機代碼真的很容易。