【问题标题】:Loading bitmaps efficiently from internal storage, not resource从内部存储而不是资源有效地加载位图
【发布时间】:2016-07-26 21:47:11
【问题描述】:

我正在下载这样的位图:

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异常,所以我应该缩放这个位图以占用更小的内存空间。问题是页面上的代码只解释了如何处理资源图像,而不是来自内部存储的图像。所以,我有两个问题:

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

有没有一种方法可以一次性下载并保存图片?

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

【问题讨论】:

  • 扔掉 BitmapFactory。 Indead 你应该创建一个循环,从输入流中读取块并将它们直接写入文件输出流。
  • 您说的是“内部存储器”,但如果这是真的,我们无法在“文件路径”上看到。
  • 看起来不是加载位图的问题。

标签: android performance memory bitmap


【解决方案1】:

从内存中加载图像不是问题,除非您像在 ViewPager 中那样一次加载大量图像。或者你的图像真的很大。但如果不是这样,你应该没问题。

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

【讨论】:

  • 我正在从内部存储中加载它们,但它们就像 800x600 图像以适合 50x50 圆形图像视图的消息,就像 gmail 一样,所以我真的应该处理它们。不使用 Volley 是否有一种简单的方法可以将图像部分写入?我真的需要一个小的解决方案。我认为对于位图处理解决了,我没有看到方法decodeFile存在,我以为它只是decodeResource developer.android.com/reference/android/graphics/…
  • @Gatonito 实际上你真正需要做的是计算样本量。在这里,developer.android.com/training/displaying-bitmaps/…
【解决方案2】:

你可以试试下面的代码:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-26
    • 2015-10-24
    相关资源
    最近更新 更多