일반적으로 이미지 타입이 RGB가 아닌 CMYK인 경우 


ImageIO.read() 를 이용하여 읽을 경우  Unsupported Image Type 가 발생한다.


일반적으로 CMYK타입 이미지는  ImageIO 로 read 하기 불가능하다




ImageIO.read(file); 를 이용해서 Exception이 발생할 경우 컨버터를 이용하여 처리하는 방식을 이용하여 오류를 줄일 수 있다. 



converter_Lib.zip



converter_Lib.zip의 icc 파일은 Cmyk2RgbConverter와 동일한 경로에 위치하면 된다. 



< Cmyk2RgbConverter.java >


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
public class Cmyk2RgbConverter {
 
    public static final int TYPE_RGB = 1;
    public static final int TYPE_CMYK = 2;
    public static final int TYPE_YCCK = 3;
 
    private static int colorTp = TYPE_RGB;
    private static boolean markerFlag = false;
 
 
 
    public static BufferedImage readImage(File file) throws IOException, ImageReadException {
        colorTp = TYPE_RGB;
        markerFlag = false;
 
        ImageInputStream stream = ImageIO.createImageInputStream(file);
        Iterator < itor_imgReader > iter = ImageIO.getitor_imgReaders(stream);
        while (iter.hasNext()) {
            itor_imgReader reader = iter.next();
            reader.setInput(stream);
 
            BufferedImage image;
 
            ICC_pf pf = null;
            try {
                image = reader.read(0);
                
                reader.reset();
            } catch (IIOException e) {
                colorTp = TYPE_CMYK;
                checkMarker(file);
                pf = Sanselan.getICCpf(file);
                Writablewr wr = (Writablewr) reader.readwr(0null);
 
                
                reader.reset();
 
                if (colorTp == TYPE_YCCK) {
                    convertYcck2Cmyk(wr);
                }
 
                if (markerFlag) {
                    convInvColors(wr);
                }
                image = convertCmykToRgb(wr, pf);
                image.flush();
            } finally {
                stream.close(); 
            }
 
            return image;
        }
 
        return null;
    }
 
    public static void checkMarker(File file) throws IOException, ImageReadException {
        JpegImageParser parser = new JpegImageParser();
        ByteSource byteSource = new ByteSourceFile(file);
        @SuppressWarnings("rawtypes")
        ArrayList segments = parser.readSegments(byteSource, new int[] {
            0xffee
        }, true);
        if (segments != null && segments.size() >= 1) {
            UnknownSegment app14Segment = (UnknownSegment) segments.get(0);
            byte[] data = app14Segment.bytes;
            if (data.length >= 12 && data[0== 'A' && data[1== 'd' && data[2== 'o' && data[3== 'b' && data[4== 'e') {
                markerFlag = true;
                int transform = app14Segment.bytes[11& 0xff;
                if (transform == 2)
                    colorTp = TYPE_YCCK;
            }
        }
    }
 
    public static void convertYcck2Cmyk(Writablewr wr) {
        int height = wr.getHeight();
        int width = wr.getWidth();
        int stride = width * 4;
        int[] rowData = new int[stride];
        for (int h = 0; h < height; h++) {
            wr.getPixels(0, h, width, 1, rowData);
 
            for (int x = 0; x < stride; x += 4) {
                int y = rowData[x];
                int cb = rowData[x + 1];
                int cr = rowData[x + 2];
 
                int c = (int)(y + 1.402 * cr - 178.956);
                int m = (int)(y - 0.34414 * cb - 0.71414 * cr + 135.95984);
                y = (int)(y + 1.772 * cb - 226.316);
 
                if (c < 0)
                    c = 0;
                else if (c > 255)
                    c = 255;
                if (m < 0)
                    m = 0;
                else if (m > 255)
                    m = 255;
                if (y < 0)
                    y = 0;
                else if (y > 255)
                    y = 255;
 
                rowData[x] = 255 - c;
                rowData[x + 1= 255 - m;
                rowData[x + 2= 255 - y;
            }
 
            wr.setPixels(0, h, width, 1, rowData);
        }
    }
 
    public static void convInvColors(Writablewr wr) {
        int height = wr.getHeight();
        int width = wr.getWidth();
        int stride = width * 4;
        int[] rowData = new int[stride];
        for (int h = 0; h < height; h++) {
            wr.getPixels(0, h, width, 1, rowData);
            for (int x = 0; x < stride; x++)
                rowData[x] = 255 - rowData[x];
            wr.setPixels(0, h, width, 1, rowData);
        }
    }
 
    public static BufferedImage convertCmykToRgb(wr cmykwr, ICC_pf cmykpf) throws IOException {
 
        if (cmykpf == null) {
            cmykpf = ICC_pf.getInstance(CMYKConverter.class.getResourceAsStream("ISOcoated_v2_300_eci.icc"));
        }
 
        ICC_ColorSpace cmykCS = new ICC_ColorSpace(cmykpf);
        BufferedImage rgbImage = new BufferedImage(cmykwr.getWidth(), cmykwr.getHeight(), BufferedImage.TYPE_INT_RGB);
        Writablewr rgbwr = rgbImage.getwr();
        ColorSpace rgbCS = rgbImage.getColorModel().getColorSpace();
        ColorConvertOp cmykToRgb = new ColorConvertOp(cmykCS, rgbCS, null);
        cmykToRgb.filter(cmykwr, rgbwr);
        return rgbImage;
    }
 
    public static void intToBigEndian(int value, byte[] array, int index) {
        array[index] = (byte)(value >> 24);
        array[index + 1= (byte)(value >> 16);
        array[index + 2= (byte)(value >> 8);
        array[index + 3= (byte)(value);
    }
 
}
 
cs


+ Recent posts