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?
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.
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); }
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
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 } });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With