有没有办法用我的 JfileChooser 中选择的扩展来保存我的 bufferedImage?

Posted

技术标签:

【中文标题】有没有办法用我的 JfileChooser 中选择的扩展来保存我的 bufferedImage?【英文标题】:Is there a way to save my bufferedImage with the extention selected in my JfileChooser? 【发布时间】:2019-04-03 14:48:32 【问题描述】:

我的代码有问题。首先,我创建了一个 JfileChooser,将我的 bufferedImage 保存到一个文件中。 问题是当我保存它时,如果我不在窗口中写入扩展名,它将是一个普通文件而不是 jpg/png 或其他文件。我该怎么做?

我尝试了一些奇怪的代码,比如获取文件扩展名的描述,但它不起作用

    JFileChooser savechooser = new JFileChooser();
    savechooser.setFileFilter(new FileNameExtensionFilter("JPEG File", "jpg"));
    savechooser.setFileFilter(new FileNameExtensionFilter("PNG File", "png"));
    savechooser.setFileFilter(new FileNameExtensionFilter("GIF File", "gif"));
    int returnVal = savechooser.showSaveDialog(null);
    if(returnVal == JFileChooser.APPROVE_OPTION) 
        ImageIO.write(bImage, "png" , new File(savechooser.getSelectedFile().getAbsolutePath()));

我希望是“test.png”或“test.jpeg”,但实际输出是“test”文件..

【问题讨论】:

【参考方案1】:

ImageIO.write(...)(代码中的“png”)的第二个参数是文件的格式。这与文件的 name 没有直接关系。 “文件扩展名” 或后缀只是文件名的一部分,可以是任何东西,尽管按照惯例,它用于指示文件的格式(即,没有什么能阻止你命名JPEG 文件“foo.gif”,如果你真的想要,它仍然是一个 JPEG 文件)。 Windows 通常使用此约定来确定文件类型并选择适当的应用程序来打开文件,因此使用非标准扩展名可能会造成混淆。

要解决您看到的问题,最好确保文件名以正确的扩展名结尾,除非用户添加了一个。例如(假设用户选择了 PNG 格式,但您也可以轻松地将其调整为其他格式):

// JFileChooser code as is

if (returnVal == JFileChooser.APPROVE_OPTION) 
   File file = savechooser.getSelectedFile();

   String fileName = file.getName();
   if (!fileName.toLowerCase().endsWith(".png")) 
       file = new File(file.getParent(), fileName + ".png");
   

   if (!ImageIO.write(image, "PNG" , file)) 
       // TODO: Handle file could not be written case
   

以上将确保文件具有正确的文件扩展名,除非用户自己提供。

我还在您的代码中发现了另一个问题。您调用savechooser.setFileFilter(..) 三次。每次调用都会用新的过滤器替换当前过滤器。您可能想改用savechooser.addChoosableFileFilter(...)(也许setFileFilter(..) 是您想用作默认值的那个)。过滤器将过滤对话框中显示的文件,从而过滤用户单击的文件,但不会影响用户自己提供的名称。您可以从savechooser.getFileFilter() 获取当前过滤器,并使用它来确定要使用的格式。

这里有一个更完整的解决方案:

JFileChooser savechooser = new JFileChooser();
FileNameExtensionFilter pngFilter = new FileNameExtensionFilter("PNG File", "png")
savechooser.addChoosableFileFilter(pngFilter);
savechooser.addChoosableFileFilter(new FileNameExtensionFilter("JPEG File", "jpg"));
savechooser.addChoosableFileFilter(new FileNameExtensionFilter("GIF File", "gif"));

savechooser.setFileFilter(pngFilter); // Default choose PNG

int returnVal = savechooser.showSaveDialog(null);

if (returnVal == JFileChooser.APPROVE_OPTION) 
   File file = savechooser.getSelectedFile();

   FileNameExtensionFilter currentFilter = (FileNameExtensionFilter) savechooser.getFileFilter();
   String ext = currentFilter.getExtensions()[0];

   if (!currentFilter.accept(file)) 
       // File does not not have the correct extension, fix it
       String fileName = file.getName();
       file = new File(file.getParent(), fileName + "." + ext);
   

   String format = "jpg".equals(ext) ? "JPEG" : ext; // May not be strictly necessary, just a reminder that file ext != file format

   if (!ImageIO.write(image, format , file)) 
       // TODO: Handle file could not be written case
   

【讨论】:

感谢 Anwser,只是想知道,您将缓冲图像 bImage 保存在哪里?而对于not bewritten case的Handle,我应该做一个try catch方法还是使用其他方法? @Cronologium 我刚刚命名了变量图像。它和你的 bImage 一样。处理您认为合适的未书面案例。在 UI 应用程序中,我可能会显示一个对话框来解释用户发生了什么。 如果它有助于解决问题,请accept the answer。

以上是关于有没有办法用我的 JfileChooser 中选择的扩展来保存我的 bufferedImage?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法用我的排行榜解决这个错误?

将 JFileChooser 添加到 Eclipse Window Builder

java JFileChooser 选择文件时,文件很多的时候如何能进行日期排序,便于查找想要选择的文件

使用 JFileChooser 过滤文件类型

如何从 JFileChooser(JAVA Swing) 中禁用文件操作、文件选择和过滤面板?

取消在 JFileChooser 中选择文件而不关闭对话框