【问题标题】:Android - Displaying large bitmaps from internet, efficientlyAndroid - 有效地显示来自互联网的大型位图
【发布时间】:2012-07-10 18:22:50
【问题描述】:

给定图片网址,我需要下载它并在 ImageView 中显示。
一切正常,除了图像非常大并且抛出 OutOfMemoryException 的情况。

希望 Android 文档提供解决此问题的方法:http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

我尝试修改这段代码以接受 InputStream,而不是 Resource。
但是,似乎我在那里遗漏了一些东西,因为图像没有显示,也不例外,但我在 LogCat 中看到:SkImageDecoder::Factory returned null

这是我如何解码图像并将其缩小(基于 Android 文档):

public static Bitmap decodeBitmapFromInputStream(InputStream inputStream,
            int reqWidth, int reqHeight) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(inputStream, null, options);

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

        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeStream(inputStream, null, options);
    }

    public 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) {
            if (width > height) {
                inSampleSize = Math.round((float) height / (float) reqHeight);
            } else {
                inSampleSize = Math.round((float) width / (float) reqWidth);
            }
        }
        return inSampleSize;
    }

现在,在我的位图下载器方法中,我这样称呼它:

inputStream=entity.getContent();
return decodeBitmapFromInputStream(inputStream, 320, 480);

这是完整的方法,以防万一:

static Bitmap downloadBitmap(String url){
        AndroidHttpClient client=AndroidHttpClient.newInstance("Android");
        HttpGet getRequest=new HttpGet(url);

        try{
            HttpResponse response=client.execute(getRequest);
            int statusCode=response.getStatusLine().getStatusCode();

            if(statusCode!=HttpStatus.SC_OK){
                Log.d("GREC", "Error "+statusCode+" while retrieving bitmap from "+url);
                return null;
            }

            HttpEntity entity=response.getEntity();
            if(entity!=null){
                InputStream inputStream=null;
                try{
                    inputStream=entity.getContent();
                    return decodeBitmapFromInputStream(inputStream, 320, 480);
                }catch (Exception e) {
                    Log.d("GREC", "Exception occured in BitmapDownloader");
                    e.printStackTrace();
                }
                finally{
                    if(inputStream!=null){
                        inputStream.close();
                    }
                    entity.consumeContent();
                }
            }
        }catch (Exception e) {
            getRequest.abort();
            Log.d("GREC", "Error while retriving bitmap from "+url+", "+e.toString());
        }finally{
            if(client!=null){
                client.close();
            }
        }
        return null;
    }

【问题讨论】:

  • 调用 entity.getContent() 会给你一个 InputStream 你解码两次 - 这通常是行不通的。

标签: android android-layout android-intent android-emulator android-widget


【解决方案1】:

问题在于,一旦您使用了来自 HttpUrlConnection 的 InputStream,您就无法回退并再次使用相同的 InputStream。因此,您必须为图像的实际采样创建一个新的 InputStream。否则我们必须中止 http 请求。 见decodeStream returns null

【讨论】:

    猜你喜欢
    • 2012-03-20
    • 2014-02-08
    • 1970-01-01
    • 2015-11-28
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多