该方法为大图像(不是分辨率)抛出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)
答案 0 :(得分:1)
<强> Read Article 强>
图像尺寸:4000 * 3000 in px
图像加载时:4000 * 3000 * 4 =? KB
因此,Android设备的Vitrual堆内存为:32 MB,64 MB,128 MB ......等等
如果您使用:
<application
android:largeHeap="true">
</application>
这将增加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;
}
}
答案 1 :(得分:0)
请尝试使用这些选项属性..
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的数量。 Click here for more details
在应用程序标记
中的Manifest.xml中再添加一个属性机器人:largeHeap =&#34;真&#34;
答案 2 :(得分:0)
请阅读http://developer.android.com/training/displaying-bitmaps/load-bitmap.html如何处理大型位图。
BitmapFactory类提供了几种解码方法 (decodeByteArray(),decodeFile(),decodeResource()等)用于创建 来自各种来源的位图。选择最合适的解码 基于图像数据源的方法。这些方法试图 为构造的位图分配内存,因此很容易 导致OutOfMemory异常