安卓:SkImageDecoder::工厂返回空值

31

我正在使用本地主机获取图像并在 ImageView 中查看。出现“工厂返回 null”错误,但我检查了代码很多次,不知道哪里有问题。希望得到任何帮助!

GalleryZoom.java

public class Zoom extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.gallery_zoom);

        String selection = getIntent().getExtras().getString("image");
        Toast.makeText(this, selection, Toast.LENGTH_LONG).show();

        new backgroundLoader().execute();       
    }


    private class backgroundLoader extends AsyncTask<Void, Void, Void> {
        Bitmap bmp;

        @Override
        protected Void doInBackground(Void... params) {

            bmp = DecodeBitmapSampleSize(getIntent().getExtras().getString("image"), 48, 64);
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            ImageView image = (ImageView) findViewById(R.id.imageZoom);
            image.setImageBitmap(bmp);
        }

    }

    public Bitmap DecodeBitmapSampleSize (String strURL, int reqWidth, int reqHeight) {
        InputStream in = null;
        Bitmap bmp = null;

        in = OpenHttpConnection(strURL);
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(in, null, options);

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

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

    private InputStream OpenHttpConnection(String strURL) {

        try {
            URL url = new URL(strURL);

            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            InputStream in = new BufferedInputStream(connection.getInputStream());
            return in;
        } catch (Exception exception) {
            exception.printStackTrace();
            return null;
        }
    }

    public static int calculateSampleSize(BitmapFactory.Options options,
            int reqWidth, int reqHeight) {

        final int width = options.outWidth;
        final int height = options.outHeight;
        int inSampleSize = 1;

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

}

LogCat日志

08-13 21:55:19.578: I/MemoryCache(3197): MemoryCache maximum limit is 6MB
08-13 21:55:19.658: I/MemoryCache(3197): cache size = 24600, length = 1
08-13 21:55:19.688: I/MemoryCache(3197): cache size = 24600, length = 1
08-13 21:55:19.708: I/MemoryCache(3197): cache size = 24600, length = 1
08-13 21:55:19.708: I/MemoryCache(3197): cache size = 24600, length = 1
08-13 21:55:20.628: I/MemoryCache(3197): cache size = 71600, length = 2
08-13 21:55:20.678: I/MemoryCache(3197): cache size = 101408, length = 3
08-13 21:55:26.228: I/MemoryCache(3197): MemoryCache maximum limit is 6MB
08-13 21:55:26.228: I/MemoryCache(3197): MemoryCache maximum limit is 6MB
08-13 21:55:26.998: D/skia(3197): --- SkImageDecoder::Factory returned null

请参考这篇帖子,它对我很有用:https://dev59.com/xX_aa4cB1Zd3GeqP4YUG。 - mithil1501
5个回答

63

我遇到了同样的问题,并确保要下载图像的URL是正确的。通过调试代码,我发现在第一次解码后inputstream中的position变量被设置为1024。 因此,在第二次解码之前,我添加了 inputstream.reset()。这样就可以解决问题了。 希望能对其他人有所帮助。


6
这对我有用,但请确保首先调用boolean supported = inputStream.markSupported()。必须支持标记或者reset()会抛出一个IOException异常。如果不支持,请考虑打开第二个输入流。 - Shellum
你是怎么解决这个问题的?我也遇到了同样的问题,并在这里发布了:https://dev59.com/rHTYa4cB1Zd3GeqPx7fW。但出于某种原因,它在一些非常特定的网站和文件上无法正常工作。 - android developer

12

查看了一些资料后,我找到了最好的解决方案。

正如#jiaGeorge所指出的那样,你应该在第一次解码后重置输入流,问题是有时候重置不被支持,但是你可以将输入流包装在一个BufferedInputStream内,这样就可以解决问题。

final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; 
BufferedInputStream buffer=new BufferedInputStream(is);
BitmapFactory.decodeStream(buffer,null,options);
buffer.reset();

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

    // Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false; 
BitmapFactory.decodeStream(buffer,null,options);

12

此外,一些URL可能以“ .jpg”、“ .png”、“ .tif”等结尾,但实际上并不是指向图像。例如:http://www.guoguiyan.com/data/out/96/69698096-high-resolution-wallpapers.jpg。 - shoe

1

1

当我从相册应用程序返回的意图中读取流时,遇到了类似的问题。如Shellum上面提到的那样,inputstream.reset()会抛出IOException异常,因此我通过关闭流并重新打开它来解决了这个问题。简单而有效。


我按照这个建议在C#中将流位置设置为0。 - Gandalf458

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接