V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fantasquex
V2EX  ›  Java

关于 ImageIO.write()的奇怪 exception

  •  
  •   fantasquex · 2021-03-02 22:17:10 +08:00 · 1735 次点击
    这是一个创建于 1143 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 ImageIO.write()的文档中标明会抛出 IOException,在我写一个小 project 的时候遇到抛出 IndexOutOfBoundsException 导致我的程序崩溃,于是深入调查。 最小复现程序如下:

    package test;
    
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    import javax.imageio.ImageIO;
    
    public class MyChange {
        public static void main(String[] args) {
            File inputFile = new File("0.png");
            try (InputStream is = new FileInputStream(inputFile)) {
                BufferedImage image = ImageIO.read(is);
                ImageIO.write(image, "bmp", new File("0.bmp"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    输入的图片比较有特点,将任意一张图片(image.png)使用 imagemagick 做如下变换可得到触发 exception 的输入

    convert image.png -colorspace gray -depth 2 -alpha off 0.png
    

    可以使用 mediainfo 确认 bit depth 为 2 。

    这边自己生成的一个样例 https://iili.io/fm4Vna.png

    经过这边的测试只有 bit depth 为 2 时会抛出这个 exception,而 bit depth 为 1,4 和 8 时都可以正常完成程序的预期功能。

    测试的 openJDK 是 15.0.2,同时测试了 openJDK 11.0.10 ,欢迎大佬复现。

    想请教 v 友这是 openJDK 的问题还是我对于 Java 的理解有问题,感谢!

    5 条回复    2021-03-03 13:27:18 +08:00
    luozic
        1
    luozic  
       2021-03-03 02:01:22 +08:00 via iPhone
    BMP 文件的图像深度可选 lbit 、4bit 、8bit 及 24bit
    luozic
        2
    luozic  
       2021-03-03 02:04:15 +08:00 via iPhone
    @luozic 还有 32bit,没有 2bit
    luozic
        3
    luozic  
       2021-03-03 02:13:14 +08:00 via iPhone
    @luozic 还有 16bi t,目前看到的规范就确定这几种
    codehz
        4
    codehz  
       2021-03-03 05:56:38 +08:00
    bmp 格式属于微软私有的格式,尚且没有公开的官方标准,别看它看起来简单,实际上细节很多,不同模式下存储的方法都有所不同,还有对齐的问题。。
    fantasquex
        5
    fantasquex  
    OP
       2021-03-03 13:27:18 +08:00
    @codehz
    @luozic 我还想问一下他抛出 IndexOutOfBoundsException 我可以怎么优雅的处理,我之前的处理方法是只处理了 IOException,另外这里 jdk 抛出 IOException 会不会更好,谢谢!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2997 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 15:01 · PVG 23:01 · LAX 08:01 · JFK 11:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.