Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set DPI information in an image?

Tags:

java

image

I have an application that I want to export high-resolution (or rather, high pixel density?) images for printing - for example, I want images that print at 250 dots per inch (DPI), instead of the default, which I understand to be 72 DPI.

I'm using a BufferedImage with a Graphics2D object to draw the image, then ImageIO.write() to save the image.

Any idea how I can set the DPI?

like image 801
David Koelle Avatar asked Nov 26 '08 18:11

David Koelle


People also ask

How do I make my 600 DPI image?

Open your picture to adobe photoshop- click image size-click width 6.5 inch and resulation (dpi) 300/400/600 you want. -click ok. Your picture will be 300/400/600 dpi then click image- brightness and contrast- increase contrast 20 then click ok.


3 Answers

Kurt's answer showed the way, still it took me quite some time to get it run, so here is the code that sets DPI when saving a PNG. There is a lot to do to get the proper writers and such...

 private BufferedImage gridImage;  ...   private void saveGridImage(File output) throws IOException {     output.delete();      final String formatName = "png";      for (Iterator<ImageWriter> iw = ImageIO.getImageWritersByFormatName(formatName); iw.hasNext();) {        ImageWriter writer = iw.next();        ImageWriteParam writeParam = writer.getDefaultWriteParam();        ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);        IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, writeParam);        if (metadata.isReadOnly() || !metadata.isStandardMetadataFormatSupported()) {           continue;        }         setDPI(metadata);         final ImageOutputStream stream = ImageIO.createImageOutputStream(output);        try {           writer.setOutput(stream);           writer.write(metadata, new IIOImage(gridImage, null, metadata), writeParam);        } finally {           stream.close();        }        break;     }  }   private void setDPI(IIOMetadata metadata) throws IIOInvalidTreeException {      // for PMG, it's dots per millimeter     double dotsPerMilli = 1.0 * DPI / 10 / INCH_2_CM;      IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize");     horiz.setAttribute("value", Double.toString(dotsPerMilli));      IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize");     vert.setAttribute("value", Double.toString(dotsPerMilli));      IIOMetadataNode dim = new IIOMetadataNode("Dimension");     dim.appendChild(horiz);     dim.appendChild(vert);      IIOMetadataNode root = new IIOMetadataNode("javax_imageio_1.0");     root.appendChild(dim);      metadata.mergeTree("javax_imageio_1.0", root);  } 
like image 57
Peter Kofler Avatar answered Sep 24 '22 03:09

Peter Kofler


Seting up TIFF DPI

If you want to set dpi for TIFF, try to do that by next steps:

private static IIOMetadata createMetadata(ImageWriter writer, ImageWriteParam writerParams, int resolution) throws                                                                                                             IIOInvalidTreeException {     // Get default metadata from writer     ImageTypeSpecifier type = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY);     IIOMetadata meta = writer.getDefaultImageMetadata(type, writerParams);      // Convert default metadata to TIFF metadata     TIFFDirectory dir = TIFFDirectory.createFromMetadata(meta);      // Get {X,Y} resolution tags     BaselineTIFFTagSet base = BaselineTIFFTagSet.getInstance();     TIFFTag tagXRes = base.getTag(BaselineTIFFTagSet.TAG_X_RESOLUTION);     TIFFTag tagYRes = base.getTag(BaselineTIFFTagSet.TAG_Y_RESOLUTION);      // Create {X,Y} resolution fields     TIFFField fieldXRes = new TIFFField(tagXRes, TIFFTag.TIFF_RATIONAL, 1, new long[][] { { resolution, 1 } });     TIFFField fieldYRes = new TIFFField(tagYRes, TIFFTag.TIFF_RATIONAL, 1, new long[][] { { resolution, 1 } });      // Add {X,Y} resolution fields to TIFFDirectory     dir.addTIFFField(fieldXRes);     dir.addTIFFField(fieldYRes);      // Add unit field to TIFFDirectory (change to RESOLUTION_UNIT_CENTIMETER if necessary)     dir.addTIFFField(new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_RESOLUTION_UNIT), BaselineTIFFTagSet.RESOLUTION_UNIT_INCH));      // Return TIFF metadata so it can be picked up by the IIOImage     return dir.getAsMetadata(); } 

Also, similar way you can setting up any TIFF tag.

Read more at the source

like image 38
Sergey Bubenshchikov Avatar answered Sep 22 '22 03:09

Sergey Bubenshchikov


i am using this code for tiff file in my project and it works well..

import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.media.jai.NullOpImage;
import javax.media.jai.OpImage;
import javax.media.jai.PlanarImage;
import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageDecoder;
import com.sun.media.jai.codec.ImageEncoder;
import com.sun.media.jai.codec.SeekableStream;
import com.sun.media.jai.codec.TIFFEncodeParam;
import com.sun.media.jai.codec.TIFFField;
class SetDDPI
 {
static void tiff_Maker(List<BufferedImage> output, String result) throws   IOException
{
    TIFFEncodeParam params = new TIFFEncodeParam();
    OutputStream out = new FileOutputStream(result);
    List<BufferedImage> imageList = new ArrayList<BufferedImage>();
    for (int i = 1; i < output.size(); i++)
    {
        imageList.add(output.get(i));
    }
    params.setWriteTiled(true);
    params.setCompression(TIFFEncodeParam.COMPRESSION_GROUP4);
    params.setExtraImages(imageList.iterator());
    TIFFField[] extras = new TIFFField[2];
    extras[0] = new TIFFField(282, TIFFField.TIFF_RATIONAL, 1, (Object) new long[][] { { (long) 300, (long) 1 },
            { (long) 0, (long) 0 } });
    extras[1] = new TIFFField(283, TIFFField.TIFF_RATIONAL, 1, (Object) new long[][] { { (long) 300, (long) 1 },
            { (long) 0, (long) 0 } });
    params.setExtraFields(extras);
    ImageEncoder encoder = ImageCodec.createImageEncoder("tiff", out, params);
    encoder.encode(output.get(0));
    out.close();
}
static List<BufferedImage> tiff_Extractor(File tiff) throws IOException
{
    List<BufferedImage> images = new ArrayList<BufferedImage>();
    SeekableStream ss = new FileSeekableStream(tiff);
    ImageDecoder decoder = ImageCodec.createImageDecoder("tiff", ss, null);
    int numPages = decoder.getNumPages();
    for (int j = 0; j < numPages; j++)
    {
        PlanarImage op = new NullOpImage(decoder.decodeAsRenderedImage(j), null, null, OpImage.OP_IO_BOUND);
        images.add(op.getAsBufferedImage());

    }
    return images;
}
}

this is to set 300 DPI of Tiff image. you can change it according to your need.

extras[0] = new TIFFField(282, TIFFField.TIFF_RATIONAL, 1, (Object) new     
long[][] { { (long) 300, (long) 1 },{ (long) 0, (long) 0 } });

extras[1] = new TIFFField(283, TIFFField.TIFF_RATIONAL, 1, (Object) new     
long[][] { { (long) 300, (long) 1 },{ (long) 0, (long) 0 } });
like image 31
rj27 Avatar answered Sep 25 '22 03:09

rj27