2008-11-26 26 views
23

Mam aplikację, do której chcę wyeksportować obrazy o wysokiej rozdzielczości (lub raczej o dużej gęstości?) Do drukowania - na przykład chcę, aby obrazy były drukowane z prędkością 250 punktów na cal (DPI), zamiast wartości domyślnej, co Rozumiem, że to 72 DPI.Jak ustawić informacje o DPI w obrazie?

Używam BufferedImage z obiektem Graphics2D do narysowania obrazu, a następnie ImageIO.write(), aby zapisać obraz.

Masz pomysł, jak ustawić DPI?

Odpowiedz

24

Odpowiedź Kurta pokazała drogę, ale zabrało mi to trochę czasu, więc oto kod, który ustawia DPI podczas zapisywania PNG. Jest wiele do zrobienia, aby uzyskać odpowiednie pisarzy i takie ...

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

dlaczego jest nazywany obrazem siatki? coś innego niż zwykły obraz? – Zeveso

+0

@Zeveso Właśnie zdarzyło mi się skopiować/wkleić ten kod z działającej aplikacji, która zapisała obraz siatki, stąd nazwa BufferedImage i metoda. Kod działa dla każdego obrazu BufferedImage. –

+1

@PeterKofler Używam powyższego kodu bez żadnych zmian. powyższy kod tworzy plik PNG zgodnie z oczekiwaniami (przy użyciu podanych dpi), ale kiedy używam powyższego kodu do pliku JPEG, to się nie powiedzie, czy muszę ustawić dowolny parametr dla JPEG, czy ten kod działa tylko dla PNG? – Mihir

0

Używam tego kodu do pliku tiff w moim projekcie i to działa dobrze ..

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

tego celu jest ustaw 300 DPI obrazu Tiff. możesz to zmienić w zależności od potrzeb.

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

Jeśli chcesz ustawić dpi dla TIFF, spróbuj zrobić to przez następnych etapach:

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

Również podobny sposób można zakładających dowolny tag TIFF .

Czytaj więcej na stronie source

Powiązane problemy