在Android中计算合适的图像大小

在Android中计算合适的图像大小,android,bitmap,Android,Bitmap,我目前正在使用这里的代码在Android中解码图像: 我使用了1024分钟的解码,这在Galaxy S4、Galaxy Note 3、Galaxy Tab 3、Xperia Z和HTC One M8等高端设备上运行良好 我遇到的唯一问题是,这会使一些较弱的手机(如Galaxy S2和Nexus One)的应用程序崩溃 我正在尝试将图像的宽度和高度降低到1024像素的最小值,在Galaxy S2和Nexus One上,当我尝试加载文件时,它会抛出一个OutOfMemoryError 有没有一种方

我目前正在使用这里的代码在Android中解码图像:

我使用了1024分钟的解码,这在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等高端设备上保持合适的质量

银河系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.
06-10 21:17:18.345 I/dalvikvm堆(5973):强制收集用于5992720字节分配的软引用
06-10 21:17:18.380 D/dalvikvm(5973):前气相色谱仪(高度和宽度>要求宽度){
最终int半高=高度/2;
最终整数半宽度=宽度/2;
//计算最大的inSampleSize值,该值为2和的幂
//两者都保留
//高度和宽度大于请求的高度和宽度。
而((半高/采样)大于所需高度
&&(半宽/采样尺寸)>reqWidth){
inSampleSize*=2;
}
}
返回样本大小;
}
公共静态对decodeSampledBitmapFromByteArray(
字节[]数据,输入请求宽度,输入请求高度){
//使用INJUSTDECBOUNDS首次解码=true检查尺寸
final BitmapFactory.Options=new BitmapFactory.Options();
options.inJustDecodeBounds=true;
BitmapFactory.decodeByteArray(数据,0,数据.length,选项);
//计算样本大小
options.inSampleSize=计算样本大小(选项、要求宽度、,
(高度);
//使用inSampleSize集合解码位图
options.inJustDecodeBounds=false;
返回新对(options.inSampleSize,
BitmapFactory.decodeByteArray(数据,0,数据.length,选项));
}

您需要设置样本大小。我发现2是足够好的,即使是大位图,如12MP照片

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;

image = BitmapFactory.decodeFile(filename, options);

其中filename是位图的文件名。

我假设您对
reqWidth
reqHeight
使用了1024的固定值。如果是这种情况,并且您正在屏幕上显示图像,则获取屏幕的宽度和高度,并将其用作
reqWidth
reqHeight


通过使用1024的硬编码值,您可以加载高达2047x2047px的图像,这对于较小的设备来说太大了。

我确实设置了样本大小。看看我的原始问题,添加了我使用的代码。我使用的是1024的固定值。但是,我想根据可用内存计算reqWidth和reqHeight,因为照片已发布到服务器,我希望它具有尽可能高的质量。这可能吗?可能但很复杂,因为在旧设备上,位图存储在本机堆中,而在新设备上,位图被移动到VM堆中。你必须对此做大量的研究,但这是不可靠的——空闲内存可以在瞬间改变。根据生成图像的方式和存储位置,将图像流式传输到服务器将是一个更好的选择,因为您不需要将其全部保存在内存中。这是一个与你所问的不同的问题。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;

image = BitmapFactory.decodeFile(filename, options);