用于大图像的Android OutOfMemoryError

该方法为大图像(不是分辨率)抛出OutOfMemoryError我有12张MP照片,所有照片大小不同(1.5MB,2.5MB,3.2MB,4.1MB)等等,所有这些照片的分辨率相同4000 x 3000(像素)。

缩放器方法适用于尺寸小于3MB的图像,但是对于那些大于3MB的图像,它会抛出OutOfMemoryError我不知道什么可以解决它,我的应用程序主要用于调整大图像的大小,这真的让我无处可去。

缩放器方法是:

public File resizeBitmap(String imPath, int reqSize) { File fl = null; try{ // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(imPath, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqSize); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; Bitmap saveImg = BitmapFactory.decodeFile(imPath, options); //save resized image String tmpName = "IMG_"+String.valueOf(System.currentTimeMillis()) + ".jpg"; fl = fileCache.getRawFile(tmpName); FileOutputStream fos = new FileOutputStream(fl); saveImg.compress(Bitmap.CompressFormat.JPEG, 95, fos); saveImg.recycle(); return fl; } catch (Throwable eex){ eex.printStackTrace(); if(eex instanceof OutOfMemoryError) { runOnUiThread(new Runnable() { public void run() { Toast.makeText(Resizer.this, "Memory ran out", Toast.LENGTH_SHORT).show(); } }); } return null; } } //Method for calculating insamplesize public int calculateInSampleSize(BitmapFactory.Options options, int reqSize) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; Log.i("width",""+width); Log.i("height",""+height); int inSampleSize = 1; if (height > reqSize || width > reqSize) { if (width > height) { inSampleSize = Math.round((float) height / (float) reqSize); } else { inSampleSize = Math.round((float) width / (float) reqSize); } } return inSampleSize; 

}

 //Stacktrace 04-11 09:01:19.832: W/System.err(8832): java.lang.OutOfMemoryError 04-11 09:01:19.953: W/System.err(8832): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 04-11 09:01:19.972: W/System.err(8832): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:529) 04-11 09:01:19.993: W/System.err(8832): at com.scale.app.Resizer.resizeBitmap(Resizer.java:1290) 

阅读文章

图像尺寸:4000 * 3000 in px

当图像加载:4000 * 3000 * 4 =? KB

因此,Android设备的Vitrual堆内存是:32 MB,64 MB,128 MB ……等等

如果您使用:

   

这将增加VHM双倍(如果32 MB = 2 * 32 MB)。 这样做不会是一个很好的方法,影响操作系统

您需要减小图像的大小。


使用下面的类并传递图像的路径和宽度,高度你想要的

Bitmap bitmap = BitmapSize.getDecodedBitmap(path,400,400);

类::::

 public class BitmapSize{ public static Bitmap getDecodedBitmap(String path, float target_width, float target_height) { Bitmap outBitmap = null; try { Options decode_options = new Options(); decode_options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path,decode_options); //This will just fill the output parameters int inSampleSize = calculateInSampleSize(decode_options, target_width, target_height); Options outOptions = new Options(); outOptions.inJustDecodeBounds = false; outOptions.inSampleSize = inSampleSize; outOptions.inPreferredConfig = Bitmap.Config.ARGB_8888; outOptions.inScaled = false; Bitmap decodedBitmap = BitmapFactory.decodeFile(path,outOptions); outBitmap = Bitmap.createScaledBitmap(decodedBitmap,// (int)target_width, (int)target_height, true); (int)((float)decodedBitmap.getWidth() / inSampleSize), (int)((float)decodedBitmap.getHeight() / inSampleSize), true); System.out.println("Decoded Bitmap: Width " + outBitmap.getWidth() + " Height = " + outBitmap.getHeight() + " inSampleSize = " + inSampleSize); } catch (Exception e) { // TODO: handle exception } return outBitmap; } public static int calculateInSampleSize(Options options, float reqWidth, float reqHeight) { final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } } 

请阅读http://developer.android.com/training/displaying-bitmaps/load-bitmap.html如何处理大型位图。

BitmapFactory类提供了几种解码方法(decodeByteArray(),decodeFile(),decodeResource()等),用于从各种源创建位图。 根据图像数据源选择最合适的解码方法。 这些方法尝试为构造的位图分配内存,因此很容易导致OutOfMemoryexception

请尝试使用这些选项属性..

  BitmapFactory.Options opts=new BitmapFactory.Options(); opts.inDither=false; //Disable Dithering mode opts.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared opts.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future opts.inTempStorage=new byte[32 * 1024]; opts.inSampleSize = 1; 

要降低图像文件的质量,请增加opts.inSampleSize的数量 点击这里了解更多详情

并在Manifest.xml中的application tag中添加一个属性

机器人:largeHeap = “真”