【问题标题】:Android: Passing a large image from url to ImageViewAndroid:将大图像从 url 传递到 ImageView
【发布时间】:2012-12-07 13:44:16
【问题描述】:

没错,我正在创建一个 Android 应用程序,我需要在其中显示来自特定 URL 的图像。不幸的是,图像太大了,当我将它传递到可绘制对象中而不进行任何解码时,它会给我一个内存不足异常。

因此,我尝试首先使用 BitmapFactory.decodeStream 解码图像。

这里有一些代码:

首先是我用来解码图像的方法:

public static Bitmap decodeSampledBitmapFromResource(Resources res, String src,
            int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();

        InputStream input = null;
        InputStream input2 = null;

        Rect paddingRect = new Rect(-1, -1, -1, -1);

        try {
            URL url = new URL(src);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            input = connection.getInputStream();
            //input2 = connection.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(input, paddingRect, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

       try {
        input.reset();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;

        return BitmapFactory.decodeStream(input, paddingRect, 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 = 40;

    if (height > reqHeight || width > reqWidth) {
        if (width > height) {
            inSampleSize = Math.round((float)height / (float)reqHeight);
        } else {
            inSampleSize = Math.round((float)width / (float)reqWidth);
        }
    }
    return inSampleSize;
}

然后我在活动的 OnCreate 中调用该方法:

imageFrame1.setImageBitmap(
                decodeSampledBitmapFromResource(getResources(), src, 100, 100));

就像现在的代码一样,当我在第一次解码后尝试重置输入流时,它会捕获一个 IOException,然后我收到 LogCat 消息:SKImageDecoder::Factory Returned Null。

如果我删除 input.reset();从代码中,我得到相同的 LogCat 消息,只是没有 IOException。

在这一点上有点难过,希望这里有人给点建议?

【问题讨论】:

    标签: java android bitmap imageview bitmapfactory


    【解决方案1】:

    您无法从 HTTP 连接重置流,因为底层逻辑没有缓存(足够)流。

    创建一种方法,将图片写入本地存储(磁盘或内存),然后对其进行分析。可以选择同时做这两个(需要更多的努力)。

    【讨论】:

    • 我可能会误解你,但如果我尝试下载图片而不将其解码为更小的尺寸,那么由于图像尺寸过大,我会收到内存不足异常。
    • 将其存储在光盘上并从光盘解码。通过磁盘,我正在考虑闪存(存储卡或内部)。
    【解决方案2】:

    请记住,inputStream 可能不支持重置。此外,您必须先调用 mark() 来标记该点,inputStream 应重置为。要检查是否支持标记/重置,请调用 InputStream.markSupported()。

    没有标记/重置,您可以将图像下载到本地文件。它不会导致 OutOfMemory 并允许您从 FileInputStream 解码图像,就像您尝试从 Web 进行解码一样(使用二次采样)。

    【讨论】:

      猜你喜欢
      • 2018-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-28
      • 1970-01-01
      • 2013-02-11
      相关资源
      最近更新 更多