0

我有 4 行代码来下载位图,

URL u = new URL(webaddress);

InputStream in = null;

in = u.openStream();

icon = BitmapFactory.decodeStream(in);

我计划更改最后一行以执行类似于本教程的操作,我只将设置大小的图像加载到内存中以减少内存使用量。但是我不希望这涉及另一个服务器调用/下载,所以我很好奇上面四行中的哪一行实际上从源下载数据?

我将把最后一行代码更改为上面提到的教程中的最后两个函数,这样可以知道它是否意味着下载更多或更少的数据,(我试图只从一个例如可以是 5 兆像素)

抱歉,如果这是简单的/错误的思考方式,我对数据流不是很有经验。


编辑

我使用这两个函数来替换上面的最后一行代码:调用:

image = decodeSampledBitmapFromStram(in, 300,300);

图像质量不是优先事项,这是否意味着下载更多数据?

private static int calculateInSampleSize(BitmapFactory.Options options,
            int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            // Calculate ratios of height and width to requested height and
            // width
            final int heightRatio = Math.round((float) height
                    / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);

            // Choose the smallest ratio as inSampleSize value, this will
            // guarantee
            // a final image with both dimensions larger than or equal to the
            // requested height and width.
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }

        return inSampleSize;
    }

    private Bitmap decodeSampledBitmapFromStream(InputStream in, int reqWidth, int reqHeight) {
        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        Rect padding = new Rect();
        BitmapFactory.decodeStream(in, padding, options);

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

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

        return BitmapFactory.decodeStream(in, padding, options);
    }
4

2 回答 2

1

四行中的最后一行负责整个下载。 BitmapFactory.decodeStream(in);将继续从该流中提取数据,直到整个图像已下载或中途发生错误。

至于带宽问题,我会非常小心地了解解码器在尝试之前如何对大图像进行下采样。在将大图像缩小到较小尺寸时,以高质量方式执行此操作的唯一方法是通过平均原始图像中的像素来进行下采样。如果解码器以这种方式进行下采样,那么您将不会节省任何带宽,因为解码器仍然需要读取原始图像的每个像素,即使不是每个像素都存储在 RAM 中。您可以通过不读取原始图像中的每个像素来更快地进行下采样,但代价是最终图像质量。沿着这些思路,我确实注意到了一个更喜欢“质量优于速度”的选项:

http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inPreferQualityOverSpeed

我有一种感觉,对于这个特定的选项,您可以通过读取更少的数据来获得更快的速度,但 API 声明这仅适用于 JPEG。不确定这是否有助于您的特定用例,但可能值得研究。

于 2013-08-27T19:46:56.027 回答
1

以下文档将帮助您更好地了解流式传输http://docs.oracle.com/javase/tutorial/essential/io/streams.html。简而言之,一旦建立到资源位置的连接,就会检索/读取确定大小的缓冲区(数据部分)。通常,这个过程一直持续到所有部分都被读取为止。

流媒体的主要优势是以零碎的方式运作。例如,假设您要下载大小为 500 MB 的图像。流式传输不是一次性传输,而是允许分块下载。这在错误处理、重试、峰值网络利用率等方面更好。

于 2013-08-27T19:49:02.850 回答