gpt4 book ai didi

java - 在java中缩放多页TIFF图像

转载 作者:行者123 更新时间:2023-12-01 13:11:12 25 4
gpt4 key购买 nike

我想更改多页 TIFF 图像的高度,因此我使用下面的代码片段来缩放它。但它只返回 tiff 文件的第一页,我猜它会将其转换为 JPEG 图像。如何保留文件的所有页面?

public static byte[] scale(byte[] fileData, int width, int height) {
System.out.println("width:::"+width+"::::height:::"+height);
ByteArrayInputStream in = new ByteArrayInputStream(fileData);
ByteArrayOutputStream buffer=null;
BufferedImage img=null;
BufferedImage imageBuff=null;
try {
ImageInputStream imageStream = ImageIO.createImageInputStream(new ByteArrayInputStream(fileData));

java.util.Iterator<ImageReader> readers = ImageIO.getImageReaders(imageStream);
while(readers.hasNext()) {
ImageReader nextImageReader = readers.next();
nextImageReader.reset();
}

img = ImageIO.read(in);
if(height == 0) {
height = (width * img.getHeight())/ img.getWidth();
}
if(width == 0) {
width = (height * img.getWidth())/ img.getHeight();
}
Image scaledImage = img.getScaledInstance(width, height, Image.SCALE_SMOOTH);
imageBuff = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
imageBuff.getGraphics().drawImage(scaledImage, 0, 0, new Color(0,0,0), null);

buffer = new ByteArrayOutputStream();

ImageIO.write(imageBuff, "TIF", buffer);


} catch (IOException e) {
e.printStackTrace();
} finally{
if(img!=null){
img.flush();
img=null;
}
if(imageBuff!=null){
imageBuff.flush();
imageBuff=null;
}

if(buffer!=null){
try {
buffer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

if(in!=null){
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return buffer.toByteArray();
}

更新代码:

public static byte[] resize(byte[] img,int height,int width) throws IOException {
byte[] outimage = null;

ImageReader reader=null;
ImageWriter writer=null;
ByteArrayOutputStream baos=null;
ImageOutputStream ios=null;
ImageInputStream imageStream=null;
try {
baos = new ByteArrayOutputStream(30000);
ios = ImageIO.createImageOutputStream(baos);

reader = getTiffImageReader();
imageStream= ImageIO.createImageInputStream(new ByteArrayInputStream(img));
reader.setInput(imageStream);

int pages = reader.getNumImages(true);

Iterator<ImageWriter> imageWriters = ImageIO.getImageWritersByFormatName("TIFF");
writer = imageWriters.next();

writer.setOutput(ios);
ImageWriteParam writeParam = writer.getDefaultWriteParam();
writeParam.setTilingMode(ImageWriteParam.MODE_DEFAULT);

writer.prepareWriteSequence(reader.getStreamMetadata());

for (int i = 0; i < pages; i++) {
//IIOImage iioImage = reader.readAll(i, null);
BufferedImage bufimage=null;
BufferedImage imageBuff=null;
bufimage=reader.read(i);
imageBuff=Thumbnails.of(bufimage).size(1200, 1200).asBufferedImage();
IIOImage scalediioImage = new IIOImage(imageBuff, null, null);
writer.writeToSequence(scalediioImage, writeParam);
bufimage.flush();
imageBuff.flush();
}

writer.endWriteSequence();
outimage = baos.toByteArray();


} catch (Exception e) {
e.printStackTrace();
}
finally{
if(imageStream!=null){
imageStream.close();
}
if(ios!=null){
ios.flush();
ios.close();
}

if(baos!=null){
baos.close();
}
if(reader!=null){
reader.dispose();
}
if(writer!=null){
writer.dispose();
}
}
return outimage;
}

最佳答案

ImageIO.write(...) 只会写入单个独立图像。将多个图像写入同一输出流并不能解决此问题。然而 ImageIO 包完全支持你想要的,它只是需要更多的代码。

获取 TIFF 格式的正确 ImageWriter,使用:

ImageWriter writer =  ImageIO.getImageWritersByFormatName("TIFF").next();  // Assumes TIFF plugin installled

请参阅 ImageIO.getImageWritersByFormatName(String) 的 API 文档了解更多信息。

然后使用 writer.canWriteSequence()判断您的 writer 实例是否支持写入序列。对于 TIFF,它应该返回true。如果没有,您需要寻找不同的插件。

接下来,使用writer.prepareWriteSequence(...)准备您的图像序列。

对于要附加的每个图像(页面),请使用 writer.writeToSequence(new IIOImage(..., bufferedImage, null), ...)for 循环中。

最后,在 for 循环之外使用 writer.endWriteSequence()结束图像序列。

希望这些指导能让您朝着正确的方向前进。

更新:这是我认为应该可以工作的代码的清理和修改版本(我没有也无法在我的工作笔记本电脑上安装 JAI)。

重要的更改是从循环中删除 writer.setOutput(ios) (您应该只设置一次),并移动 writer.endWriteSequence() 驱逐环形。我还删除了 BufferedImage 数组,以避免将所有图像保留在内存中,为了方便起见,您可能希望保留它。

如果您仍然遇到问题,请告诉我,我会看看我能做些什么。

public static byte[] resize(byte[] img) throws IOException {
byte[] outimage = null;

try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(30000);
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);

ImageReader reader = getTiffImageReader();
ImageInputStream imageStream = ImageIO.createImageInputStream(new ByteArrayInputStream(img));
reader.setInput(imageStream);

int pages = reader.getNumImages(true);

Iterator<ImageWriter> imageWriters = ImageIO.getImageWritersByFormatName("TIFF");
ImageWriter writer = imageWriters.next();

writer.setOutput(ios);
ImageWriteParam writeParam = writer.getDefaultWriteParam();
writeParam.setTilingMode(ImageWriteParam.MODE_DEFAULT);

writer.prepareWriteSequence(reader.getStreamMetadata()); // You want the stream metadata here

for (int i = 0; i < pages; i++) {
IIOImage iioImage = reader.readAll(i, null); // Save some lines by using readAll

BufferedImage image = (BufferedImage) iioImage.getRenderedImage();

// Modify image here...

iioImage.setRenderedImage(image);

writer.writeToSequence(iioImage, writeParam);
}

writer.endWriteSequence(); // Crucial, must be done outside loop

ios.flush();
ios.close();

outimage = baos.toByteArray();
baos.close();

writer.dispose();
reader.dispose();

} catch (Exception e) {
e.printStackTrace();
}

return outimage;
}

关于java - 在java中缩放多页TIFF图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22856461/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com