Comments (7)
and just like that I got it working π
IIOMetadata metadata = new TIFFImageMetadata(List.of(
new TIFFEntry(TIFF.TAG_X_RESOLUTION, 200),
new TIFFEntry(TIFF.TAG_Y_RESOLUTION, 200)));
var type = ImageTypeSpecifier.createFromBufferedImageType(TYPE_INT_RGB);
metadata = writer.convertImageMetadata(metadata, type, null);
from twelvemonkeys.
okay, so I lied π
I'm not sure exactly why, but I have it now working with both writers. I believe somewhere I must have passed in the wrong property, e.g. the write params, and caused some corrupted output. I'll stop spamming you, hopefully.
from twelvemonkeys.
No worries!
I've been away on summer holiday, so not been able to comment. But glad you figured it out! π
from twelvemonkeys.
haha, given it was very late I immediately went to bed and I completely missed that the output came out purple π
I tried some of the other color spaces without any luck. Hopefully I have some time today to dig into it, but any hints would be appreciated.
Java
import static java.awt.AlphaComposite.Src;
import static java.awt.RenderingHints.KEY_DITHERING;
import static java.awt.RenderingHints.VALUE_DITHER_DISABLE;
import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
import static java.nio.ByteOrder.BIG_ENDIAN;
import static javax.imageio.ImageWriteParam.MODE_EXPLICIT;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.ByteOrder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.IntStream;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriter;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.twelvemonkeys.image.MonochromeColorModel;
import com.twelvemonkeys.imageio.metadata.tiff.TIFF;
import com.twelvemonkeys.imageio.metadata.tiff.TIFFEntry;
import com.twelvemonkeys.imageio.plugins.tiff.TIFFImageMetadata;
import net.autobuilder.AutoBuilder;
public class TiffTest {
public static void main(String[] args) {
// create(TiffSettings.group4()
// .addToImages(Path.of("/Users/ben/Downloads/original.jpg"))
// .destination(Path.of("/Users/ben/Downloads/java_g4.tif"))
// .build());
// create(TiffSettings.lzwColor()
// .addToImages(Path.of("/Users/ben/Downloads/original.jpg"))
// .destination(Path.of("/Users/ben/Downloads/java_lzw.tif"))
// .build());
create(TiffSettings.jpegColor()
.addToImages(Path.of("/Users/ben/Downloads/original.jpg"))
.destination(Path.of("/Users/ben/Downloads/java_jpg.tif"))
.build());
System.out.println("done");
}
public static void create(TiffSettings settings) {
var images = new BufferedImage[settings.images().size()];
ImageWriter writer = ImageIO.getImageWritersByFormatName("TIFF").next();
try (var fileOutput = Files.newOutputStream(settings.destination());
var output = ImageIO.createImageOutputStream(fileOutput)) {
for (int i = 0; i < settings.images().size(); i++) {
images[i] = ImageIO.read(settings.images().get(i).toFile());
if (settings.monochrome()) {
images[i] = convertMonochrome(images[i]);
}
}
output.setByteOrder(BIG_ENDIAN);
writer.setOutput(output);
var params = writer.getDefaultWriteParam();
params.setCompressionMode(MODE_EXPLICIT);
params.setCompressionType(settings.compression());
var tiffMetadata = new TIFFImageMetadata(List.of(
new TIFFEntry(TIFF.TAG_X_RESOLUTION, 200),
new TIFFEntry(TIFF.TAG_Y_RESOLUTION, 200)));
var type = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
var metadata = writer.convertImageMetadata(tiffMetadata, type, /* write param */ null);
writer.prepareWriteSequence(/* stream metadata */ null);
for (var image : images) {
writer.writeToSequence(new IIOImage(image, /* thumbnails */ null, metadata), params);
}
writer.endWriteSequence();
} catch (IOException e) {
throw new UncheckedIOException(e);
} finally {
writer.dispose();
}
}
private static BufferedImage convertMonochrome(BufferedImage source) {
if (IntStream.of(source.getSampleModel().getSampleSize()).sum() == 1) {
return source;
}
var destination = new BufferedImage(source.getWidth(), source.getHeight(),
TYPE_BYTE_BINARY, MonochromeColorModel.getInstance());
var graphics = destination.createGraphics();
try {
graphics.setComposite(Src);
graphics.setRenderingHint(KEY_DITHERING, VALUE_DITHER_DISABLE);
graphics.drawImage(source, 0, 0, null);
return destination;
} finally {
graphics.dispose();
}
}
@AutoValue @AutoBuilder
public static abstract class TiffSettings {
public abstract ImmutableList<Path> images();
public abstract ByteOrder byteOrder();
public abstract String compression();
public abstract boolean monochrome();
public abstract Path destination();
public abstract int xResolution();
public abstract int yResolution();
public static TiffTest_TiffSettings_Builder group4() {
return builder()
.compression("CCITT T.6")
.monochrome(true)
.xResolution(200)
.yResolution(200);
}
public static TiffTest_TiffSettings_Builder jpegColor() {
return builder()
.compression("JPEG")
.xResolution(200)
.yResolution(200);
}
public static TiffTest_TiffSettings_Builder lzwColor() {
return builder()
.compression("LZW")
.xResolution(72)
.yResolution(72);
}
public static TiffTest_TiffSettings_Builder builder() {
return TiffTest_TiffSettings_Builder.builder()
.byteOrder(BIG_ENDIAN);
}
}
}
from twelvemonkeys.
Hi Ben,
I donβt have a computer nearby at the moment, sorry. I type this on my phone.
But keep in mind that image metadata is per image/IFD in the TIFF. So you should probably create the metadata object inside the loop where you write images. Also, the type var should be created from the actual image you write (use ITS.createFromRenderedImag(image)).
from twelvemonkeys.
thanks! I appreciate the response and please don't bother yourself when not available or it is a hassle.
I actually did that in a refactoring between meetings. I think the issue is something to do with the alpha channel or in some "transparency" mode, where I read index 0 is r=255,g=0,b=255 which is pink. If I convert the original jpg with ImageMagick, it turns from sRGB 3-channel to Grayscale 2-channel and the tiff (jpeg compressed) is perfect. This could be from downloading a sample from the CDN which would do some mozjpeg-style optimization to the jpeg. That might not happen on the source image in the pipeline and that I should download a better sample.
from twelvemonkeys.
oh oh oh! This is actually a bug in TwelveMonkeys.
If I select the com.sun.imageio.plugins.tiff.TIFFImageWriter
then the jpeg-encoded tiff is rendered correctly. It has a white background. The com.twelvemonkeys.imageio.plugins.tiff.TIFFImageWriter
implementation has a pink background.
The DPI metadata did not get applied where it defaults to 78. So I would need to handle that xml nonsense, which looked very messy when I was searching yesterday.
Unfortunately it does seem that I found a bug here. Attached is a zip containing my test sample and outputs.
from twelvemonkeys.
Related Issues (20)
- Troubleshooting with ImageIO plugin registry issue (NoClassDefFoundErrors) without web.xml file HOT 1
- YCCK JPEG from a PDF with wrong colors HOT 5
- TIFF: Support SAMPLEFORMAT_COMPLEXINT (5) HOT 3
- WebP plugin stops working when other plugins are enabled too HOT 2
- PSD: Get layer kind (type) to metadata HOT 1
- Twelvemonkeys Servlet should support Jakarta HOT 6
- JPEGImageReader read invalid image without throwing exception HOT 4
- PSD: When make PNG from PSD using TwelveMonkeys, it's different from Photoshop. HOT 4
- Change Maven GPG plugin to use Bouncy Castle signer
- Unsupported BitsPerSample for SampleFormat 3/Floating Point (expected 16/32): 64 HOT 4
- PSD: BufferOverflowException if encoder adds garbage to the end of rows
- Dynamic images in WebP format, and even ordinary GIF images, cannot read delays after using this plugin. HOT 2
- Warning system custom messages HOT 3
- Unable to read dynamic webp using javax.imageio.ImageIO#read(java.io.InputStream) on aws lambda HOT 1
- TIFF: ArrayIndexOutOfBoundsException in HorizontalDeDifferencingFloatingPointStream.decodeDeltaBytes HOT 3
- JPEG 2000 format support HOT 1
- TIFF: Decoding chunky gray + extra samples is broken HOT 1
- heic-image HOT 1
- WebP: "Coordinate out of bounds!" exception thrown when reading certain files HOT 2
- Please make BufferedChannelImageInputStream public HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from twelvemonkeys.