Write dpi metadata to a jpeg image in Java

I am trying to programatically set the dpi metadata of an jpeg image in Java. The source of the image is a scanner, so I get the horizontal/vertical resolution from TWAIN, along with the image raw data. I'd like to save this info for better print results.

Here's the code I have so far. It saves the raw image (byteArray) to a JPEG file, but it ignores the X/Ydensity information I specify via IIOMetadata. Any advice what I'm doing wrong?

Any other solution (third-party library, etc) would be welcome too.

import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream    

import org.w3c.dom.Element;    
import com.sun.imageio.plugins.jpeg.JPEGImageWriter;

public boolean saveJpeg(int[] byteArray, int width, int height, int dpi, String file)
{
    BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

    WritableRaster wr = bufferedImage.getRaster();
    wr.setPixels(0, 0, width, height, byteArray);

    try
    {           
        // Image writer 
        JPEGImageWriter imageWriter = (JPEGImageWriter) ImageIO.getImageWritersBySuffix("jpeg").next();
        ImageOutputStream ios = ImageIO.createImageOutputStream(new File(file));
        imageWriter.setOutput(ios);

        // Compression
        JPEGImageWriteParam jpegParams = (JPEGImageWriteParam) imageWriter.getDefaultWriteParam();
        jpegParams.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
        jpegParams.setCompressionQuality(0.85f);

        // Metadata (dpi)
        IIOMetadata data = imageWriter.getDefaultImageMetadata(new ImageTypeSpecifier(bufferedImage), jpegParams);
        Element tree = (Element)data.getAsTree("javax_imageio_jpeg_image_1.0");
        Element jfif = (Element)tree.getElementsByTagName("app0JFIF").item(0);
        jfif.setAttribute("Xdensity", Integer.toString(dpi));
        jfif.setAttribute("Ydensity", Integer.toString(dpi));
        jfif.setAttribute("resUnits", "1"); // density is dots per inch         

        // Write and clean up
        imageWriter.write(data, new IIOImage(bufferedImage, null, null), jpegParams);
        ios.close();
        imageWriter.dispose();
    }
    catch (Exception e)
    {
       return false;
    }

    return true;
}

Thanks!


Asked by: Melissa873 | Posted: 21-01-2022






Answer 1

Some issues that were not considered here:

  1. The tree is not directly mapped to the IOMetaData. To apply data from tree, add following call after setting the densities and raster parameters:

    data.setFromTree("javax_imageio_jpeg_image_1.0", tree);
    
  2. don't use the meta data as first parameter in the write call. See JPEGImageWriter#write(IIOMetaData, IIOImage, ImageWriteParam). If streamMetaData is not NULL, a warning (WARNING_STREAM_METADATA_IGNORED) will be generated.

  3. set the meta data as IOMetadata of the IOImage. These meta data are used by JPEGImageWriter. The correct write call then is

    imageWriter.write(null, new IIOImage(F_scaledImg, null, data), jpegParams);
    

Answered by: Dainton647 | Posted: 22-02-2022



Answer 2

I would seem this could be a bug.

I found this post from a few google searches

Apparently there are alot more that point to a bug as well.

The post above talks about using JMagick as a third party work around.

Answered by: Kimberly477 | Posted: 22-02-2022



Similar questions

java - How can I write metadata into a .JPG?

I'm using this code to get these three diferent metadata attributes ('Object Name', 'ImageDescription' and 'Keywords') using the apache commons.imaging (snapshot). However, I have no clue about how to write into this attributes. Does anybody know the proper way? Thanks in advance... IImageMetadata metadata = null; String name; try { metadata = Imaging.getMetadata(new File(filename)); } catch (ImageReadE...


java - PNG metadata read and write

I am using a piece of code posted on stackover flow to write custom metadata to PNG image and read it. The write function seems to work fine but when i try to read data that i had written it throws NullPointerException. Can someone tell me what is wrong? Here is code for writing metadata try{ ...


xml - Using the Rome Java API to access metadata fields

I've been using the Rome API to parse data from an XML feed pretty successfully so for, but have run in to a bit of a snag. Given the following snippet of XML: <entry> <id>uniqueId</id> <updated>2008-11-05T01:32:35Z</updated> <mm:status xmlns:mm="http://contentprovider.com&...


how to extract metadata from html files using java

hi ive been doing a project in which metadata for various filetypes(html, xml etc.,) are needed. are there any existing api's to do the above. ideas and suggestions regardin the above are welcome. thanks in advance.


How to manage and edit metadata of an audio file in Java

Greetings!! I've been searching a lot about how to read the metadata of .aac file on Java, but still hasn't succeeded in finding somethong useful. I'm new in programming and I'm doing this as an assignment. The most of info I found was this: http://download-llnw.oracle.com/javase/tutorial/essential/io/file...


What is a good Java library to write GPS metadata on JPEGs (in EXIF)?

I have developed a Java application (Latipics) that geotags pictures with location information pulled from Google Latitude. I use an open source library called Sanselan to read/write GPS coordinates from/into JPEGs' metadata. It works mostly great except that Apple's Preview (stock JPEG viewer in OS X) seems to misinterpret the GPS longitude reference (


Java library for reading and writing IPTC metadata to JPEG and TIFF

Does anyone know some opensource Java library for reading and writing IPTC metadata to JPEG and TIFF? Now I'm using Apache Sanselan. Unfortunately, it can only read IPTC, not write (http://commons.apache.org/sanselan/formatsupport.html). Will ...


metadata - Java web site meta data

Closed. This question needs to be more focused. It ...


Collect metadata from file java

This question already has answers here:


java - PDFBox image metadata

For a school project i'm working on an image extractor for PDF's for this i'm using the PDFBox library. The problem i'm facing now is to get the metadata, so far I only managed to get the metadata from the PDF itself but not from the images inside the PDF. Is it possible to get the metadata from all the images inside a PDF with the PDFBox? if so could anybody refer me to an example? Any examples i've found so far ...


java - Do android photo's store compass information in metadata, if not how could it be done?

Just wondering , is there a way of storing the compass information of your phone when you take a photo, Ideally the direction the person is facing when the photo will be recorded. How would i go about implementing this in android Edit added the ExifInterface does not store data based on the compass direction when a photo is taken. How could i go about storing it with the photo?...


Adding Metadata to Java RMI

I'm trying to create a system that will, on every RMI call, 1) gather some data about the current local system state (let's say the system time) 2) serialize it and transparently add it to the data sent over the wire with the call (ie, without changing the signature of the stub method being called) 3) deserialize it on the other side and take some action (let's say logging it to a file) 4) ...






Still can't find your answer? Check out these amazing Java communities for help...



Java Reddit Community | Java Help Reddit Community | Dev.to Java Community | Java Discord | Java Programmers (Facebook) | Java developers (Facebook)



top