项目需求:
使用 Java ImageIO 搭配 TwelveMonkeys ImageIO 库,要把多个 BufferedImage(由一个多页 TIFF 图片而来,因为要对每一页做一些处理)转成 base64。
尝试:
用 ImageWriter.writeToSequence 方法先把 BufferedImage 输出到 ByteArrayOutputStream
再用 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 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 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;
}
}