-
-
Notifications
You must be signed in to change notification settings - Fork 319
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
Allow tiff writing to use an explicit photometric interpretation option #815
Comments
Hi Ben, Thanks for reporting! I think I understand the issue. Unfortunately, it's not as easy as just "allow ... explicit photometric interpretation", as that photometric may not be compatible with the actual image data. We could make an illegal combination of photometric and actual image data throw an exception, but that would make the library harder to use in some cases. Or we could automatically convert, but that's quite hard to implement robustly, and may make some writes surprisingly slow due to the implicit conversion. So I tried to keep things simple by just going with whatever the input was. For the logic you mention, I use the following, to avoid the fixed color model, but instead use the color model supplied in the image: // Can't use createFromRenderedImage in this case, as it does not consider palette for TYPE_BYTE_BINARY...
// TODO: Consider writing workaround in ImageTypeSpecifiers
ImageTypeSpecifier spec = new ImageTypeSpecifier(renderedImage); So I think you should be able to get new IndexColorModel(1, 2, new int[] {0xFFFFFFFF, 0xFF000000}, 0, false, -1, DataBuffer.TYPE_BYTE); I'll create a test case to verify this (I thought I had that already), but feel free to try it out and report back in the mean time! 😀 |
Thank you, @haraldk! I had seen your similar comment in #533 (comment). Unfortunately it didn't work for me because the color model was inferred from |
Excellent! There's actually two constructors you can use:
But yes, it unfortunate that the many factory methods don't just do the right thing from the start. I've made my own PS: Studying your sample code some more, I don't think you actually need the lines: var type = ImageTypeSpecifier.createFromRenderedImage(image); // ..or new ImageTypeSpecifier(image)
var tiffMetadata = new TIFFImageMetadata(List.of(
new TIFFEntry(TAG_X_RESOLUTION, new Rational(settings.xResolution())),
new TIFFEntry(TAG_Y_RESOLUTION, new Rational(settings.yResolution()))));
var metadata = writer.convertImageMetadata(tiffMetadata, type, params);
writer.writeToSequence(new IIOImage(image, /* thumbnails */ null, metadata), params); It should be enough to just do: var tiffMetadata = new TIFFImageMetadata(List.of(
new TIFFEntry(TAG_X_RESOLUTION, new Rational(settings.xResolution())),
new TIFFEntry(TAG_Y_RESOLUTION, new Rational(settings.yResolution()))));
writer.writeToSequence(new IIOImage(image, /* thumbnails */ null, tiffMetadata), params); ...as the writer will merge ("convert") the metadata and fill in/overwrite any necessary values in the |
Thanks, I’ll give that a shot. Less code for me to screw up! 🙂 |
That didn't work when using a jpeg output. I forget why, but those two lines resolves that issue. Caused by: javax.imageio.IIOException: Metadata components != number of destination bands
at java.desktop/com.sun.imageio.plugins.jpeg.JPEGImageWriter.checkSOFBands(JPEGImageWriter.java:1337)
at java.desktop/com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeOnThread(JPEGImageWriter.java:739)
at java.desktop/com.sun.imageio.plugins.jpeg.JPEGImageWriter.write(JPEGImageWriter.java:384)
at com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageWriter.write(JPEGImageWriter.java:173)
at com.twelvemonkeys.imageio.plugins.tiff.TIFFImageWriter.writePage(TIFFImageWriter.java:252)
at com.twelvemonkeys.imageio.plugins.tiff.TIFFImageWriter.writeToSequence(TIFFImageWriter.java:964) |
Interesting... I need to investigate a little, but I don't think we should pass the TIFF image metadata to the JPEG writer, when writing a JPEG compressed TIFF. That's probably an oversight... |
Thanks for reporting! |
Is your feature request related to a use case or a problem you are working on? Please describe.
The TIFF writer defaults to BLACK_IS_ZERO for monochrome images. Our previous implementation, based on icafe, used WHITE_IS_ZERO by default. While the TIFF 6.0 standard makes this choice arbitrary and the reader must support it, a partner's AS/400 does not handle this correctly. They print white-on-black images which causes problems for our mutual customers. I would like to change the default on our side, since this legacy vendor is not flexible in making modifications.
Describe the solution you'd like
I attempted to add the exif metadata like,
but this is not honored, as stated by the following code snippet:
TwelveMonkeys/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageWriter.java
Lines 796 to 798 in 399c75f
Describe alternatives you've considered
I am attempting to coerce the library to observe a color model that is inferred to WHITE_IS_ZERO by the logic below. Since the
ImageTypeSpecifier.createFromRenderedImage
infers all monochrome images to callcreateGrayscale
, this has a fixed color space and is not inferred based on the buffered image'sColorModel
. I did not see a way to coerce this to match your inference logic.TwelveMonkeys/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageWriter.java
Lines 451 to 461 in 399c75f
I will explore next using Java native support for TIFF instead of this plugin to see if it honors the exif metadata setting.
Additional context
I was able to get the customer to confirm the compatibility problem by using imagemagick,
Here is the tiff conversion logic that I am using if helpful,
The text was updated successfully, but these errors were encountered: