• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

OutOfMemoryError与Android中的图像选择。如何在将图像解码为位图之前调整图像大小?

java 来源:kramer65 3次浏览

我在我的Android应用程序中构建了一个imagepicker,为此我使用了example code on this page。这基本上给了我一个按钮,可以从SD卡上获取文件,或者通过拍照来打开文件。一旦我选择了一个图像,它会使用一个简单的ImageView来显示图像。一般来说,这很好地工作;我可以选择一个图像,然后再次单击选择图像按钮并选择另一个图像。到目前为止这么好..与小文件是。OutOfMemoryError与Android中的图像选择。如何在将图像解码为位图之前调整图像大小?

当我使用“较大的文件”时,问题就开始了;我只是用内置的手机相机拍下的照片。我可以选择一个,而且效果很好。当我再次打了选择图像按钮,然后选择另一个形象,我就在这行一个OutOfMemoryError(线链接到页面75):

bitmap = BitmapFactory.decodeFile(path); 

我的测试设备是一个相当现代化的一个(银河S4迷你),所以不应该是这个问题。因为我需要将图像发送为Base64字符串,对此我总有需要调整它的API,我可以用这样的调整图像大小:

Bitmap yourBitmap; 
Bitmap resized = Bitmap.createScaledBitmap(yourBitmap, newWidth, newHeight, true); 

但不幸的是,为了这个,我首先需要解码该文件实际上首先导致问题。

所以我的问题是,有没有一种方法可以在将图像解码为位图之前调整图像大小?欢迎所有提示!


===========解决方案如下:

虽然加载大的位图文件,BitmapFactory类提供了几种解码方法(decodeByteArray(),decodeFile(),decodeResource(),等等)。

STEP 1

的inJustDecodeBounds属性设置为true,而解码避免了内存分配,为位图对象返回空但设置outWidth,outHeight和outMimeType。该技术允许您在构建位图之前读取图像数据的尺寸和类型(以及内存分配)。

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; 

要避免java.lang.OutOfMemory异常,请在解码之前检查位图的维数。

STEP 2

告诉解码器子样本图像,加载一个较小的版本到内存中,设置inSampleSize为true你BitmapFactory.Options对象。

例如,分辨率为2048×1536且用inSampleSize为4解码的图像会生成大约512×384的位图。将其加载到内存中时,整个图像使用0.75MB而不是12MB。

这里的计算样本大小值是两个基于目标宽度和高度的功率的方法:

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); 
} 

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; 
} 

请仔细阅读本链接了解详情。 http://developer.android.com/training/displaying-bitmaps/load-bitmap.html


版权声明:本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。
喜欢 (0)