Java自带的ImageIO留下的坑

    前些日子接到了一个需求,要求代码中计算一个网络图片的宽高,于是我想到了ImageIO.read(URL url)方法,很快就开发完了这个功能,可是到了生产后就懵逼了,很多图片地址读取不到内容。

    图片都是七牛服务器的地址,全是jpg格式,在网页中显示也没有问题,这是为什么呢?


    一开始有同事说图片有问题,有可能是图片原本不是jpg格式,后来直接重命名为jpg格式导致的,于是乎我下载了一张图片,在本地测试了一下,完美通过测试,应该不是这个问题。


    那就应该是网络问题了,我跟了一下源码,发现在筛选ImageReaderSpi对象的时候,返回了空,jpg图片应该命中JPEGImageReaderSpi才对。又跟了一次源码,在JPEGImageReaderSpi的canDecodeInput(Object source)方法中,我发现图片流返回的前两个字节分别是0x1F和0x8B,导致这个校验返回false。百度了一下,这两个字节应该是gzip流的标识符,猜测这个图片地址是经过gzip处理之后的图片流。


    那么是不是我在经过GZIPInputStream处理一下就OK了?


    写个单元测试吧。

    @Test
    public void testReadImage() throws IOException {
        String urlStr = "http://img5.mtime.cn/mg/2019/07/19/104427.91760942_235X132X4.jpg";
        BufferedImage image = readImage(urlStr);
        System.out.println(String.format("size: %d * %d", image.getWidth(), image.getHeight()));
    }

    private static BufferedImage readImage(String urlStr) throws IOException {
        InputStream is = new URL(urlStr).openStream();
        BufferedInputStream bis = new BufferedInputStream(is);
        if (isGzip(bis)) {
            return ImageIO.read(new GZIPInputStream(bis));
        } else {
            return ImageIO.read(bis);
        }
    }

    private static boolean isGzip(BufferedInputStream is) throws IOException {
        is.mark(0);
        int b1 = is.read();
        int b2 = is.read();
        is.reset();
        return b1 == 0x1F && b2 == 0x8B;
    }

    测试通过。

标签: JAVA IO ImageIO

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.jsunw.com/?post=40

相关推荐

你肿么看?

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。