WORK AROUND
Name: abR10136 Date: 04/13/2004
Usage of metadata object and explicitly specified destination type
helps to avoid major increase of size. Result still will be bigger
than optimal but this is less noticeable.
=================== BEGIN OF WORKAROUND EXAMPLE ======================
import java.awt.image.BufferedImage;
import java.awt.Graphics;
import javax.imageio.ImageIO;
import javax.imageio.IIOImage;
import javax.imageio.ImageWriter;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.event.IIOWriteWarningListener;
import javax.imageio.stream.ImageOutputStream;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.metadata.IIOInvalidTreeException;
import java.io.File;
import java.io.IOException;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class Workaround implements IIOWriteWarningListener {
public static void main(String[] args) throws IOException {
BufferedImage bi = ImageIO.read(new File(args[0]));
BufferedImage bi_argb = new BufferedImage(bi.getWidth(),
bi.getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics g = bi_argb.createGraphics();
g.drawImage(bi, 0, 0, null);
ImageWriter iw =
(ImageWriter)ImageIO.getImageWritersByFormatName("jpeg").next();
iw.addIIOWriteWarningListener(new Workaround());
ImageWriteParam p = iw.getDefaultWriteParam();
ImageTypeSpecifier type =
ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
p.setDestinationType(type);
p.setSourceBands(new int[] {0, 1, 2});
ImageOutputStream ios =
ImageIO.createImageOutputStream(new File("Workaround.jpeg"));
iw.setOutput(ios);
System.out.println("create metadata");
IIOMetadata meta = iw.getDefaultImageMetadata(type, null);
meta = addAdobeTransform(meta);
iw.write(null,
new IIOImage(bi.getData(), null, meta),
p);
ios.close();
}
public void warningOccurred(ImageWriter source,
int imageIndex,
String warning) {
System.out.println("WRITING WARNING: " + warning);
}
private static IIOMetadata addAdobeTransform(IIOMetadata meta) throws IIOInvalidTreeException {
// add the adobe transformation (transform 1 -> to YCbCr)
Node root = meta.getAsTree("javax_imageio_jpeg_image_1.0");
NodeList nlist = root.getChildNodes();
Node markerSequence = getChildNode(root, "markerSequence");
if (markerSequence == null) {
throw new RuntimeException("Invalid metadata!");
}
IIOMetadataNode adobeTransform = getChildNode(markerSequence, "app14Adobe");
if (adobeTransform == null) {
adobeTransform = new IIOMetadataNode("app14Adobe");
adobeTransform.setAttribute("transform" , "1"); // convert RGB to YCbCr
adobeTransform.setAttribute("version", "101");
adobeTransform.setAttribute("flags0", "0");
adobeTransform.setAttribute("flags1", "0");
markerSequence.appendChild(adobeTransform);
} else {
adobeTransform.setAttribute("transform" , "1");
}
meta.setFromTree("javax_imageio_jpeg_image_1.0", root);
return meta;
}
private static IIOMetadataNode getChildNode(Node p, String name) {
NodeList nlist = p.getChildNodes();
for (int i=0; i<nlist.getLength(); i++) {
Node n = nlist.item(i);
if (name.equals(n.getNodeName())) {
return (IIOMetadataNode)n;
}
}
return null;
}
}
==================== END OF WORKAROUND EXAMPLE =======================
|