如何让java Image Buffer正确读取PNG文件?

时间:2011-04-29 18:51:33

标签: java image image-processing resize crop

出于某种原因,使用ImageBuffer和ImageIO打开一些PNG文件不起作用。这里有一些我正在使用的代码可以很好地调整大小/裁剪JPG:

BufferedImage image = ImageIO.read(new File(location));

BufferedImage croppedImage = image.getSubimage(
    cropInfo.getX(), cropInfo.getY(), cropInfo.getW(), cropInfo.getH());

BufferedImage resizedImage = new BufferedImage(
    TARGET_WIDTH, TARGET_HEIGHT, croppedImage.getType());
Graphics2D g = resizedImage.createGraphics();
g.drawImage(croppedImage, 0, 0, TARGET_WIDTH, TARGET_HEIGHT, null);
g.dispose();

this.changeContentType("image/png", ".png"); // not really relevant. just a property

ImageIO.write(resizedImage, "png", new File(location));

return resizedImage;

此函数的目标是获取给定的任何类型,调整大小并裁剪图像,然后将其保存到具有相同文件名的PNG。

它适用于Windows,但如果我在Linux(lenny)上裁剪/调整大小,它会完全崩溃并抱怨文件的类型(它表示类型为0)。

java.lang.IllegalArgumentException: Unknown image type 0
    java.awt.image.BufferedImage.<init>(BufferedImage.java:490)
    trainingdividend.domain.file.ServerImage.resizeImage(ServerImage.java:68)
    trainingdividend.domain.file.ServerImage.cropAndResize(ServerImage.java:80)
    trainingdividend.service.user.UserAccountManagerImpl.cropAvatar(UserAccountManagerImpl.java:155)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

解决方案?

我可以使用另一个库吗?

3 个答案:

答案 0 :(得分:4)

在Windows上运行我的函数时,croppedImaged.getType()返回值5.因此,简单的“hack”是存储类型,检查它是否为0 ......如果是,则设置值到5手动。

int imageType = croppedImage.getType();
if(imageType == 0) imageType = 5;

然后我们传入 imageType ,它应该适用于Linux。

我确信这有一个缺点,如果在其他情况下值为0,它会将其设置为5,这将是错误的。但是,这似乎适用于Linux上的常见图像类型,并没有造成任何问题。

很明显,Windows 1.6版本的Java 1.6非常好,但Linux版本中有一个错误。

答案 1 :(得分:1)

egervari,您可以使用像imgscalr(Apache 2)这样的库来“正确地”为您执行所有调整大小,以便使用very simple API解决这些问题 - 它无法帮助您裁剪,但调整大小是最好的(不同的速度,质量,甚至如果你想要的抗锯齿)。

我想指出你现在使用的代码(强制CUSTOM类型为3BYTE_BGR类型)也应该考虑带有alpha通道的入站图像。

此外,如果您想继续使用自定义代码,RGB和ARGB是Java2D中支持的两种最佳图像类型 - 如果使用支持不良的图像类型,当Java2D执行图像操作时,它会回退它的软件渲染管道并没有使用专门的硬件加速管道。这不仅影响性能,因为您会看到结果实际上看起来更糟糕(例如,在GIF中你看到了很多)。

再一次,如果你想尝试一下,imgscalr会自动为你处理这一切,但如果没有,我想我只是在你遇到一些令人头痛的问题时提醒一下。

java图像处理是......气质:)

答案 2 :(得分:0)

解决方法是首先将文件转换为jpeg,然后对其进行处理。类型0错误似乎主要影响PNG图像。