-
-
Notifications
You must be signed in to change notification settings - Fork 316
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JPEG metadata always read-only #668
Comments
Hi Jani, It would help my understanding if you describe what the use case is here, ie. what will you use the merged metadata for. 😀 In any case, the metadata is read-only for now, as there hasn't been any need to merge. It's non-trivial, but probably not too hard to implement Without actually making the metadata mutable and implementing |
Hi and thanks for the prompt response. I totally understand why the use case for this might be a little hard to understand. So let me include some more details. Basically, our application has the following workflow:
To achieve this, our application first reads the metadata from the original image just like shown in the code snippet in my first message. Then we set the required hardcoded metadata like so:
and then we merge our custom metadata (
This approach worked fine for us for a long time. Recently we noticed ImageIO threw various errors with some images our users uploaded. Adding TwelveMonkeys to the project resolved those issues (good job, btw) but as a side effect of metadata being read-only it broke our metadata handler. Your suggestion of using a instance of |
We're also facing problems with this in jAlbum 29 since we moved from using v3.5 to v3.8.1 of your lib. In our case it's the setFromTree() call that triggers this error. We're also including the original EXIF data with generated image as a user option, but this no longer works. The reason why we call setFromTree is that we have to modify the tree a bit for some JPEG images in order to avoid errors when including the metadata for some images. I've attached one such image, it triggers an "javax.imageio.metadata.IIOInvalidTreeException: Invalid DHT node" exception if we simply include the original IIOMetadata object when writing the new scaled file. |
@davidekholm I'm not able to reproduce the problem with the JPEG you provided. It does not seem to be a problem with the DHT node, and I don't find any Exif data either... Can you double check that the file is the correct one, and that GitHub upload does not "fix" the file for us? 😉 If the file is as intended, can you please send me the code you use? I think I should be able to provide a workaround in any case. PS: I fixed an issue related to the "Invalid DHT node" issue in #559, that is in the 3.8.2 release. I verified that the image indeed has this problem under 3.8.1. Can you please upgrade to 3.8.3. |
Yes, the image might not have EXIF data, still I simply want to pass along whatever metadata it has. If you can show how to only pass along EXIF data, I appreciate if you can show an example. Anyway, here's a sample code that throws "Invalid DHT node" when writing an image, passing along metadata from the image I attached earlier. This code is close to pseudocode, but you can actually execute it within jAlbum's system console. Just drop the sample image onto jAlbum, then select it and open jAlbum's system console window, set the script language to "Groovy" and execute it:
|
Hi Harald. I've updated to v3.8.3 and the "Invalid DHT node" error is indeed gone now. Thank you. |
One possible workaround: try (ImageInputStream input = ImageIO.createImageInputStream(...)) {
ImageReader reader = ImageIO.getImageReaders(input).next();
reader.setInput(input);
IIOImage image = reader.readAll(0, null);
IIOMetadataNode root = (IIOMetadataNode) image.getMetadata().getAsTree("javax_imageio_jpeg_image_1.0");
// Manipulate metadata from input as you like...
try (ImageOutputStream output = ImageIO.createImageOutputStream(...))) {
ImageWriter writer = ImageIO.getImageWriter(reader);
writer.setOutput(output);
ImageWriteParam param = writer.getDefaultWriteParam();
// Get default metadata from writer (to obtain a mutable com.sun.imageio.plugins.jpeg.JPEGMetadata instance)
IIOMetadata metadata = writer.getDefaultImageMetadata(ImageTypeSpecifiers.createFromRenderedImage(image.getRenderedImage()), param);
// Populate with manipulated metadata from original
metadata.setFromTree("javax_imageio_jpeg_image_1.0", root);
image.setMetadata(metadata);
writer.write(null, image, param);
}
} |
Thanks Harald, so this will copy the EXIF data only? |
No, it gives you a mutable JPEG metadata, so you can copy whatever you like (what this issue is about). Copying only Exif is (probably) possible, but tedious.. To copy only the Exif segment, you need to look at the Sadly, there is a bug in the JDK metadata, that inserts multiple I'd love to fix it, but proposing PRs to OpenJDK often takes several times that of a workaround... If only there was more time. |
Greetings. I'm trying to read and modify metadata of JPEG images. Let's look at the following (heavily simplified) code:
It works fine without TwelveMonkeys, but throws an error (only) when TwelveMonkeys is installed:
It seems that the metadata is always read-only and thus mergeTree function does not work. I've looked into this with debugger and it seems that in TwelveMonkeys'
JPEGImage10Metadata.java
isReadOnly()
always returns true while in the originalcom.sun.imageio.plugins.jpeg.JPEGMetadata
it's always false. Any idea why is this and how could I get around this?The text was updated successfully, but these errors were encountered: