일반적으로 이미지 타입이 RGB가 아닌 CMYK인 경우
ImageIO.read() 를 이용하여 읽을 경우 Unsupported Image Type 가 발생한다.
일반적으로 CMYK타입 이미지는 ImageIO 로 read 하기 불가능하다
ImageIO.read(file); 를 이용해서 Exception이 발생할 경우 컨버터를 이용하여 처리하는 방식을 이용하여 오류를 줄일 수 있다.
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(0, null); 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 |
'Development > Java' 카테고리의 다른 글
iReport Designer Tool 가이드 (0) | 2020.03.30 |
---|---|
Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener (0) | 2019.02.04 |
[Spring Framework] Cannot create PoolableConnectionFactory ORA-00923 (0) | 2018.07.26 |
List Conllection의 중복제거를 위한 HashSet Collection (0) | 2018.04.06 |
List에 내용물이 String이나 int가 아닌경우 정렬 (0) | 2018.04.06 |