Java 使用JAI/ImageIO写入时将灰度图像渲染到黑暗区域
有人能解释为什么会发生这种情况吗。我读取图像并将其渲染到输出写入器中。如果是彩色文件(或黑白文件),则渲染效果良好。然而,如果源图像是灰度的,我得到的只是一个黑匣子 示例文件可在 下面是我的pom插件依赖性片段Java 使用JAI/ImageIO写入时将灰度图像渲染到黑暗区域,java,graphics,rendering,javax.imageio,Java,Graphics,Rendering,Javax.imageio,有人能解释为什么会发生这种情况吗。我读取图像并将其渲染到输出写入器中。如果是彩色文件(或黑白文件),则渲染效果良好。然而,如果源图像是灰度的,我得到的只是一个黑匣子 示例文件可在 下面是我的pom插件依赖性片段 <dependency> <groupId>javax.media</groupId> <artifactId>jai_core</artifactId> <vers
<dependency>
<groupId>javax.media</groupId>
<artifactId>jai_core</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>com.sun.media</groupId>
<artifactId>jai_imageio</artifactId>
<version>1.1</version>
</dependency>
好的,我现在已经修复了我的解码器,谢谢你的示例文件!:-) 无论如何,经过一些研究,我得出结论,问题最终在于示例文件,而不是您的代码或您正在使用的库 此文件的问题在于TIFF元数据包含
photommetricinterpretation==3
/palete和ColorMap
标记。即,图像使用索引颜色模型/调色板。如果根据(我的理解)规范,使用所提供的颜色映射,按照应该的方式读取图像,则图像将显示为全黑色。相反,如果我忽略了这一点,而是将其读取为灰度(假设PhotometricInterpretation==1
/black为零),它将显示为白色(浅灰色)背景上的黑色文本
编辑:
更好的解释是,颜色映射中的值都是8位的量(使用每个颜色条目的低8位),而不是应该使用的完整16位。。。如果我在读取和创建调色板时仅使用低8位检测到这一点,则图像将按预期显示(如DropBox中所示)。根据规范,这仍然是一个不好的图像,但可以检测到。请将相关代码(最好是a)与您的问题一起发布在此处,而不是链接中。链接可能会失效,链接可能包含大型项目,这些项目太大,无法要求志愿者进行审查。我们将非常感谢您遵守此请求,这可能会帮助您获得更好、更快的帮助。您为什么要将图像绘制到自身上?这可能不是您的意图……这只是一段工作代码。在我的实际应用程序中,我在绘制图形之前对图形进行编辑(在文本上添加黑色矩形)、调整大小等。也就是说,还有什么我应该做的吗?谢谢我的评论有意义吗,或者我还遗漏了什么?不,这是有道理的。但我还是会删除那个代码,看看它是否会改变什么,如果不会,就编辑这个问题。帮助您的助手关注您的问题,而不是非问题。:-)此外,由于TIFF阅读/写作没有与JRE捆绑在一起,您可能应该提及您正在使用的插件和版本等(我猜是JAI,但我可能错了)。非常感谢您的研究。我将研究原始图像是如何创建的(由我们使用的第三方库创建)。除此之外,我能做些什么来解决标准java/imageio库的问题吗(我猜不会)metadata@VinayB你可以。但是图像不准确,其他图像可能完全关闭。我认为你最好的选择是1:告诉第三方库写灰度而不是调色板。2:修复第三方库。3:截取colormap中的所有值并将其乘以256。或者使用我的库,由于您的问题,它现在支持此功能。:-)
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class GrayScaleImaging {
public static void main(String[] args)
throws IOException {
//works
// final File inputFile = new File("/home/vinayb/Downloads/page1_color.tif");
// final File outputFile = new File("/home/vinayb/Downloads/page1_color_mod.tif");
//doesn't work
final File inputFile = new File("/home/vinayb/Downloads/page1_grayscale.tif");
final File outputFile = new File("/home/vinayb/Downloads/page1_grayscale_mod.tif");
if (outputFile.exists()) {
outputFile.delete();
}
ImageReader imageReader = null;
ImageWriter imageWriter = null;
Graphics2D g = null;
try (final ImageInputStream imageInputStream = ImageIO.createImageInputStream(inputFile);
final ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(outputFile);) {
//setup reader
imageReader = ImageIO.getImageReaders(imageInputStream).next();
imageReader.setInput(imageInputStream);
//read image
final BufferedImage initialImage = imageReader.read(0);
//prepare graphics for the output
final BufferedImage finalImage = new BufferedImage(initialImage.getWidth(), initialImage.getHeight(), imageType(initialImage));
g = finalImage.createGraphics();
//do something to the image
//doSomething(g)
//draw image
g.drawImage(initialImage, 0, 0, initialImage.getWidth(), initialImage.getHeight(), null);
//setup writer based on reader
imageWriter = ImageIO.getImageWriter(imageReader);
imageWriter.setOutput(imageOutputStream);
//write
imageWriter.write(null, new IIOImage(initialImage, null, imageReader.getImageMetadata(0)), imageWriter.getDefaultWriteParam());
} finally {
//cleanup
if (imageWriter != null) {
imageWriter.dispose();
}
if (imageReader != null) {
imageReader.dispose();
}
if (g != null) {
g.dispose();
}
}
}
private static int imageType(BufferedImage bufferedImage) {
return bufferedImage.getType() == 0 ? BufferedImage.TYPE_INT_ARGB : bufferedImage.getType();
}
}