当前位置: 首页 > 知识库问答 >
问题:

使用Java创建多页Tiff

葛昱
2023-03-14

我感兴趣的是拍摄一个tif图像,并在其中添加一个包含Java文本的层,如果可能的话,最好使用十二只猴子图像库。

我可以从这里调整代码以将文本添加到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公司:

<dependency>
    <groupId>com.twelvemonkeys.imageio</groupId>
    <artifactId>imageio-tiff</artifactId>
    <version>3.2.1</version>
</dependency>

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

我能够为JPG运行以下代码,但JPG没有层。

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);
    }
}

非常感谢。

共有1个答案

姚子石
2023-03-14

您可以使用标准的ImageIO API编写多页图像(以支持它的格式,如TIFF)。既然Java ImageIO附带了一个捆绑的TIFF插件,从Java 9开始,下面的内容应该可以正常工作,没有额外的依赖关系。对于Java 8和更早版本,您仍然需要一个TIFF插件,如JAI或TwelveMonkeys所述。

例如,请参见TIFFImageWriterTest。testWriteSequence方法来自于TwelveMonkeys ImageIO项目的测试用例,例如如何做到这一点。

重要部分:

BufferedImage[] images = ...
OutputStream stream = ... // May also use File here, as output

// 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);

    // Compression: None, PackBits, ZLib, Deflate, LZW, JPEG and CCITT variants allowed
    // (different plugins may use a different set of compression type names)
    params.setCompressionType("Deflate");

    writer.prepareWriteSequence(null);

    for (BufferedImage image : images) {
        writer.writeToSequence(new IIOImage(image, null, null), params);
    }

    // We're done
    writer.endWriteSequence();
}

writer.dispose();
 类似资料:
  • 我正在尝试从Java结果集创建PDF报告。如果报告只有一页,我在这里就没有问题了。这个问题源于这样一个事实:这份报告可能有一到十页长。现在,我要创建一个单页文档: 所以我的问题是,如何根据需要动态创建页面。有没有一个面向对象的答案盯着我看,而我就是看不见?

  • 我读到DB2不支持限制和偏移量。我还读到您必须使用ROW_NUMBER()和子查询来获得所需的结果。如果这是SQL查询: 其中$offset是偏移量,$rowserPage是我希望在页面上显示的数据库行的数量,这可以等效为DB2查询。

  • 问题内容: 我决定使用Java重新创建Snake,但是我有些困惑。目前,我有一个正方形,用户可以使用箭头键在屏幕上移动。当您按一次LEFT时,方型会开始使用计时器向左移动。当您按任何其他已设置的键(向右,向上,向下)时,它会改变方向。我的目标是使用ArrayList容纳组成蛇的正方形。目前,我已经创建了一个ArrayList,其中仅包含一个Snake对象,如果我将第二个Snake对象添加到列表中并

  • 我需要创建一个带有分页的HTML表。数据来自两个不同的来源(可能是来自两个不同数据库的两个表,比如一个Oracle,另一个是MySQL),您不能使用JOIN select语句。为了使它更复杂,我需要以升序显示按时间戳排序的数据(其中一个属性是timestamp)。 例如,源A有45条记录,源B有55条记录。因此,该表将显示总共100条记录,但一次只显示15条记录。因此必须有7页(6页15条记录,1

  • 我想在spring mvc中使用注释方法创建一个示例项目,用户可以通过单击按钮导航到一个页面到另一个页面。我为spring创建了一个新的mvc项目示例 我期待你的帮助先谢谢你 登录。JAVA 登录控制器。JAVA 登录。jsp calc.jsp 所容纳之物jsp 当点击calc页面上的“鼠标”按钮时,会出现以下错误 加上 单击登录页面中的登录按钮时发生以下错误 例外

  • 我需要将图像(主要是JPEG)直接转换为PDF文档的PDF页面。 可能是图像的大小不同。 每个PDF页面应该具有与图像相同的精确尺寸。 因此每个页面只包含全分辨率的图像。 如何实现这一点,一个页面被设置为图像/内容的尺寸? 因为我看到PDF文件有不同的页面大小和方向,但如何用PDFbox做到这一点?