Java 如何将多个 BufferedImage 转成一个多页 TIFF 格式的 base64?

项目需求:
使用 Java ImageIO 搭配 TwelveMonkeys ImageIO 库,要把多个 BufferedImage(由一个多页 TIFF 图片而来,因为要对每一页做一些处理)转成 base64。

尝试:

  1. ImageWriter.writeToSequence 方法先把 BufferedImage 输出到 ByteArrayOutputStream
  2. 再用 DatatypeConverter 把从 ByteArrayOutputStream 取得的 byte[] 转成 base64

结果:
但是转出来的 base64 String 图片仅第一页可正常显示,之后二三等页皆漆黑一片无法显示。

要怎么修正才能产生每一页皆正常的 base64 图形呢?

import javax.imageio.*;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
import javax.xml.bind.DatatypeConverter;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;

class MultipageTIFFToBase64 {
  public static void main(String[] args) throws IOException {
    File multipageTIFF = new File("multipage.tiff");
    BufferedImage[] imagePages = readMultipageTIFF(multipageTIFF);
    String base64 = convertToBase64String(imagePages);

    System.out.println(base64);
  }

  public static String convertToBase64String(BufferedImage[] imagePages) throws IOException {
    String base64String;
    byte[] imageBytes;

    ImageWriter imageWriter = null;
    try (
      ByteArrayOutputStream bao = new ByteArrayOutputStream();
      ImageOutputStream ios = ImageIO.createImageOutputStream(bao)
    ) {
      Iterator<ImageWriter> imageWriterIterator = ImageIO.getImageWritersByFormatName("TIFF");
      imageWriter = imageWriterIterator.next();
      imageWriter.setOutput(ios);

      ImageWriteParam params = imageWriter.getDefaultWriteParam();
      params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
      params.setCompressionType("JPEG");
      params.setCompressionQuality(1f);

      imageWriter.prepareWriteSequence(null);
      for (int i = 0; i < imagePages.length; i++) {
        BufferedImage imagePage = imagePages[i];
        IIOImage iioImage = new IIOImage(imagePage, null, null);
        imageWriter.writeToSequence(iioImage, params);
      }
      imageWriter.endWriteSequence();

      imageBytes = bao.toByteArray();
    } catch (IOException e) {
      if (imageWriter != null) {
        imageWriter.abort();
      }

      throw e;
    } finally {
      if (imageWriter != null) {
        imageWriter.dispose();
      }
    }

    base64String = DatatypeConverter.printBase64Binary(imageBytes);

    return base64String;
  }

  public static BufferedImage[] readMultipageTIFF(File tiffFile) throws IOException {
    BufferedImage[] imagePages;

    ImageReader imageReader = null;
    try (
      FileInputStream fis = new FileInputStream(tiffFile);
      ImageInputStream iis = ImageIO.createImageInputStream(fis)
    ) {
      Iterator<ImageReader> imageReaderIterator = ImageIO.getImageReaders(iis);
      imageReader = imageReaderIterator.next();
      imageReader.setInput(iis);

      int numImagePages = imageReader.getNumImages(true);
      imagePages = new BufferedImage[numImagePages];
      for (int i = 0; i < numImagePages; i++) {
        BufferedImage imagePage = imageReader.read(i);
        imagePages[i] = imagePage;
      }
    } catch (IOException e) {
      if (imageReader != null) {
        imageReader.abort();
      }

      throw e;
    } finally {
      if (imageReader != null) {
        imageReader.dispose();
      }
    }

    return imagePages;
  }
}
阅读 4.5k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题