OutOfMemoryError而在Android的图像选择。如何对其进行解码,以位图前调整图像? [英] OutOfMemoryError with image selection in Android. How to resize image before decoding it to bitmap?

查看:157
本文介绍了OutOfMemoryError而在Android的图像选择。如何对其进行解码,以位图前调整图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要建在我的Andr​​oid应用程序的imagepicker,为我所用的这个页面例如code。这基本上给了我它打开通过拍照来从SD卡,或者一个文件的可能性按钮。有一次,我选择的图像,它会显示使用简单的ImageView图像。在一般情况下,这个工作得很好;我可以选择图像,然后再次单击选择图像按钮,并选择另一幅图像。到目前为止好。与小文件即是。

I'm building an imagepicker in my Android app, for which I used the example code on this page. This basically gives me a button which opens the possibility to get a file from the SD card, or one by taking a picture. Once I selected an image, it displays the image using a simple ImageView. In general, this works perfectly well; I can select an image, then click the select image button again and select another image. So far so good.. with small files that is.

这个问题开始,当我使用大文件;图片我只是采取了与内置的手机摄像头。我可以选择一个,并且效果很好。当我再次点击选择图像按钮,然后选择另一种形象,我得到这条线一个OutOfMemoryError(线连接到第75页):

The problem starts, when I use "larger files"; pictures I simply took with the built-in phone camera. I can select one, and that works well. When I hit the select-image button again and select another image, I get an OutOfMemoryError on this line (line 75 of the linked to page):

bitmap = BitmapFactory.decodeFile(path);

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

My test-device is quite a modern one (Galaxy S4 Mini), so that shouldn't be the problem. Since I need to send the image as a base64 string to an API for which I need to resize it anyway, I can resize the image using something like this:

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

不过遗憾的是,为了这个,我首先需要去$ C C文件,这实际上导致摆在首位的问题$

But unfortunately, for this I first need to decode the file, which actually causes the problem in the first place.

所以我的问题是;在那里,我可以我去$ C C $它为位图前调整图像大小的方法吗?所有的提示是欢迎!

So my question is; is there a way that I can resize the image before I decode it to a bitmap? All tips are welcome!

推荐答案

当你加载大的位图文件,BitmapFactory类提供了多种解码方式(德codeByteArray(),德codeFILE(),德codeResource(),等等)。

While you load large bitmap files, BitmapFactory class provides several decoding methods (decodeByteArray(), decodeFile(), decodeResource(), etc.).

第1步

在inJustDe codeBounds属性设置为true,而解码避免了内存分配,返回null位图对象,但设置outWidth,outHeight和outMimeType。这种技术可以让你读取图像数据的尺寸和类型之前,位图的建设(和内存分配)。

Setting the inJustDecodeBounds property to true while decoding avoids memory allocation, returning null for the bitmap object but setting outWidth, outHeight and outMimeType. This technique allows you to read the dimensions and type of the image data prior to construction (and memory allocation) of the bitmap.

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例外,解码之前检查位图的尺寸。

To avoid java.lang.OutOfMemory exceptions, check the dimensions of a bitmap before decoding it.

第2步

要告诉德codeR子采样图像,装载的缩小版到​​内存中,inSampleSize设置为true,你BitmapFactory.Options对象。

To tell the decoder to subsample the image, loading a smaller version into memory, set inSampleSize to true in your BitmapFactory.Options object.

例如,图像分辨率2048x1536的是德$ C $光盘为4 inSampleSize产生约512x384的位图。加载此到内存使用0.75MB,而不是12MB的完整图像。

For example, an image with resolution 2048x1536 that is decoded with an inSampleSize of 4 produces a bitmap of approximately 512x384. Loading this into memory uses 0.75MB rather than 12MB for the full image.

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

Here’s a method to calculate a sample size value that is a power of two based on a target width and height:

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

请阅读以下链接了解详细信息。 <一href="http://developer.android.com/training/displaying-bitmaps/load-bitmap.html">http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

Please read this link for details. http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

这篇关于OutOfMemoryError而在Android的图像选择。如何对其进行解码,以位图前调整图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆