使用ImageIO.write()创建JPEG格式会生成一个0字节的文件。

12

我正在尝试编写一个方法,该方法接受一张图片,并保存该图片的100x100缩略图。但是,当我保存文件时,它以不可读的0字节图像(并显示“Error interpreting JPEG image file(在状态200中调用JPEG库不正确)”错误)显示在Ubuntu的ImageViewer中。我的代码如下:

public boolean scale(){

    String file = filename.substring(filename.lastIndexOf(File.separator)+1);
    File out = new File("data"+File.separator+"thumbnails"+File.separator+file);

    if( out.exists() ) return false;

    BufferedImage bi;
    try{
        bi = ImageIO.read(new File(filename));
    }
    catch(IOException e){
        return false;
    }

    Dimension imgSize = new Dimension(bi.getWidth(), bi.getHeight());
    Dimension bounds = new Dimension(100, 100);
    int newHeight = imgSize.height;
    int newWidth = imgSize.width;

    if( imgSize.width > bounds.width ){
        newWidth = bounds.width;
        newHeight = (newWidth*imgSize.height)/imgSize.width;
    }

    if( imgSize.height > bounds.width ){
        newHeight = bounds.height;
        newWidth = (newHeight*imgSize.width)/imgSize.height;
    }

    Image img = bi.getScaledInstance(newWidth, newHeight, BufferedImage.SCALE_SMOOTH);
    BufferedImage thumb = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_4BYTE_ABGR);
    Graphics2D g2d = thumb.createGraphics();
    g2d.drawImage(img, 0, 0, null);
    g2d.dispose();

    try{
        ImageIO.write(thumb, "jpg", out);
    }
    catch(IOException e){
        return false;
    }

    return true;
}

"filename"是包含该方法的类的全局变量,表示原始图像的路径。我的主要问题是我不明白为什么要创建一个0字节的图像。


据我所知,你需要关闭IO缓冲区才能实际写入内容。这通常是Java中IO的工作方式 - 不过可能我说错了。 - user1131435
3
请检查您是否有写入磁盘的权限,并且您是否有足够的磁盘空间可用。 - Reimeus
@Reimeus - 我有写入权限,并且我有可用的磁盘空间;至少我认为我有,因为我能够成功创建其他文件(具体来说是 .txt 文件),除非我误解了您所说的“磁盘空间”,否则我有足够的空间。 - Thomas Preston
@Telthien - 除非我漏掉了什么,ImageIO似乎没有关闭其缓冲区的方法。我认为它会被ImageIO处理,而无需我调用任何东西。 - Thomas Preston
为了更快地获得更好的帮助,请发布一个SSCCE - Andrew Thompson
显示剩余2条评论
3个回答

13

所以问题就在于这里。我正在OpenJDK中工作。显然,OpenJDK没有JPEG编码器,因此在文件被创建时

ImageIO.write(thumb, "jpg", out);

实际上它没有创建任何内容来保存到文件中,因此生成了一个空的0字节不可读取的文件。将ImageIO参数更改为"png"(并适当调整新的File()扩展名),可以成功使用上述代码创建所需的图像。


4

JPG 没有 alpha 通道,ImageIO.write() 将会悄无声息地失败(只返回 false)。一种方法是将您的图像复制到另一个图像中。

BufferedImage newBufferedImage = new BufferedImage(bufferedImage.getWidth(),
  bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB);
newBufferedImage.getGraphics().drawImage(bufferedImage, 0, 0, null);

boolean write = ImageIO.write(newBufferedImage, extension, outputfile);
if (!write) {
  // do something
}

这就是了!静默失败应该是一个bug。 - undefined

3

即使JVM有JPG编码器,我也遇到了同样的问题,原因是在底层使用了不支持的BufferImage类型。我使用了BufferedImage.TYPE_USHORT_GRAY,显然不被支持,没有出现错误消息,但生成了一个0字节的文件。当我切换到BufferedImage.TYPE_BYTE_GRAY时,它完美地工作了。


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