我目前正在使用此处的代码解码Android中的图片:
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
我使用1024的MinSize进行解码,这在Galaxy S4,Galaxy Note 3,Galaxy Tab 3,Xperia Z和HTC One M8等高端设备上运行得非常好。
我遇到的唯一问题是在一些较弱的手机(如Galaxy S2和Nexus One)中崩溃应用程序。
我正在尝试将图像缩减为最小宽度和高度为1024像素,而在Galaxy S2和Nexus One上,当我尝试加载文件时,它会抛出OutOfMemoryError
。
有没有办法计算出合适的图像尺寸,不会让Galaxy S2和Nexus One崩溃,但仍然可以在Galaxy S4等高端设备上保持适当的质量?
Galaxy S2上崩溃的堆栈跟踪如下:
06-10 21:17:18.345 I/dalvikvm-heap( 5973): Forcing collection of SoftReferences for 5992720-byte allocation
06-10 21:17:18.380 D/dalvikvm( 5973): GC_BEFORE_OOM freed <1K, 17% free 36845K/43911K, paused 34ms, total 34ms
06-10 21:17:18.380 E/dalvikvm-heap( 5973): Out of memory on a 5992720-byte allocation.
06-10 21:17:18.380 I/dalvikvm( 5973): "Thread-3353" prio=5 tid=26 RUNNABLE
06-10 21:17:18.380 I/dalvikvm( 5973): | group="main" sCount=0 dsCount=0 obj=0x420cf690 self=0x54c821a0
06-10 21:17:18.380 I/dalvikvm( 5973): | sysTid=6099 nice=0 sched=0/0 cgrp=apps handle=1422403056
06-10 21:17:18.380 I/dalvikvm( 5973): | schedstat=( 1566617822 87113594 202 ) utm=152 stm=4 core=0
06-10 21:17:18.385 I/dalvikvm( 5973): at android.graphics.Bitmap.nativeCreate(Native Method)
06-10 21:17:18.385 I/dalvikvm( 5973): at android.graphics.Bitmap.createBitmap(Bitmap.java:640)
06-10 21:17:18.390 I/dalvikvm( 5973): at android.graphics.Bitmap.createBitmap(Bitmap.java:575)
06-10 21:17:18.390 I/dalvikvm( 5973): at android.graphics.Bitmap.createBitmap(Bitmap.java:501)
06-10 21:17:18.390 I/dalvikvm( 5973): at com.aura.app.fragments.CameraFragment$AuraCameraHost.saveImage(CameraFragment.java:675)
06-10 21:17:18.390 I/dalvikvm( 5973): at com.commonsware.cwac.camera.ImageCleanupTask.run(ImageCleanupTask.java:195)
06-10 21:17:18.390 I/dalvikvm( 5973):
06-10 21:17:18.390 W/dalvikvm( 5973): threadid=26: thread exiting with uncaught exception (group=0x40f8d2a0)
06-10 21:17:18.390 E/ACRA ( 5973): ACRA caught a OutOfMemoryError exception for com.aura.app. Building report.
编辑:
解码代码如下:
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) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and
// keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Pair<Integer, Bitmap> decodeSampledBitmapFromByteArray(
byte[] data, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(data, 0, data.length, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return new Pair<Integer, Bitmap>(options.inSampleSize,
BitmapFactory.decodeByteArray(data, 0, data.length, options));
}
答案 0 :(得分:1)
我假设您为reqWidth
和reqHeight
使用了固定值1024。如果是这种情况,并且您在屏幕上显示图像,请获取屏幕的宽度和高度,并将其用作reqWidth
和reqHeight
。
通过使用1024的硬编码值,您可能会加载高达2047x2047px的图像,这对于较小的设备来说太大了。
答案 1 :(得分:-1)
您需要设置样本大小。我发现即使对于大型位图(如12MP照片),2也足够好。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
image = BitmapFactory.decodeFile(filename, options);
其中filename是位图的文件名。