从内部存储有效加载位图,而不是资源

时间:2016-07-26 21:47:12

标签: android performance memory bitmap

我正在下载这样的位图:

HttpURLConnection connection = (HttpURLConnection) url.openConnection();
...
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);

将它们保存到内部存储器中:

fos = new FileOutputStream(filePath);
image.compress(Bitmap.CompressFormat.JPEG, 90, fos);

但是在研究了google page about bitmaps之后,它说将大位图下载到内存中可能会抛出一个outOfMemory异常,所以我应该缩放这个位图以占用内存上更小的空间。问题是页面上的代码只解释了如何使用资源图像,而不是来自内部存储的图像。所以,我有两个问题:

如何从内部存储中获取位图?

有没有办法以一种方式下载和保存图像?

我首先创建一个Bitmap图像,然后将其传递给保存它的方法,因此我假设图像被完全加载到内存中,然后将其保存到内部存储中。

2 个答案:

答案 0 :(得分:0)

从内部存储器加载图像不是问题,除非您像在ViewPager中一样加载所有内容。或者你的形象真的很大。但如果不是这样,你应该没事。

关于下载图片的问题,我强烈建议您不要选择“全部采用一种方式”。因为面向对象编程。另外,请尝试使用 Volley 下载图片。

答案 1 :(得分:0)

您可以尝试使用以下代码:

public void loadPhotoToView(String path) {
        File imgFile = new File(path);
        if (imgFile.exists()) {
            imageView.setImageBitmap(decodeFile(imgFile));
        }
    }

    // Decode image and scale it to reduce memory consumption
    public Bitmap decodeFile(File f) {
        try {
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f), null, o);

            // The new size we want to scale to, the bigger the better of quality
            final int REQUIRED_SIZE = 200;

            // Find the correct scale value. It should be the power of 2.
            int scale = 1;
            while (o.outWidth / scale / 2 >= REQUIRED_SIZE &&
                    o.outHeight / scale / 2 >= REQUIRED_SIZE) {
                scale *= 2;
            }

            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {
        }
        return null;
    }

另一种方法是使用像Picasso这样的库来加载图像:

Picasso.with(this).load(imgFile).into(imageView);