声明:
此文章的详解其实是个人遇到问题的解决方案,具体详细描述还要看各大佬的文章,一般都是英文的论坛大佬描述的比较好。解决方案也是借鉴大佬文章实现的
1、异常解释
javax.imageio.IIOException: Unsupported Image Type异常一般情况是由于图片颜色模式是CMYK导致的,因为其内部读取文件的类JPEGImageReader只能读取RGB color model
一般经过ps的图片自动保存曾jpeg格式颜色空间都会改变成CMYK,如果强行转换颜色空间会导致图片失色
gift的图色彩模式是CMYK模式(注意,这是给印刷机用的)在java.awt包下的Image类只能使用RGB模式,修改模式之后打水印会造成失色问题
失色图片效果:
如果是人脸的话,失色效果会更加让人不可接受,例如面无血色,嘴唇苍白~
2、解决思路
水印图片不允许失色的情况所以要解决这个问题的主要思路就是
-
1如何使用CMYK颜色模式的图片
-
2如果将CMYK颜色模式改成RGB并且不失色
我们先来看第一种,如何使用CMYK颜色模式的图片
ImageIO类创建Image对象的时候调用 getImageTypesOnThread方法判断图片颜色类型
switch (colorSpaceCode) {
case JPEG.JCS_GRAYSCALE:
list.add(raw);
list.add(getImageType(JPEG.JCS_RGB));
break;
case JPEG.JCS_RGB:
list.add(raw);
list.add(getImageType(JPEG.JCS_GRAYSCALE));
list.add(getImageType(JPEG.JCS_YCC));
break;
case JPEG.JCS_RGBA:
list.add(raw);
break;
case JPEG.JCS_YCC:
if (raw != null) { // Might be null if PYCC.pf not installed
list.add(raw);
list.add(getImageType(JPEG.JCS_RGB));
}
break;
case JPEG.JCS_YCCA:
if (raw != null) { // Might be null if PYCC.pf not installed
list.add(raw);
}
break;
case JPEG.JCS_YCbCr:
// As there is no YCbCr ColorSpace, we can't support
// the raw type.
// due to 4705399, use RGB as default in order to avoid
// slowing down of drawing operations with result image.
list.add(getImageType(JPEG.JCS_RGB));
if (iccCS != null) {
list.add(new ImageTypeProducer() {
protected ImageTypeSpecifier produce() {
return ImageTypeSpecifier.createInterleaved
(iccCS,
JPEG.bOffsRGB, // Assume it's for RGB
DataBuffer.TYPE_BYTE,
false,
false);
}
});
}
list.add(getImageType(JPEG.JCS_GRAYSCALE));
list.add(getImageType(JPEG.JCS_YCC));
break;
case JPEG.JCS_YCbCrA: // Default is to convert to RGBA
// As there is no YCbCr ColorSpace, we can't support
// the raw type.
list.add(getImageType(JPEG.JCS_RGBA));
break;
}
自动读取文件colorSpaceCode为9(抱歉这里真的没看懂什么时候赋值9的,可能除非改源码)code为9在这个switch中找不到对应类型抛出javax.imageio.IIOException: Unsupported Image Type异常
那么我们来看看JPEF类下有没有code为9的
源码片段:很明显,不知道什么原因,code为8和9的被注释掉无法使用
// IJG Color codes.
public static final int JCS_UNKNOWN = 0; // error/unspecified
public static final int JCS_GRAYSCALE = 1; // monochrome
public static final int JCS_RGB = 2; // red/green/blue
public static final int JCS_YCbCr = 3; // Y/Cb/Cr (also known as YUV)
public static final int JCS_CMYK = 4; // C/M/Y/K
public static final int JCS_YCC = 5; // PhotoYCC
public static final int JCS_RGBA = 6; // RGB-Alpha
public static final int JCS_YCbCrA = 7; // Y/Cb/Cr/Alpha
// 8 and 9 were old "Legacy" codes which the old code never identified
// on reading anyway. Support for writing them is being dropped, too.
public static final int JCS_YCCA = 10; // PhotoYCC-Alpha
public static final int JCS_YCCK = 11; // Y/Cb/Cr/K
public static final int NUM_JCS_CODES = JCS_YCCK+1;
ok到此为止,如果没有修改源码的能力,那么我去看一下第二步是否可以走得通
2、如果将CMYK颜色模式改成RGB并且不失色
此处解决方法在我另一个文章,查看另一个文章即可看到解决方法的代码,
点击查看:JAVA给照片添加平铺水印并解决javax.imageio.IIOException: Unsupported Image Type异常
主要是用其他两个包的功能将转码缺失精度改成严格对应。
结局,感谢观看~