/** * Returns the raw color model of the reader at the specified image index * * @param reader * @param imageIndex * @return */ private ColorModel getRawColorModel(ImageReader reader, int imageIndex) { try { ImageTypeSpecifier imageType = reader.getRawImageType(imageIndex); if (imageType == null) { return null; } ColorModel cm = imageType.getColorModel(); return cm; } catch (Exception e) { LOGGER.log(Level.FINE, "Failed to determine the native color model of the reader", e); } return null; }
@Override public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException { readIFD(imageIndex); ImageTypeSpecifier rawType = getRawImageType(imageIndex); Set<ImageTypeSpecifier> specs = new LinkedHashSet<>(5); // TODO: Based on raw type, we can probably convert to most RGB types at least, maybe gray etc if (rawType.getColorModel().getColorSpace().getType() == ColorSpace.TYPE_RGB) { if (rawType.getNumBands() == 3 && rawType.getBitsPerBand(0) == 8) { specs.add(ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_3BYTE_BGR)); // specs.add(ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_BGR)); // specs.add(ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB)); } else if (rawType.getNumBands() == 4 && rawType.getBitsPerBand(0) == 8) { specs.add(ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_4BYTE_ABGR)); // specs.add(ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_ARGB)); specs.add(ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_4BYTE_ABGR_PRE)); } } specs.add(rawType); return specs.iterator(); }
private TIFFImageMetadata initMeta(final Directory ifd, final ImageTypeSpecifier imageType, final ImageWriteParam param) { Validate.notNull(imageType, "imageType"); Map<Integer, Entry> entries = new LinkedHashMap<>(ifd != null ? ifd.size() + 10 : 20); if (ifd != null) { for (Entry entry : ifd) { entries.put((Integer) entry.getIdentifier(), entry); } } int compression; if ((param == null || param.getCompressionMode() == TIFFImageWriteParam.MODE_COPY_FROM_METADATA) && ifd != null && ifd.getEntryById(TIFF.TAG_COMPRESSION) != null) { compression = ((Number) ifd.getEntryById(TIFF.TAG_COMPRESSION).getValue()).intValue(); } else { compression = TIFFImageWriteParam.getCompressionType(param); } int photometricInterpretation = getPhotometricInterpretation(imageType.getColorModel(), compression); entries.put(TIFF.TAG_PHOTOMETRIC_INTERPRETATION, new TIFFEntry(TIFF.TAG_PHOTOMETRIC_INTERPRETATION, TIFF.TYPE_SHORT, photometricInterpretation)); // TODO: Set values from param if != null + combined values... return new TIFFImageMetadata(entries.values()); }
@Override public boolean canEncodeImage(final ImageTypeSpecifier type) { // Fast case, it's a known, supported type switch (type.getBufferedImageType()) { case BufferedImage.TYPE_INT_RGB: case BufferedImage.TYPE_INT_ARGB: case BufferedImage.TYPE_INT_ARGB_PRE: case BufferedImage.TYPE_3BYTE_BGR: case BufferedImage.TYPE_4BYTE_ABGR: case BufferedImage.TYPE_4BYTE_ABGR_PRE: case BufferedImage.TYPE_USHORT_555_RGB: case BufferedImage.TYPE_BYTE_GRAY: case BufferedImage.TYPE_BYTE_INDEXED: return true; case BufferedImage.TYPE_BYTE_BINARY: // Could be supported? Uncertain if the format allows < 8 bit/sample for color map entries case BufferedImage.TYPE_INT_BGR: // TODO: Should be supported, just needs to invert band indices/offsets case BufferedImage.TYPE_USHORT_565_RGB: case BufferedImage.TYPE_USHORT_GRAY: return false; default: // Fall through } // Inspect color model etc. ColorSpace colorSpace = type.getColorModel().getColorSpace(); if (!(colorSpace.getType() == ColorSpace.TYPE_RGB || colorSpace.getType() == ColorSpace.TYPE_GRAY)) { return false; } // TODO! return true; }
private ImageTypeSpecifier getRawImageTypeForLayer(final int layerIndex) throws IOException { ImageTypeSpecifier compositeType = getRawImageTypeForCompositeLayer(); PSDLayerInfo layerInfo = metadata.layerInfo.get(layerIndex); // If layer has more channels than composite data, it's normally extra alpha... if (layerInfo.channelInfo.length > compositeType.getNumBands()) { // ...but, it could also be just one of the user masks... int newBandNum = 0; for (PSDChannelInfo channelInfo : layerInfo.channelInfo) { // -2 = user supplied layer mask, -3 real user supplied layer mask (when both a user mask and a vector mask are present) if (channelInfo.channelId >= -1) { newBandNum++; } } // If there really is more channels, then create new imageTypeSpec if (newBandNum > compositeType.getNumBands()) { int[] indices = new int[newBandNum]; for (int i = 0, indicesLength = indices.length; i < indicesLength; i++) { indices[i] = i; } int[] offs = new int[newBandNum]; for (int i = 0, offsLength = offs.length; i < offsLength; i++) { offs[i] = 0; } return ImageTypeSpecifiers.createBanded(compositeType.getColorModel().getColorSpace(), indices, offs, compositeType.getSampleModel().getDataType(), true, false); } } return compositeType; }
private boolean isDestinationCMYK(final IIOImage image, final ImageWriteParam param) { // If destination type != null, rendered image type doesn't matter return !image.hasRaster() && image.getRenderedImage().getColorModel().getColorSpace().getType() == ColorSpace.TYPE_CMYK || param != null && param.getDestinationType() != null && param.getDestinationType().getColorModel().getColorSpace().getType() == ColorSpace.TYPE_CMYK; }
private ByteArrayOutputStream transcode(final ImageReader reader, final URL resource, final ImageWriter writer, int outCSType) throws IOException { try (ImageInputStream input = ImageIO.createImageInputStream(resource)) { reader.setInput(input); ImageTypeSpecifier specifier = null; Iterator<ImageTypeSpecifier> types = reader.getImageTypes(0); while (types.hasNext()) { ImageTypeSpecifier type = types.next(); if (type.getColorModel().getColorSpace().getType() == outCSType) { specifier = type; break; } } // Read image with requested color space ImageReadParam readParam = reader.getDefaultReadParam(); readParam.setSourceRegion(new Rectangle(Math.min(100, reader.getWidth(0)), Math.min(100, reader.getHeight(0)))); readParam.setDestinationType(specifier); IIOImage image = reader.readAll(0, readParam); // Write it back ByteArrayOutputStream bytes = new ByteArrayOutputStream(1024); try (ImageOutputStream output = new MemoryCacheImageOutputStream(bytes)) { writer.setOutput(output); ImageWriteParam writeParam = writer.getDefaultWriteParam(); writeParam.setDestinationType(specifier); writer.write(null, image, writeParam); return bytes; } } }
@Test public void testGray() { ImageTypeSpecifier spec = UInt32ImageTypeSpecifier.createInterleaved(GRAY, new int [] {0}, false, false); assertEquals(1, spec.getNumBands()); assertEquals(1, spec.getNumComponents()); assertEquals(32, spec.getBitsPerBand(0)); assertThat(spec.getColorModel(), is(ComponentColorModel.class)); assertFalse(spec.getColorModel().hasAlpha()); assertFalse(spec.getColorModel().isAlphaPremultiplied()); assertEquals(1, spec.getColorModel().getNumComponents()); assertEquals(1, spec.getColorModel().getNumColorComponents()); assertThat(spec.getSampleModel(), is(PixelInterleavedSampleModel.class)); assertEquals(1, spec.getSampleModel().getNumBands()); assertEquals(1, spec.getSampleModel().getNumDataElements()); }
@Test public void testGrayAlpha() { ImageTypeSpecifier spec = UInt32ImageTypeSpecifier.createInterleaved(GRAY, new int [] {0, 1}, true, false); assertEquals(2, spec.getNumBands()); assertEquals(2, spec.getNumComponents()); assertEquals(32, spec.getBitsPerBand(0)); assertEquals(32, spec.getBitsPerBand(1)); assertThat(spec.getColorModel(), is(ComponentColorModel.class)); assertTrue(spec.getColorModel().hasAlpha()); assertFalse(spec.getColorModel().isAlphaPremultiplied()); assertEquals(2, spec.getColorModel().getNumComponents()); assertEquals(1, spec.getColorModel().getNumColorComponents()); assertThat(spec.getSampleModel(), is(PixelInterleavedSampleModel.class)); assertEquals(2, spec.getSampleModel().getNumBands()); assertEquals(2, spec.getSampleModel().getNumDataElements()); }
@Test public void testRGB() { ImageTypeSpecifier spec = UInt32ImageTypeSpecifier.createInterleaved(sRGB, new int [] {0, 1, 2}, false, false); assertEquals(3, spec.getNumBands()); assertEquals(3, spec.getNumComponents()); assertEquals(32, spec.getBitsPerBand(0)); assertEquals(32, spec.getBitsPerBand(1)); assertEquals(32, spec.getBitsPerBand(2)); assertThat(spec.getColorModel(), is(ComponentColorModel.class)); assertFalse(spec.getColorModel().hasAlpha()); assertFalse(spec.getColorModel().isAlphaPremultiplied()); assertEquals(3, spec.getColorModel().getNumComponents()); assertEquals(3, spec.getColorModel().getNumColorComponents()); assertThat(spec.getSampleModel(), is(PixelInterleavedSampleModel.class)); assertEquals(3, spec.getSampleModel().getNumBands()); assertEquals(3, spec.getSampleModel().getNumDataElements()); }
@Test public void testRGBAlphaPre() { ImageTypeSpecifier spec = UInt32ImageTypeSpecifier.createInterleaved(sRGB, new int [] {0, 1, 2, 3}, true, true); assertEquals(4, spec.getNumBands()); assertEquals(4, spec.getNumComponents()); assertEquals(32, spec.getBitsPerBand(0)); assertEquals(32, spec.getBitsPerBand(1)); assertEquals(32, spec.getBitsPerBand(2)); assertEquals(32, spec.getBitsPerBand(3)); assertThat(spec.getColorModel(), is(ComponentColorModel.class)); assertTrue(spec.getColorModel().hasAlpha()); assertTrue(spec.getColorModel().isAlphaPremultiplied()); assertEquals(4, spec.getColorModel().getNumComponents()); assertEquals(3, spec.getColorModel().getNumColorComponents()); assertThat(spec.getSampleModel(), is(PixelInterleavedSampleModel.class)); assertEquals(4, spec.getSampleModel().getNumBands()); assertEquals(4, spec.getSampleModel().getNumDataElements()); }
@Test public void testRGBAlpha() { ImageTypeSpecifier spec = UInt32ImageTypeSpecifier.createInterleaved(sRGB, new int [] {0, 1, 2, 3}, true, false); assertEquals(4, spec.getNumBands()); assertEquals(4, spec.getNumComponents()); assertEquals(32, spec.getBitsPerBand(0)); assertEquals(32, spec.getBitsPerBand(1)); assertEquals(32, spec.getBitsPerBand(2)); assertEquals(32, spec.getBitsPerBand(3)); assertThat(spec.getColorModel(), is(ComponentColorModel.class)); assertTrue(spec.getColorModel().hasAlpha()); assertFalse(spec.getColorModel().isAlphaPremultiplied()); assertEquals(4, spec.getColorModel().getNumComponents()); assertEquals(3, spec.getColorModel().getNumColorComponents()); assertThat(spec.getSampleModel(), is(PixelInterleavedSampleModel.class)); assertEquals(4, spec.getSampleModel().getNumBands()); assertEquals(4, spec.getSampleModel().getNumDataElements()); }
@Test public void testCMYK() { ImageTypeSpecifier spec = UInt32ImageTypeSpecifier.createInterleaved(CMYK, new int [] {0, 1, 2, 3}, false, false); assertEquals(4, spec.getNumBands()); assertEquals(4, spec.getNumComponents()); assertEquals(32, spec.getBitsPerBand(0)); assertEquals(32, spec.getBitsPerBand(1)); assertEquals(32, spec.getBitsPerBand(2)); assertEquals(32, spec.getBitsPerBand(3)); assertThat(spec.getColorModel(), is(ComponentColorModel.class)); assertFalse(spec.getColorModel().hasAlpha()); assertFalse(spec.getColorModel().isAlphaPremultiplied()); assertEquals(4, spec.getColorModel().getNumComponents()); assertEquals(4, spec.getColorModel().getNumColorComponents()); assertThat(spec.getSampleModel(), is(PixelInterleavedSampleModel.class)); assertEquals(4, spec.getSampleModel().getNumBands()); assertEquals(4, spec.getSampleModel().getNumDataElements()); }
@Test public void testCMYKAlpha() { ImageTypeSpecifier spec = UInt32ImageTypeSpecifier.createInterleaved(CMYK, new int [] {0, 1, 2, 3, 4}, true, false); assertEquals(5, spec.getNumBands()); assertEquals(5, spec.getNumComponents()); assertEquals(32, spec.getBitsPerBand(0)); assertEquals(32, spec.getBitsPerBand(1)); assertEquals(32, spec.getBitsPerBand(2)); assertEquals(32, spec.getBitsPerBand(3)); assertEquals(32, spec.getBitsPerBand(4)); assertThat(spec.getColorModel(), is(ComponentColorModel.class)); assertTrue(spec.getColorModel().hasAlpha()); assertFalse(spec.getColorModel().isAlphaPremultiplied()); assertEquals(5, spec.getColorModel().getNumComponents()); assertEquals(4, spec.getColorModel().getNumColorComponents()); assertThat(spec.getSampleModel(), is(PixelInterleavedSampleModel.class)); assertEquals(5, spec.getSampleModel().getNumBands()); assertEquals(5, spec.getSampleModel().getNumDataElements()); }
/** * Extract the ImageLayout from the provided reader for the first available image. * * @param reader an istance of {@link ImageReader} * @throws IOException in case an error occurs */ protected void setLayout(ImageReader reader) throws IOException { Utilities.ensureNonNull("reader", reader); // save ImageLayout ImageLayout2 layout = new ImageLayout2(); ImageTypeSpecifier its = reader.getImageTypes(0).next(); layout.setColorModel(its.getColorModel()).setSampleModel(its.getSampleModel()); layout.setMinX(0).setMinY(0).setWidth(reader.getWidth(0)).setHeight(reader.getHeight(0)); layout.setTileGridXOffset(0) .setTileGridYOffset(0) .setTileWidth(reader.getTileWidth(0)) .setTileHeight(reader.getTileHeight(0)); setlayout(layout); }
@Test public void testGetImageTypesCMYK() throws IOException { // Make sure CMYK images will report their embedded color profile among image types JPEGImageReader reader = createReader(); List<TestData> cmykData = getCMYKData(); for (TestData data : cmykData) { reader.setInput(data.getInputStream()); Iterator<ImageTypeSpecifier> types = reader.getImageTypes(0); assertTrue(data + " has no image types", types.hasNext()); boolean hasRGBType = false; boolean hasCMYKType = false; while (types.hasNext()) { ImageTypeSpecifier type = types.next(); int csType = type.getColorModel().getColorSpace().getType(); if (csType == ColorSpace.TYPE_RGB) { hasRGBType = true; } else if (csType == ColorSpace.TYPE_CMYK) { assertTrue("CMYK types should be delivered after RGB types (violates \"contract\" of more \"natural\" type first) for " + data, hasRGBType); hasCMYKType = true; break; } } assertTrue("No RGB types for " + data, hasRGBType); assertTrue("No CMYK types for " + data, hasCMYKType); } reader.dispose(); }
@Test public void testReadCMYKAsCMYK() throws IOException { // Make sure CMYK images can be read and still contain their original (embedded) color profile JPEGImageReader reader = createReader(); List<TestData> cmykData = getCMYKData(); for (TestData data : cmykData) { reader.setInput(data.getInputStream()); Iterator<ImageTypeSpecifier> types = reader.getImageTypes(0); assertTrue(data + " has no image types", types.hasNext()); ImageTypeSpecifier cmykType = null; while (types.hasNext()) { ImageTypeSpecifier type = types.next(); int csType = type.getColorModel().getColorSpace().getType(); if (csType == ColorSpace.TYPE_CMYK) { cmykType = type; break; } } assertNotNull("No CMYK types for " + data, cmykType); ImageReadParam param = reader.getDefaultReadParam(); param.setDestinationType(cmykType); param.setSourceRegion(new Rectangle(reader.getWidth(0), 8)); // We don't really need to read it all BufferedImage image = reader.read(0, param); assertNotNull(image); assertEquals(ColorSpace.TYPE_CMYK, image.getColorModel().getColorSpace().getType()); } reader.dispose(); }
assertEquals(type.getColorModel().getColorSpace(), image.getColorModel().getColorSpace());
@Test public void testCreatePacked8() { // "BYTE 332 RGB" assertEquals( createPacked(sRGB, 0xe0, 0x1c, 0x03, 0x0, DataBuffer.TYPE_BYTE, false), ImageTypeSpecifiers.createPacked(sRGB, 0xe0, 0x1c, 0x3, 0x0, DataBuffer.TYPE_BYTE, false) ); // "BYTE 2222 ARGB" assertEquals( createPacked(sRGB, 0xc0, 0x30, 0x0c, 0x03, DataBuffer.TYPE_BYTE, false), ImageTypeSpecifiers.createPacked(sRGB, 0xc0, 0x30, 0x0c, 0x03, DataBuffer.TYPE_BYTE, false) ); // "BYTE 2222 ARGB PRE" assertEquals( createPacked(sRGB, 0xc0, 0x30, 0x0c, 0x03, DataBuffer.TYPE_BYTE, true), ImageTypeSpecifiers.createPacked(sRGB, 0xc0, 0x30, 0x0c, 0x03, DataBuffer.TYPE_BYTE, true) ); // Extra: Make sure color models bits is actually 8 (ImageTypeSpecifiers equivalent returns 32) assertEquals(8, ImageTypeSpecifiers.createPacked(sRGB, 0xc0, 0x30, 0x0c, 0x03, DataBuffer.TYPE_BYTE, false).getColorModel().getPixelSize()); }
@Test public void testCreatePacked16() { // TYPE_USHORT_555_RGB assertEquals( createPacked(sRGB, DCM_555_RED_MASK, DCM_555_GRN_MASK, DCM_555_BLU_MASK, 0, DataBuffer.TYPE_USHORT, false), ImageTypeSpecifiers.createPacked(sRGB, DCM_555_RED_MASK, DCM_555_GRN_MASK, DCM_555_BLU_MASK, 0, DataBuffer.TYPE_USHORT, false) ); // "SHORT 555 RGB" (impossible, only BYTE, USHORT, INT supported) // TYPE_USHORT_565_RGB assertEquals( createPacked(sRGB, DCM_565_RED_MASK, DCM_565_GRN_MASK, DCM_565_BLU_MASK, 0, DataBuffer.TYPE_USHORT, false), ImageTypeSpecifiers.createPacked(sRGB, DCM_565_RED_MASK, DCM_565_GRN_MASK, DCM_565_BLU_MASK, 0, DataBuffer.TYPE_USHORT, false) ); // "USHORT 4444 ARGB" assertEquals( createPacked(sRGB, 0xf00, 0xf0, 0xf, 0xf000, DataBuffer.TYPE_USHORT, false), ImageTypeSpecifiers.createPacked(sRGB, 0xf00, 0xf0, 0xf, 0xf000, DataBuffer.TYPE_USHORT, false) ); // "USHORT 4444 ARGB PRE" assertEquals( createPacked(sRGB, 0xf00, 0xf0, 0xf, 0xf000, DataBuffer.TYPE_USHORT, true), ImageTypeSpecifiers.createPacked(sRGB, 0xf00, 0xf0, 0xf, 0xf000, DataBuffer.TYPE_USHORT, true) ); // Extra: Make sure color models bits is actually 16 (ImageTypeSpecifier equivalent returns 32) assertEquals(16, ImageTypeSpecifiers.createPacked(sRGB, DCM_565_RED_MASK, DCM_565_GRN_MASK, DCM_565_BLU_MASK, 0, DataBuffer.TYPE_USHORT, false).getColorModel().getPixelSize()); }