用Java创建多页Tiff

我有兴趣拍摄一个tif图像,并在其中添加一个包含Java文本的图层,如果可能的话,最好使用Twelve Monkeys图像库。

我可以从这里调整代码,将文本添加到tif或创建一个只有文本的相同大小的新tif,但不要将它们保存为多页tif。 例如:

import javax.imageio.*; import javax.imageio.stream.ImageOutputStream; import java.awt.*; import java.awt.image.*; import java.io.*; public class ImageUtil { public static void main(String[] args) throws Exception { BufferedImage src = ImageIO.read(new File("/path/to/main.tif")); BufferedImage text = createTextLayer(src); BufferedImage[] images = new BufferedImage[]{src, text}; createMultiPage(images); } private static BufferedImage createTextLayer(BufferedImage src) { int w = src.getWidth(); int h = src.getHeight(); BufferedImage img = new BufferedImage( w, h, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = img.createGraphics(); g2d.drawImage(img, 0, 0, null); g2d.setPaint(Color.red); g2d.setFont(new Font("Serif", Font.BOLD, 200)); String s = "Hello, world!"; FontMetrics fm = g2d.getFontMetrics(); int x = img.getWidth() - fm.stringWidth(s) - 5; int y = fm.getHeight() * 5; g2d.drawString(s, x, y); g2d.dispose(); return img; } private static void createMultiPage(BufferedImage[] images) throws IOException { File tempFile = new File("/new/file/path.tif"); //I also tried passing in stream var below to the try, but also receive java.lang.UnsupportedOperationException: Unsupported write variant! //OutputStream stream = new FileOutputStream(tempFile); // Obtain a TIFF writer ImageWriter writer = ImageIO.getImageWritersByFormatName("TIFF").next(); try (ImageOutputStream output = ImageIO.createImageOutputStream(tempFile)) { writer.setOutput(output); ImageWriteParam params = writer.getDefaultWriteParam(); params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); params.setCompressionType("None"); //error here: java.lang.UnsupportedOperationException: Unsupported write variant! writer.prepareWriteSequence(null); for (int i = 0; i < images.length; i++){ writer.writeToSequence(new IIOImage(images[i], null, null), params); } // We're done writer.endWriteSequence(); } } } 

Maven的:

  com.twelvemonkeys.imageio imageio-tiff 3.2.1  

如何从图像和生成的文本图像创建多页tif?

我能够获得以下代码来运行jpgs,但jpgs没有图层。

 public static void testWriteSequence() throws IOException { BufferedImage[] images = new BufferedImage[] { new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB), new BufferedImage(110, 100, BufferedImage.TYPE_INT_RGB), new BufferedImage(120, 100, BufferedImage.TYPE_INT_RGB), new BufferedImage(130, 100, BufferedImage.TYPE_INT_RGB) }; Color[] colors = {Color.BLUE, Color.GREEN, Color.RED, Color.ORANGE}; for (int i = 0; i < images.length; i++) { BufferedImage image = images[i]; Graphics2D g2d = image.createGraphics(); try { g2d.setColor(colors[i]); g2d.fillRect(0, 0, 100, 100); } finally { g2d.dispose(); } } //ImageWriter writer = createImageWriter(); ImageWriter writer = ImageIO.getImageWritersByFormatName("JPEG").next(); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); try (ImageOutputStream output = ImageIO.createImageOutputStream(buffer)) { writer.setOutput(output); ImageWriteParam params = writer.getDefaultWriteParam(); params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); writer.prepareWriteSequence(null); params.setCompressionType("JPEG"); writer.writeToSequence(new IIOImage(images[0], null, null), params); params.setCompressionType("JPEG"); writer.writeToSequence(new IIOImage(images[1], null, null), params); params.setCompressionType("JPEG"); writer.writeToSequence(new IIOImage(images[2], null, null), params); params.setCompressionType("JPEG"); writer.writeToSequence(new IIOImage(images[3], null, null), params); writer.endWriteSequence(); File tempFile = new File("/path/to/new/file.jpg"); OutputStream out = new FileOutputStream(tempFile); buffer.writeTo(out); } } 

谢谢。

您可以使用标准ImageIO API编写多页图像(支持它的格式,如TIFF)。

例如,参见TwelveMonkeys ImageIO项目的测试用例中的TIFFImageWriterTest.testWriteSequence方法,以获取如何执行此操作的示例。

重要的部分:

 BufferedImage[] images = ... OutputStream stream = ... // Obtain a TIFF writer ImageWriter writer = ImageIO.getImageWritersByFormatName("TIFF").next(); try (ImageOutputStream output = ImageIO.createImageOutputStream(stream)) { writer.setOutput(output); ImageWriteParam params = writer.getDefaultWriteParam(); params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); writer.prepareWriteSequence(null); // This is from the test case, you probably want to replace this with a for loop... // ...and use a single compression type for all the images. params.setCompressionType("JPEG"); writer.writeToSequence(new IIOImage(images[0], null, null), params); params.setCompressionType("None"); writer.writeToSequence(new IIOImage(images[1], null, null), params); params.setCompressionType("None"); writer.writeToSequence(new IIOImage(images[2], null, null), params); params.setCompressionType("PackBits"); writer.writeToSequence(new IIOImage(images[3], null, null), params); // We're done writer.endWriteSequence(); }