5

我在 stackoverflow 中遇到了很多关于这个错误的问题,但没有一个找到解释我的场景的正确解决方案。

在我的 android 应用程序中,我必须允许用户单击按钮以打开图库并选择图像。然后需要将特定的选定图像加载到我的布局(UI)中的 ImageView 中。

这样做是很好的。以下是我用来实现此目的的代码。

在上传按钮中单击->

        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent,"Select Picture"), REQUEST_UPLOAD_IMG);

然后 onActivityResult ->

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
{       
    //super.onActivityResult(requestCode, resultCode, data);        
    if(resultCode == Activity.RESULT_OK)
    {
        if(requestCode==REQUEST_UPLOAD_IMG)
        {               
            Uri selectedImageURI = data.getData();
            uploadImgVW.setImageURI(selectedImageURI);              
        }
        else
        {
            Toast.makeText(MainActivity.this, "You can only select an Image.", Toast.LENGTH_LONG).show();
        }
    }
}

但如果用户选择更大尺寸的图像(如2MB大小),应用程序将退出并出现以下错误。但是正常(KB 级别)图像很好,想知道我可以为这个问题做些什么(处理这种错误情况)。谢谢...

错误->

06-20 16:43:58.445: E/AndroidRuntime(2075): FATAL EXCEPTION: main
06-20 16:43:58.445: E/AndroidRuntime(2075): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
4

3 回答 3

7

有一系列文章描述了如何有效地管理位图。查看您的代码,您加载图像而不知道它有多大,您最终将面临这些问题,特别是如果您加载和处理许多图像。

其中一篇文章中描述的想法是加载已经缩小的位图(首先检查要加载的图像有多大,然后计算缩小因子,然后才加载缩小的图像) . 为此,您首先需要知道 ImageView 的尺寸,然后您必须使用BitmapFactory.decode(...)因为您有要显示的目标文件的 Uri。Uri 到文件应该是微不足道的。

此外,您还需要检查应用程序的内存消耗......您可能还有其他资源挂在内存中,您需要清理它们。我正在使用一个非常有用的工具 - MAT可以在这里找到一篇非常好的文章。作者 Patrick Dubroy 在 Google IO 2011 上就这个主题举办了一场非常有趣的会议。检查一下,对我来说这很有帮助......

于 2013-06-21T13:32:17.900 回答
1

调整图像大小,然后设置

public static Bitmap decodeUri(Context c, Uri uri, final int requiredSize) 
            throws FileNotFoundException {
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(c.getContentResolver().openInputStream(uri), null, o);

        int width_tmp = o.outWidth
                , height_tmp = o.outHeight;
        int scale = 1;

        while(true) {
            if(width_tmp / 2 < requiredSize || height_tmp / 2 < requiredSize)
                break;
            width_tmp /= 2;
            height_tmp /= 2;
            scale *= 2;
        }

        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        return BitmapFactory.decodeStream(c.getContentResolver().openInputStream(uri), null, o2);
    }   

或者你可以这样使用

if(resultCode == RESULT_OK){  
                Uri selectedImage = data.getData();
                InputStream imageStream = null;
                try {
                    imageStream = getContentResolver().openInputStream(selectedImage);
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream);
                profileImage.setImageBitmap(Bitmap.createScaledBitmap(yourSelectedImage , 120, 120, false));
                }
于 2013-06-21T13:35:50.763 回答
0

你可以试试这个...

BitmapFactory.Options options = new BitmapFactory.Options();
options.inTempStorage = new byte[16*1024];

Bitmap bitmapImage = BitmapFactory.decodeFile(path, options);
于 2013-06-21T13:38:52.393 回答