在我看来,特定设备(特定于供应商的操作系统构建?)生成断开的PNG。然而,似乎唯一缺少的是一些Zip/zlib数据完整性检查值,如果忽略数据完整性检测,则可以正确重建图像。
出于某种原因,我的原始答案(如下)不适用于OP。因此,这里有一种仅使用ImageIO的替代(更详细)方法:
InputStream input = new ByteArrayInputStream(form.getImageFileData());
Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
if (!readers.hasNext()) {
// TODO: Handle, return null or throw exception, whatever is more appropriate
}
ImageReader reader = readers.next();
reader.setInput(input);
try {
ImageReadParam param = reader.getDefaultReadParam();
int imageNo = 0;
int width = reader.getWidth(imageNo);
int height = reader.getHeight(imageNo);
// If possible, create a destination image up front
ImageTypeSpecifier type = reader.getRawImageType(imageNo);
if (type != null) {
param.setDestination(type.createBufferedImage(width, height));
}
// Decode into the destination
BufferedImage image;
try {
image = reader.read(imageNo, param);
}
catch (IOException e) {
if (e.getCause() instanceof ZipException && param.getDestination() != null) {
// If we got here, the destination will contain a partial image
// We'll use that.
image = param.getDestination();
}
else {
throw e;
}
}
}
finally {
input.close();
}
由于
ZipException
,否则,图像看起来不错。
下面是一个使用Java的可能解决方案。我已经在OSX上测试了它,它适用于我,使用Java 1.7.0_71和1.8.0_51(都是Oracle JRE),使用提供的测试文件。堆栈跟踪被打印到控制台,图像的最后一行丢失,否则,它看起来很好:
byte[] data = form.getImageFileData();
Image tmp = Toolkit.getDefaultToolkit().createImage(data);
BufferedImage image = new BufferedImageFactory(tmp).getBufferedImage();
这将比使用
ImageIO
,所以我建议您首先尝试使用
后台以流
如前所述,然后仅在失败时使用此代码作为后备
java.util.zip.ZipException
根本原因。
PS:您可能可以将
Image
到
BufferedImage
使用
MediaTracker
完全加载(或使用
ImageIcon
hack),然后将结果绘制到
缓冲图像
如果你不介意失去一些精度,比如原始的颜色模型等等。
这个
BufferedImageFactory
类是我的TwelveMonkeys ImageIO库的一部分,在BSD许可下可用,可以在
on GitHub
.