Skip to main content

[JAVA2D] loading and saving jpegs using cmyk color mode

2 replies [Last post]
Anonymous

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Chris Campbell

Ahh, I forgot that our JPEGImageReader does not currently support
reading CMYK JPEG images. See the following for more details:
http://java.sun.com/j2se/1.5.0/docs/api/javax/imageio/metadata/doc-
files/jpeg_metadata.html#color

I'm not sure if we can ever loosen this restriction, but you might want
to file an RFE against java/imageio, and we can investigate whether it
would be possible to add support for CMYK images.

Note that there is a separate interest list devoted to Image I/O:
java-imageio-interest@java.sun.com

Thanks,
Chris

On Sep 9, 2003, at 3:34 PM, Francisco Hernandez wrote:
> I actually did try to use ImageIO but it would fail to load the cmyk
> jpgs, cmyk tifs work though..
> I'd get this exception thrown: javax.imageio.IIOException: Unsupported
> Image Type
>
> I also tried using the jai imageio plugins but they didnt help
>
> Chris Campbell wrote:
>
>> Hi Francisco,
>>
>> The JPEGImageEncoder/Decoder classes (in the com.sun.image.codec.jpeg
>> package) that you're using here are not supported. Since JDK 1.4,
>> the Image I/O API is the supported mechanism for reading and writing
>> images, and the JPEG IIO plugins should be higher quality than the
>> older (unsupported) JPEG classes.
>>
>> Using IIO, your code snippet would be greatly simplified, and I'm
>> hoping that there wouldn't be any problems related to CMYK:
>>
>> import javax.imageio.*;
>> public static void main(String args[]) throws Exception {
>> String inputImageFileName = "front_cmyk.jpg";
>> String outputImageFileName = "front_" +
>> System.currentTimeMillis() + ".jpg";
>> OutputStream out = new FileOutputStream(outputImageFileName);
>>
>> BufferedImage image = ImageIO.read(new
>> File(inputImageFileName));
>> ImageIO.write(image, "jpeg", out);
>>
>> out.close();
>> System.out.println("output file name: " + outputImageFileName);
>> }
>>
>> For more information on Image I/O:
>> http://java.sun.com/j2se/1.5.0/docs/guide/imageio/
>>
>> Thanks,
>> Chris
>>
>> On Sep 4, 2003, at 2:46 AM, Francisco Hernandez wrote:
>>
>>> I'm having a bit of trouble opening a cmyk image and saving it again
>>> as
>>> cmyk, it actually does save as cmyk but the colors are totally off
>>>
>>> below is the code im using, I basically just want to open a cmyk
>>> image,
>>> write some text and shapes onto the image (using Graphics2D), then
>>> save it,
>>> but I removed the part of the code where it writes on the image for
>>> simplification of the code listing here
>>>
>>>
>>>
>>> public static void main(String args[]) throws Exception {
>>> String inputImageFileName = "front_cmyk.jpg";
>>> String outputImageFileName = "front_" +
>>> System.currentTimeMillis() + ".jpg";
>>> OutputStream out = new FileOutputStream(outputImageFileName);
>>>
>>> JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(new
>>> FileInputStream(inputImageFileName));
>>> BufferedImage image = decoder.decodeAsBufferedImage();
>>>
>>> JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
>>> JPEGEncodeParam param =
>>> encoder.getDefaultJPEGEncodeParam(image.getRaster(),
>>> JPEGDecodeParam.COLOR_ID_CMYK);
>>> //JPEGEncodeParam param =
>>> encoder.getDefaultJPEGEncodeParam(image);
>>> param.setQuality(1, false);
>>>
>>> encoder.encode(image.getRaster(), param);
>>> //encoder.encode(image, param);
>>>
>>>
>>> out.close();
>>> System.out.println("output file name: " +
>>> outputImageFileName);
>>> }
>>>
>>> =====================================================================
>>> == ====
>>> To unsubscribe, send email to listserv@java.sun.com and include in
>>> the body
>>> of the message "signoff JAVA2D-INTEREST". For general help, send
>>> email to
>>> listserv@java.sun.com and include in the body of the message "help".
>>
>>
>>
>
>

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

burma

There is an open rfe ( 4799903) about this problem.
You should have a look at the comment by phelps at the bottom of the page.

Here after is a piece of code I use to load CMYK jpeg images.

Emmanuel D.

------------------------------------------------------------------------------

// extract metadata
public static BufferedImage readImage(File file) throws IOException {
// Get an ImageReader.
ImageInputStream input = ImageIO.createImageInputStream(file);
Iterator readers = ImageIO.getImageReaders(input);
if(readers == null || !readers.hasNext()) {
throw new RuntimeException("No ImageReaders found");
}

ImageReader reader = (ImageReader) readers.next();
reader.setInput(input);
String format = reader.getFormatName() ;

if ( "JPEG".equalsIgnoreCase(format) ||
"JPG".equalsIgnoreCase(format) ) {
IIOMetadata metadata = reader.getImageMetadata(0);
String metadataFormat = metadata.getNativeMetadataFormatName() ;
IIOMetadataNode iioNode = (IIOMetadataNode)
metadata.getAsTree(metadataFormat);

NodeList children = iioNode.getElementsByTagName("app14Adobe") ;
if ( children.getLength() > 0 ) {
iioNode = (IIOMetadataNode) children.item(0) ;
int transform =
Integer.parseInt(iioNode.getAttribute("transform")) ;
Raster raster = reader.readRaster(0,
reader.getDefaultReadParam()) ;

if ( input != null ) input.close() ;
reader.dispose();

return createJPEG4(raster,transform) ;
}
}
throw new RuntimeException("No ImageReaders found");
}

/**

Java's ImageIO can't process 4-component
images

and Java2D can't apply AffineTransformOp
either,

so convert raster data to
RGB.

Technique due to MArk
Stephens.

Free for any
use.

*/
private static BufferedImage createJPEG4(Raster raster, int xform) {
int w = raster.getWidth() ;
int h = raster.getHeight();
byte[] rgb = new byte[w*h*3];

// if (Adobe_APP14 and transform==2) then YCCK else
CMYK

if (xform == 2) { // YCCK --
Adobe

float[] Y = raster.getSamples(0,0,w,h, 0, (float[])null) ;
float[] Cb = raster.getSamples(0,0,w,h, 1, (float[])null) ;
float[] Cr = raster.getSamples(0,0,w,h, 2, (float[])null) ;
float[] K = raster.getSamples(0,0,w,h, 3, (float[])null) ;

for (int i=0,imax=Y.length, base=0; i float k=220 - K[i], y = 255-Y[i], cb=255-Cb[i],
cr=255-Cr[i];

double val = y + 1.402*(cr-128) - k ;
val = ( val - 128) * .65f + 128 ;
rgb[base] = val<0.0? (byte)0: val>255.0? (byte)0xff:
(byte)(val+0.5);

val = y - 0.34414*(cb-128) - 0.71414*(cr-128) - k ;
val = ( val - 128) * .65f + 128 ;
rgb[base+1] = val<0.0? (byte)0: val>255.0? (byte)0xff:
(byte)(val+0.5);

val = y + 1.772 * (cb-128) - k ;
val = ( val - 128) * .65f + 128 ;
rgb[base+2] = val<0.0? (byte)0: val>255.0? (byte)0xff:
(byte)(val+0.5);
}

}
else {
//assert xform==0: xform; //
CMYK

int[] C = raster.getSamples(0,0,w,h, 0, (int[])null) ;
int[] M = raster.getSamples(0,0,w,h, 1, (int[])null) ;
int[] Y = raster.getSamples(0,0,w,h, 2, (int[])null) ;
int[] K = raster.getSamples(0,0,w,h, 3, (int[])null) ;

for (int i=0,imax=C.length, base=0; i int c = 255 - C[i] ;
int m = 255 - M[i] ;
int y = 255 - Y[i] ;
int k = 255 - K[i] ;
float kk = k/255f ;

rgb[base] = (byte)(255 - Math.min(255f, c * kk + k));
rgb[base+1] = (byte)(255 - Math.min(255f, m * kk + k));
rgb[base+2] = (byte)(255 - Math.min(255f, y * kk + k));
}
}

// from other image types we know InterleavedRaster's can be
// manipulated by AffineTransformOp, so create one of
those.
raster = Raster.createInterleavedRaster(
new DataBufferByte(rgb, rgb.length),
w, h, w*3,3, new int[] {0,1,2 }, null);

ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
ColorModel cm = new ComponentColorModel(cs, false, true,
Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
return new BufferedImage(cm, (WritableRaster) raster, true, null);
}

Chris Campbell wrote:

> Ahh, I forgot that our JPEGImageReader does not currently support
> reading CMYK JPEG images. See the following for more details:
> http://java.sun.com/j2se/1.5.0/docs/api/javax/imageio/metadata/doc-
> files/jpeg_metadata.html#color
>
> I'm not sure if we can ever loosen this restriction, but you might want
> to file an RFE against java/imageio, and we can investigate whether it
> would be possible to add support for CMYK images.
>
> Note that there is a separate interest list devoted to Image I/O:
> java-imageio-interest@java.sun.com
>
> Thanks,
> Chris
>

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".