2008-11-26 4 views
23

Ich habe eine Anwendung, die ich Bilder mit hoher Auflösung (oder besser, hohe Pixeldichte?) Zum Drucken exportieren möchte - zum Beispiel möchte ich Bilder, die mit 250 Punkten pro Zoll (DPI) drucken, anstelle der Vorgabe, die Ich verstehe 72 DPI zu sein.Wie man DPI-Informationen in einem Bild einstellt?

Ich verwende ein BufferedImage mit einem Graphics2D-Objekt, um das Bild zu zeichnen, dann ImageIO.write(), um das Bild zu speichern.

Irgendeine Idee, wie ich die DPI einstellen kann?

Antwort

24

Kurts Antwort zeigte den Weg, trotzdem brauchte ich einige Zeit, um es laufen zu lassen, also hier ist der Code, der DPI beim Speichern eines PNG setzt. Es gibt viel zu tun, um die richtigen Autoren zu bekommen und so ...

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

Warum heißt es Rasterbild? etwas anderes als ein normales Bild? – Zeveso

+0

@Zeveso Ich habe gerade diesen Code aus einer funktionierenden Anwendung kopieren/einfügen, die ein Bild eines Rasters gespeichert hat, also den Namen der BufferedImage und die Methode. Der Code funktioniert für jedes BufferedImage. –

+1

@PeterKofler Ich verwende den obigen Code ohne irgendwelche Änderungen. Der obige Code erzeugt die PNG-Datei wie erwartet (unter Verwendung der gegebenen dpi), aber wenn ich den obigen Code für die JPEG-Datei verwende, scheitert es, muss ich irgendeinen Parameter für JPEG einstellen oder dieser Code funktioniert nur für PNG? – Mihir

0

ich verwende diesen Code für TIFF-Datei in meinem Projekt und es funktioniert gut ..

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

dies zu Stellen Sie 300 DPI des Tiff-Bildes ein. Sie können es je nach Bedarf ändern.

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 TIFF DPI

Wenn Sie TIFF einstellen dpi wollen, versuchen Sie zu tun, dass durch folgende Schritte:

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

Auch ähnlich wie Sie eine TIFF-Tag einrichten können .

mehr an den mit einer scheinbar ähnlichen URL aktualisiert source