ImageIO Unsupported Image Type

知了一笑 2021-01-07 14:16:33 ⋅ 643 阅读

一、问题代码

    BufferedImage bi = ImageIO.read(inputStream);

二、异常信息

javax.imageio.IIOException: Unsupported Image Type
        at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1068)
        at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:1039)
        at javax.imageio.ImageIO.read(ImageIO.java:1448)
        at javax.imageio.ImageIO.read(ImageIO.java:1352)

三、分析问题原因

Adobe Photoshop (PS)或其他软件处理过的图片保存为jpg格式时,默认是CMYK或者(YCCK)模式。

四、了解色彩空间

RGB色彩

自然界中绝大部分的可见光谱可以用红、绿和蓝三色光按不同比例和强度的混合来表示。RGB分别代表着3种颜色:R代表红色,G代表绿色、B代表蓝色。RGB模型也称为加色模型,通常用于光照、视频和屏幕图像编辑。RGB色彩模式使用RGB模型为图像中每一个像素的RGB分量分配一个0~255范围内的强度值。

CMYK色彩

CMYK色彩模式以打印油墨在纸张上的光线吸收特性为基础,图像中每个像素都是由靛青(C)、品红(M)、黄(Y)和黑(K)色按照不同的比例合成。每个像素的每种印刷油墨会被分配一个百分比值,最亮(高光)的颜色分配较低的印刷油墨颜色百分比值,较暗(暗调)的颜色分配较高的百分比值。

YCCK 色彩

在没有Adobe标记的IJG中,有4个通道,它被假定为CMYK,但在oracle中它是YCCA.此外,IJG的实现并未考虑子采样,而对于4通道子采样,它在oracle规范中是YCCK,依此类推. Oracle 官网解释 If an Adobe APP14 marker segment is present, the colorspace is determined by consulting the transform flag. The transform flag takes one of three values:

  • 2 - The image is encoded as YCCK (implicitly converted from CMYK on encoding).
  • 1 - The image is encoded as YCbCr (implicitly converted from RGB on encoding).
  • 0 - Unknown. 3-channel images are assumed to be RGB, 4-channel images are assumed to be CMYK.

通俗一点我们可以认为CMYK 和 YCCK 是一样的,都是用于打印的色彩

五、解决方案

方案一、Apache Imaging 工具库(推荐)

1. Maven 依赖

<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-imaging -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-imaging</artifactId>
    <version>1.0-alpha2</version>
</dependency>

2. 简单使用

import org.apache.commons.imaging.ImageInfo;

final ImageInfo imageInfo = Imaging.getImageInfo(file);
System.out.println(imageInfo);

3. 输出信息

Format Details: Jpeg/DCM
Bits Per Pixel: 32
Comments: 0
Format: JPEG
Format Name: JPEG (Joint Photographic Experts Group) Format
Compression Algorithm: JPEG
Height: 2436
MimeType: image/jpeg
Number Of Images: 1
Physical Height Dpi: 300
Physical Height Inch: 8.12
Physical Width Dpi: 300
Physical Width Inch: 3.75
Width: 1125
Is Progressive: false
Is Transparent: false
Color Type: YCCK
Uses Palette: false

4. 获取格式和尺寸

final ImageInfo imageInfo = Imaging.getImageInfo(file);
System.out.println("格式:" + imageInfo.getFormat().getName());
System.out.println("尺寸:" + imageInfo.getWidth() + " x " + imageInfo.getHeight());
System.out.println("色彩空间:" + imageInfo.getColorType());

5. 输出格式和尺寸信息

格式:JPEG
尺寸:1125 x 2436
色彩空间:YCCK

6. 官网其他例子

https://commons.apache.org/proper/commons-imaging/sampleusage.html

方案二、使用jdk的原生方法获取尺寸

Java代码

final JPEGImageDecoder jpegDecoder = JPEGCodec.createJPEGDecoder(new FileInputStream(file));
final BufferedImage bufferedImage = jpegDecoder.decodeAsBufferedImage();
System.out.println("尺寸:" + bufferedImage.getWidth() + " x " + bufferedImage.getHeight());

注意:这里返回的 BufferedImage 不能直接使用,因为色彩失真了。 注意:createJPEGDecoder 的输入流之前不要使用 ImageIO.read 操作,不然会报

输出结果

尺寸:1125 x 2436

参考资料

https://stackoverflow.com/questions/7177655/java-imageio-iioexception-unsupported-image-type https://blog.csdn.net/WuZuoDingFeng/article/details/77946489 https://qa.1r1g.com/sf/ask/3555861011/ https://commons.apache.org/proper/commons-imaging/sampleusage.html https://stackoverflow.com/questions/6829428/pure-java-alternative-to-jai-imageio-for-detecting-cmyk-images


全部评论: 0

    我有话说:

    京东技术:Flutter图片缓存 | Image.network源码分析

    Android目前提供了很丰富的图片框架,像ImageLoader、Glide、Fresco等。对于Flutter而言,为了探其缓存机制或者定制自己的缓存框架,特从其Image入手进行突破。

    微信小程序-Image的widthFix属性和rpm尺寸的使用

    在做微信小程序的商品详情页,商品的详情是图片集合,渲染完成后发现图片加载的很不自然

    精品推荐:nginx常用配置总结(实战版)

    Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。

    Nginx架构详解:nginx 的安装和配置

    Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。

    浅谈Redux中间件的实践

    用户在UI层面触发行为,一个action对象通过store.dispatch派发到Reducer进行触发,接下来Reducer会根据type来更新对应的Store上的状态树,更改后的state会触发

    GNS3 2.2.18 发布,网络拓扑模拟工具

    使用 HDD disk image 作为启动 QE...