聲明:
此文章的詳解其實是個人遇到問題的解決方案,具體詳細描述還要看各大佬的文章,一般都是英文的論壇大佬描述的比較好。解決方案也是借鑑大佬文章實現的
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異常
主要是用其他兩個包的功能將轉碼缺失精度改成嚴格對應。
結局,感謝觀看~