Java中的BufferedImage和ColorModel

3

我正在使用Java中的图像处理库来操作图像。我所做的第一步是读取图像并创建一个java.awt.Image.BufferedImage对象。我是这样做的,

BufferedImage sourceImage = ImageIO.read( new File( filePath ) );

上面的代码创建了一个带有DirectColorModel的BufferedImage对象:
rmask=ff0000 gmask=ff00 bmask=ff amask=0.
当我在我的Macbook上运行上述代码时,会发生以下情况。
但是当我在Linux机器(托管服务器)上运行相同的代码时,这将创建一个带有ColorModel的BufferedImage对象: pixelBits = 24 numComponents = 3 color space = java.awt.color.ICC_ColorSpace@c39a20 transparency = 1 has alpha = false isAlphaPre = false.
我在两种情况下使用了相同的jpg图像。我不知道为什么在Mac和Linux上运行相同的图像的ColorModel不同。Mac的ColorModel有4个组件,而Linux的colormodel有3个组件。
由于这个问题产生了一个问题,我使用的图像处理库总是假定传递的图像的ColorModel中始终有4个组件,并在Linux框上运行时抛出数组越界异常。但在Macbook上,它可以正常运行。
再添加一些信息,一旦读取了图像,我打印出image.getType()
在Mac上->它返回TYPE_INT_RGB(值为1) 在Linux上->它返回TYPE_3BYTE_BGR(值为5)
我不确定我是否做错了什么或者库存在问题。请让我知道您的想法。如果我说得不清楚,请问我任何问题!

1
听起来像是库中的一个错误。它不应该对从ImageIO.read返回的图像的ColorModel做出任何假设。 - finnw
这很可能取决于使用的Linux版本和图形堆栈。对于更现代的图形堆栈,具有合成支持它们将具有Alpha通道。然而,正如DirectColorModel所说,一些项目是最终的,因为JVM需要与操作系统/图形堆栈进行交互以实际显示内容。OPs Linux系统使用3字节RGB来保存内存;如果您转换模式(xrandr等),它将转换为另一个值,因此最好将其转换为所需的模型。 - artless noise
1个回答

6
我不确定为什么你会得到两种不同的颜色模型,尽管我认为它们是相同的。DirectColorModel 有 4 个组件,但 alpha 掩码为 0,因此实际上它只有 3 个组件,就像另一个一样。
我建议编写一个简单的辅助函数,在将图像传递给该图像库之前确保图像具有正确的颜色模型。这个帮助函数可以利用 http://java.sun.com/j2se/1.4.2/docs/api/java/awt/image/ColorConvertOp.html 或使用类似以下代码的东西(未经测试):
private static BufferedImage makeCompatible(BufferedImage image) {
  int w = image.getWidth();
  int h = image.getHeight();
BufferedImage result = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR); Graphics2D g = result.createGraphics(); g.drawRenderedImage(image, new AffineTransform()); //或其他一些 drawImage 函数 g.dispose();
return result; }
假设该库能够处理BufferedImage.TYPE_4BYTE_ABGR。否则,您需要在此处放置其他内容。当然,在转换之前,您可以检查原始图像是否已具备正确的格式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接