Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manipulate an image without deleting its EXIF data

Using imageIO, I usually have the problem of transforming an image file, and after overwriting it, it loses all of its EXIF data. Is there any way to preserve it without first extracting it, caching it, and then resetting it?

like image 658
Preslav Rachev Avatar asked Jan 23 '12 13:01

Preslav Rachev


People also ask

Can EXIF data be manipulated?

Yes EXIF data can be altered. You can change the fields in post with certain programs. You can also fake the date simply by changing the date and time of the camera before taking the picture, there's nothing that says a camera has to have the exact date and time.

How do you preserve EXIF data?

EXIF data is only preserved when syncing the photo back to your computer directly. Emailing the photo will not save EXIF data. Additionally, please ensure that the Location Services is turned on for Snapseed in the iOS Settings.


1 Answers

ImageIO do have this functionality itself, but instead of ImageIO.read you will need to use ImageReader:

ImageReader reader = ImageIO.getImageReadersBySuffix("jpg").next();

(you may want to also check if such reader exists). Then you need to set the input:

reader.setInput(ImageIO.createImageInputStream(your_imput_stream));

Now you may save your metadata:

IIOMetadata metadata = reader.getImageMetadata(0); 
                            // As far as I understand you should provide 
                            // index as tiff images could have multiple pages

And then read the image:

BufferedImage bi = reader.read(0);

When you want to save new image, you should use ImageWriter:

// I'm writing to byte array in memory, but you may use any other stream
ByteArrayOutputStream os = new ByteArrayOutputStream(255);
ImageOutputStream ios = ImageIO.createImageOutputStream(os);

Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpeg");
ImageWriter writer = iter.next();
writer.setOutput(ios);

//You may want also to alter jpeg quality
ImageWriteParam iwParam = writer.getDefaultWriteParam();
iwParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwParam.setCompressionQuality(.95f);

//Note: we're using metadata we've already saved.
writer.write(null, new IIOImage(bi, null, metadata), iwParam);
writer.dispose();

//ImageIO.write(bi, "jpg", ios); <- This was initially in the code but actually it was only adding image again at the end of the file.

As it's old topic, I guess this answer is a bit too late, but may help others as this topic is still googlable.

like image 109
Rigeborod Avatar answered Sep 20 '22 08:09

Rigeborod