2

没错,我正在创建一个 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。

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

4

2 回答 2

1

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

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

于 2012-12-07T13:51:49.100 回答
0

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

如果没有标记/重置,您可以将图像下载到本地文件。它不会导致 OutOfMemory 并允许您以与您尝试从网络(使用子采样)相同的方式解码 FileInputStream 中的图像。

于 2012-12-07T14:01:34.483 回答