5

I have the following code:

ImageIO.write(originalImage, OUTPUT_TYPE, resultOutput);

This is an invocation of the following javax.imageio.ImageIO method:

public static boolean write(RenderedImage im,
                            String formatName,
                            File output)
                     throws IOException

This turns an original BMP image into a JGP output. Is it possible to also store DPI and Paper Size information in the JPEG to aid in printing operations?

Charles
  • 50,943
  • 13
  • 104
  • 142
Paul Reiners
  • 8,576
  • 33
  • 117
  • 202

2 Answers2

4

I found this post for setting DPI on PNG Files. It pointed out that you should use 'metadata.mergeTree' to properly save your metadata.

With that in mind, here is some working groovy code that takes a BMP file and creates a JPG file at arbitrary DPI:

import java.awt.image.BufferedImage
import java.io.File
import java.util.Hashtable
import java.util.Map
import javax.imageio.*
import javax.imageio.stream.*
import javax.imageio.metadata.*
import javax.imageio.plugins.jpeg.*
import org.w3c.dom.*

File sourceFile = new File("sample.bmp")
File destinationFile = new File("sample.jpg")

dpi = 100

BufferedImage sourceImage = ImageIO.read(sourceFile)
ImageWriter imageWriter = ImageIO.getImageWritersBySuffix("jpeg").next();
ImageOutputStream ios = ImageIO.createImageOutputStream(destinationFile);
imageWriter.setOutput(ios);
def jpegParams = imageWriter.getDefaultWriteParam();

IIOMetadata data = imageWriter.getDefaultImageMetadata(new ImageTypeSpecifier(sourceImage), jpegParams);
Element tree = (Element)data.getAsTree("javax_imageio_jpeg_image_1.0");
Element jfif = (Element)tree.getElementsByTagName("app0JFIF").item(0);
jfif.setAttribute("Xdensity", Integer.toString(dpi));
jfif.setAttribute("Ydensity", Integer.toString(dpi));
jfif.setAttribute("resUnits", "1"); // density is dots per inch                 
data.mergeTree("javax_imageio_jpeg_image_1.0",tree)

// Write and clean up
imageWriter.write(data, new IIOImage(sourceImage, null, data), jpegParams);
ios.close();
imageWriter.dispose();

Worked fine for me in that OSX's Preview app and Gimp both reported that the resulting image was 100 DPI. As to Paper Size...I imagine this is directly determined by DPI? I couldn't find any JPEG property that would set that particular value.

Community
  • 1
  • 1
dsummersl
  • 6,588
  • 50
  • 65
  • 1
    Paper size is automatically calculated using dpi and pixel dimensions. No need to set it in metadata. Verified it on PhotoShop and a few printer clients. – Niket Kumar Apr 25 '16 at 21:28
3

You may consider using Commons Sanselan, instead of ImageIO for this task.

See http://commons.apache.org/sanselan/whysanselan.html for more info.

Guillaume Serre
  • 307
  • 2
  • 8
  • Yes, this seems a good solution, being able to write: http://www.screaming-penguin.com/node/7485 – Joop Eggen Dec 31 '11 at 01:04
  • This doesn't work in sanselan: convert BMP to JPG. Perhaps its only useful for modifying/adding exif type information. – dsummersl Jan 05 '12 at 20:04