如何制作java';是否使用ImageBuffer正确读取PNG文件?

如何制作java';是否使用ImageBuffer正确读取PNG文件?,java,image,image-processing,resize,crop,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())

出于某些原因,使用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:未知图像类型0
java.awt.image.buffereImage.(buffereImage.java:490)
trainingdivident.domain.file.ServerImage.resizeImage(ServerImage.java:68)
trainingdivident.domain.file.ServerImage.cropAndResize(ServerImage.java:80)
trainingdivident.service.user.UserAccountManagerImpl.cropAvatar(UserAccountManagerImpl.java:155)
sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)
invoke(NativeMethodAccessorImpl.java:39)
reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
解决方案


是否还有其他库可以一起使用?

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

int imageType = croppedImage.getType();
if(imageType == 0) imageType = 5;
然后我们传入imageType,它应该可以在Linux上工作

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


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

egervari,您可以使用一个库(Apache2)来“正确地”为您调整大小,以解决这些问题——这对裁剪没有帮助,但调整大小是它最擅长的(不同的速度、质量,甚至抗锯齿,如果需要)

我想指出的是,您现在使用的代码(强制将自定义类型转换为3BYTE_BGR类型)也应该考虑到带有alpha通道的入站图像

另外,如果您想继续使用自定义代码,RGB和ARGB是Java2D中受支持最好的两种图像类型——如果您使用的图像类型支持较差,当Java2D执行图像操作时,它会退回到其软件渲染管道,而不使用专用的硬件加速图像类型。这不仅会影响性能正如您将看到的那样,结果实际上看起来更糟(例如,在GIF中,您经常看到这种情况)

再说一次,如果你想尝试一下,imgscalr会自动为你解决所有这些问题,但如果你不想尝试,我想我会提醒你,以防你遇到这些头痛问题


java图像处理是……喜怒无常的:)

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

在Linux中使用哪个JVM?(编辑:根据堆栈跟踪中的
sun.reflect
判断,它是sun的,但只是为了确定)是的,是最新的sunjvm。我把它修好了。我在其中添加了一个hack,如果image.getType()==0,我手动将其设置为5。FWIW,我刚刚在windows(JVM1.6.0_20)上编译完你的代码,它在随机jpg上运行得非常好。我想知道它是否可能是你的输入文件。不,这段代码在windows上适用于所有东西。它只是在使用升级的jdk的Debian(lenny)上不起作用。我只是检查类型是否为0,如果是,则传入5。这似乎使它起作用了。我猜这是一个bug,与我无关:(
int imageType = croppedImage.getType();
if(imageType == 0) imageType = 5;