2008-11-26 6 views
23

J'ai une application que je veux exporter des images à haute résolution (ou plutôt, haute densité de pixels?) Pour l'impression - par exemple, je veux des images qui impriment à 250 points par pouce (DPI), Je comprends être 72 DPI.Comment définir les informations DPI dans une image?

J'utilise un objet BufferedImage avec un objet Graphics2D pour dessiner l'image, puis ImageIO.write() pour enregistrer l'image.

Une idée de comment je peux définir le DPI?

Répondre

24

La réponse de Kurt a montré le chemin, il m'a encore fallu un certain temps pour l'exécuter, voici donc le code qui définit DPI lors de l'enregistrement d'un PNG. Il y a beaucoup à faire pour obtenir les écrivains et tels ... appropriés

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

pourquoi est-ce qu'on appelle l'image de la grille? quelque chose de différent d'une image régulière? – Zeveso

+0

@ Zeveso Je viens de copier/coller ce code à partir d'une application de travail qui sauvegardait une image d'une grille, donc le nom de la BufferedImage et la méthode. Le code fonctionne pour chaque BufferedImage. –

+1

@PeterKofler J'utilise le code ci-dessus sans aucun changement. le code ci-dessus crée le fichier PNG comme prévu (en utilisant dpi donné) mais quand j'utilise le code ci-dessus pour le fichier JPEG, il échoue, dois-je définir un paramètre pour JPEG ou ce code ne fonctionne que pour PNG? – Mihir

0

je suis en utilisant ce code pour le fichier tiff dans mon projet et il fonctionne bien ..

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

est de régler 300 DPI de l'image Tiff. vous pouvez le changer en fonction de vos besoins.

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

Seting up DPI TIFF

Si vous souhaitez définir ppp pour TIFF, essayez de le faire par étapes suivantes:

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

En outre, la même façon, vous pouvez mise en place une balise TIFF .

En savoir plus au source

Questions connexes