2013-05-07 17 views
0

這可能聽起來很具體......而且有點。如何在Android 2.3上加載2048x2048圖像?

我真的需要在Android 2.3上加載2048x2048 32位圖像(特別是Nexus One和Xperia Play,當前形式的應用程序因內存不足錯誤而崩潰)。

Android 2.2的它加載的罰款,並經過2.3加載所有的機器人也沒關係,有些2.3的設備(通常是用巨大的堆)還加載它的罰款。

特別是Xperia Play報告(通過OpenGL),它可以加載圖像高達4096x4096,並使用Marmalade SDK我真的可以加載瘋狂的巨大圖像,其中許多,很容易使用15​​0MB的內存。

但我想不出如何與Java該設備上加載一個2048x2048的圖像,它只是拋出我這個錯誤:

05-07 17:41:25.202:E/GraphicsJNI(27847):VM贏得」別讓我們分配30965760個字節

編輯:別告訴我使用較低的分辨率,我會引用自己:

I really need to load a 2048x2048 32-bit image on Android 2.3

較低的採樣圖像不爲2048x2048,也不是一個較高的,或經調節的一個,或一個mipmap版本,或其他任何...我需要加載這些圖像的方式是PE荒漠化問題。

+0

您是否可以降低圖像質量(假設它是jpg),使其不佔用太多內存? – Renan 2013-05-07 21:00:21

+1

這是一個PNG,以及它在未壓縮時所吃的30mb內存。 (壓縮它是500kb) – speeder 2013-05-07 21:05:20

回答

4

編輯

既然你不想按比例縮小圖片,這是可以理解的,你可能要考慮降低您加載到內存中的圖像的質量/ sizeInMbs。

例如,你說你有2048 * 2048,其正在約爲30 MB的圖像,這是該尺寸的圖像相當大的。

在那裏他的使用是1280 * 752,但在大小隻有幾百KBS圖片看看這個demo from Romain Guy。儘管尺寸很小,但圖像看起來非常清晰,並且在working demo上很乾淨。


首先,裝載2048 * 2048的圖像變成小屏幕設備,如你提到的那些設備是一種資源的浪費。下面是關於如何高效地縮放和加載大圖的fully detailed tutorial的鏈接。

請記住,儘可能縮放圖像,Android開發人員網站提到:「分辨率更高的圖像沒有提供任何明顯的好處,但仍佔用寶貴的內存並導致額外的性能開銷由於額外的飛行縮放。「

第一步,通過使用BitmapFactory獲取圖像維數。選項:

BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inJustDecodeBounds = true; 
BitmapFactory.decodeResource(getResources(), R.id.myimage, options); 
int imageHeight = options.outHeight; 
int imageWidth = options.outWidth; 
String imageType = options.outMimeType; 

第二步,找出一個採樣因子:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, 
    int reqWidth, int reqHeight) { 

// First decode with inJustDecodeBounds=true to check dimensions 
final BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inJustDecodeBounds = true; 
BitmapFactory.decodeResource(res, resId, options); 

// Calculate inSampleSize 
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 

// Decode bitmap with inSampleSize set 
options.inJustDecodeBounds = false; 
return BitmapFactory.decodeResource(res, resId, options); 
} 
+0

圖像實際上是一個動畫圖像圖集,我使用它的整個分辨率,實際上最終結果(幀)已經顯示了一半的分辨率,如果我使用了設備適當的分辨率,我需要Xperia Play上的4096x4096和平板電腦上的8192x8192 ... – speeder 2013-05-07 21:27:52

+0

看看更新後的回覆 – 2013-05-07 21:41:47

-1

您:多少來按比例縮小圖片

public static int calculateInSampleSize(
     BitmapFactory.Options options, int reqWidth, int reqHeight) { 
// Raw height and width of image 
final int height = options.outHeight; 
final int width = options.outWidth; 
int inSampleSize = 1; 

if (height > reqHeight || width > reqWidth) { 

    // Calculate ratios of height and width to requested height and width 
    final int heightRatio = Math.round((float) height/(float) reqHeight); 
    final int widthRatio = Math.round((float) width/(float) reqWidth); 

    // Choose the smallest ratio as inSampleSize value, this will guarantee 
    // a final image with both dimensions larger than or equal to the 
    // requested height and width. 
    inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; 
} 

return inSampleSize; 
} 

最後,你可以用它縮小將不得不縮小您的位圖以減少內存消耗。 我建議你看看關於Loading Large Bitmaps Efficiently這件事的官方文檔。

作爲一個額外的建議,不要忘記回收所有未使用的位圖。這將有助於GC更快地釋放內存。

-1

如果您需要任何理由(而不是在降低分辨率的daniel_c05的答案)的全分辨率,你不能使用OpenGL(爲什麼不呢?這是爲這個完美的),

  1. 將它分成瓷磚
  2. 一次只能加載和渲染幾個瓷磚
  3. 如果您需要高效縮放,請預先縮放圖像(mipmap)並平鋪每個級別。

但是真的,如果你在那個規模下工作並且想要速度,你應該使用OpenGL。

+0

OpenGL可以以某種方式直接從apk中載入?跳過堆? – speeder 2013-05-07 21:25:48

+0

是的,沒有。您可以像加載它們到Bitmap一樣加載apk中的資源。也就是說,你不能使用相同類型的壓縮,所以你通常堅持使用未壓縮的資源或使用你自己的PNG庫。真正的分裂發生的原因是1)這些圖像從未擊中Java land,2)它們可以卸載到GPU,甚至不需要佔用任何RAM。 如果你正在做這樣的事情,請使用一個好的3D庫。我衷心推薦libgdx。 – Delyan 2013-05-07 21:29:57

+0

我真的不明白...你如何將png文件直接加載到OpenGL並跳過堆? – speeder 2013-05-07 21:32:22

1

字節對於2048x2048的分辨率聽起來相當大。

難道圖像是每個通道32位而不是每個通道8位?當我要求人們使用32位PNG時,常見錯誤是他們在Photoshop等程序中選擇32位/通道(128位圖像)模式。

紅色(8位)+綠(8位)+藍(8位)+阿爾法(8位)=一個32位圖像。

相關問題