/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.pdfbox.util; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.io.File; import java.io.IOException; import java.util.Iterator; import javax.imageio.IIOException; import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageTypeSpecifier; import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.metadata.IIOInvalidTreeException; import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadataNode; import javax.imageio.stream.ImageOutputStream; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * This class handles some ImageIO operations. * * @version $Revision$ * */ public class ImageIOUtil { private ImageIOUtil() { // Default constructor } /** * Converts a given page range of a PDF document to bitmap images. * @param image the image to be written * @param imageFormat the target format (ex. "png") * @param filename used to construct the filename for the individual images * @param imageType the image type (see {@link BufferedImage}.TYPE_*) * @param resolution the resolution in dpi (dots per inch) * @return true if the images were produced, false if there was an error * @throws IOException if an I/O error occurs */ public static boolean writeImage(BufferedImage image, String imageFormat, String filename, int imageType, int resolution) throws IOException { boolean bSuccess = true; ImageOutputStream output = null; ImageWriter imageWriter = null; try { String fileName = filename + "." + imageFormat; output = ImageIO.createImageOutputStream( new File( fileName ) ); boolean foundWriter = false; Iterator<ImageWriter> writerIter = ImageIO.getImageWritersByFormatName( imageFormat ); while( writerIter.hasNext() && !foundWriter ) { try { imageWriter = (ImageWriter)writerIter.next(); ImageWriteParam writerParams = imageWriter.getDefaultWriteParam(); if( writerParams.canWriteCompressed() ) { writerParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // reset the compression type if overwritten by setCompressionMode if (writerParams.getCompressionType() == null) { writerParams.setCompressionType(writerParams.getCompressionTypes()[0]); } writerParams.setCompressionQuality(1.0f); } IIOMetadata meta = createMetadata( image, imageWriter, writerParams, resolution); imageWriter.setOutput( output ); imageWriter.write( null, new IIOImage( image, null, meta ), writerParams ); foundWriter = true; } catch( IIOException io ) { throw new IOException( io.getMessage() ); } finally { if( imageWriter != null ) { imageWriter.dispose(); } } } if( !foundWriter ) { bSuccess = false; } } finally { if( output != null ) { output.flush(); output.close(); } } return bSuccess; } private static IIOMetadata createMetadata(RenderedImage image, ImageWriter imageWriter, ImageWriteParam writerParams, int resolution) { ImageTypeSpecifier type; if (writerParams.getDestinationType() != null) { type = writerParams.getDestinationType(); } else { type = ImageTypeSpecifier.createFromRenderedImage( image ); } IIOMetadata meta = imageWriter.getDefaultImageMetadata( type, writerParams ); return (addResolution(meta, resolution) ? meta : null); } private static final String STANDARD_METADATA_FORMAT = "javax_imageio_1.0"; private static boolean addResolution(IIOMetadata meta, int resolution) { if (!meta.isReadOnly() && meta.isStandardMetadataFormatSupported()) { IIOMetadataNode root = (IIOMetadataNode)meta.getAsTree(STANDARD_METADATA_FORMAT); IIOMetadataNode dim = getChildNode(root, "Dimension"); if (dim == null) { dim = new IIOMetadataNode("Dimension"); root.appendChild(dim); } IIOMetadataNode child; child = getChildNode(dim, "HorizontalPixelSize"); if (child == null) { child = new IIOMetadataNode("HorizontalPixelSize"); dim.appendChild(child); } child.setAttribute("value", Double.toString(resolution / 25.4)); child = getChildNode(dim, "VerticalPixelSize"); if (child == null) { child = new IIOMetadataNode("VerticalPixelSize"); dim.appendChild(child); } child.setAttribute("value", Double.toString(resolution / 25.4)); try { meta.mergeTree(STANDARD_METADATA_FORMAT, root); } catch (IIOInvalidTreeException e) { throw new RuntimeException("Cannot update image metadata: " + e.getMessage()); } return true; } return false; } private static IIOMetadataNode getChildNode(Node n, String name) { NodeList nodes = n.getChildNodes(); for (int i = 0; i < nodes.getLength(); i++) { Node child = nodes.item(i); if (name.equals(child.getNodeName())) { return (IIOMetadataNode)child; } } return null; } }