2008-11-26 42 views
23

我有一個應用程序可以輸出用於打印的高分辨率(或更高像素密度?)圖像 - 例如,我希望圖像以每英寸250點(DPI)打印,而不是默認值,我明白是72 DPI。如何在圖像中設置DPI信息?

我使用帶有Graphics2D對象的BufferedImage繪製圖像,然後使用ImageIO.write()來保存圖像。

任何想法如何設置DPI?

回答

24

Kurt的答案顯示了方法,但它花了我相當長的時間纔得到它的運行,所以這裏是保存PNG時設置DPI的代碼。有很多事情要做,以獲得正確的作家,如...

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); 
} 
+0

爲什麼叫柵格圖像?與普通圖像有什麼不同? – Zeveso 2012-05-18 21:25:29

0

我使用TIFF文件的代碼在我的項目,它的工作原理以及..

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; 
} 
} 

這是設置Tiff圖像的300 DPI。你可以根據你的需要改變它。

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 } }); 
0

塞汀了TIFF DPI

如果你想設置爲TIFF DPI,嘗試這樣做,通過下面的步驟:

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); 

    // Return TIFF metadata so it can be picked up by the IIOImage 
    return dir.getAsMetadata(); 
} 

此外,類似的方式,你可以設置任何TIFF標籤。

更多的source