如何获取文件的所有不同尺寸的系统图标

9

我正在编写一段Java代码,需要获取文件系统图标的不同大小。我知道要获取文件系统图标,应该使用以下代码:

File file = new File("Whatever.txt");
FileSystemView view = FileSystemView.getFileSystemView();
Icon icon = view.getSystemIcon(file);

但是这段代码只返回图标的最小尺寸。我该怎么做才能获取其他尺寸呢?


1
据我所知,Java不支持其他图标。如果您需要它们,请向Oracle提出RFE以添加提供Icon[]的方法。 - Andrew Thompson
@AndrewThompson,能否请您再详细解释一下? - mehrmoudi
您能具体说明一下吗?您不明白的是什么? - Andrew Thompson
@AndrewThompson 好的,没问题。 我只需要获取单个文件的所有不同大小和图像的图标,就像操作系统默认的文件浏览器或资源管理器中显示的那样。 使用我上面提到的代码,只返回最小的图标;你说为了解决这个问题,我可以向Oracle提出一个RFE来添加一个提供Icon[]的方法。 你确定它会给我想要的东西吗? 如果是这样,我不知道什么是RFE,也不太了解你说的整个内容! - mehrmoudi
2
“你确定它会给我想要的吗?”如果你明确指定了,并且Oracle可以并且实现了它。RFE - “增强请求” - 通过错误数据库提出一个。点击链接,然后按照说明操作(在链接末尾描述)。顺便说一句 - 请注意,即使Oracle实现了它,也至少要等到Java 8才能使用。 ;) - Andrew Thompson
4个回答

1

对于32x32的图标,您可以使用ShellFolder。

sun.awt.shell.ShellFolder.getShellFolder( file ).getIcon( true ) 

或者使用JNI API。这两种“解决方案”已经在这里讨论过了。


0

我也遇到了需要高清晰度图标的同样问题。经过一个小时的挖掘,我认为答案相当明确,尽管非常不幸。

  1. 目前没有本地库支持。
  2. 本地支持预计在Java版本12上发布。
  3. 即使经过广泛搜索,我也找不到任何可靠的第三方库。

已经在JDK bug系统这里提交了此问题的工单,但它似乎不在他们的优先级列表中。


然而,似乎有解决方法:

我假设您正在使用Windows。在Linux上查找图标文件很容易,因为图标是单独存储并链接到桌面条目中的。

  1. 使用第三方命令行exe工具(例如this onethis one)将图标提取到临时目录中。您可以使用Runtime.exec()
  2. 使用像这里建议的那些的.ico阅读器库将所有图像文件读入List中的BufferedImage
  3. 遍历列表以找到分辨率最高的图像。
  4. 删除临时文件。

更新

刚刚实现了我的解决方法,它起作用了。这是代码片段。我在我的实现中使用了iconsext.exeimage4j

    // Extract icons and wait for completion.
    File iconDir = new File("tempIcons");
    String[] iconsextCmd = { "iconsext.exe", "/save", exeFile.getPath(), iconDir.getPath(), "-icons" };
    Process iconsextProc = Runtime.getRuntime().exec(iconsextCmd);
    iconsextProc.waitFor();

    // Get all icons, sort by ascending name, and pick first one.
    File[] icons = iconDir.listFiles();
    Arrays.sort(icons, (f1, f2) -> f1.getName().compareTo(f2.getName()));
    File defaultIcon = icons[0];

    // Read images from icon.
    List<ICOImage> iconImgs = ICODecoder.readExt(defaultIcon);

    // Sort images by descending size and color depth, and pick first one.
    iconImgs.sort((i1, i2) -> (i2.getWidth() * i2.getHeight() * 33 + i2.getColourDepth())
            - (i1.getWidth() * i1.getHeight() * 33 + i1.getColourDepth()));
    BufferedImage awtImg = iconImgs.get(0).getImage();

    // Delete temporary icons.
    for (File i : icons)
    {
        i.delete();
    }
    iconDir.delete();

加入一些JavaFX代码:

Nice and big icons

漂亮又大的图标!


我知道这个解决方法有些麻烦和复杂,而且它也抵消了Java跨平台的优势,但说实话这是我能想到的最好的方法。希望能对你有所帮助。


这只提取系统默认图标,如果我需要Steam图标怎么办?在iconsextract页面上,它说有一个选项可以[将单个图标复制到剪贴板],这可能在这里很方便,但不幸的是该页面本身相当古老。 - clockw0rk

0

我创建了一个名为JIconExtractReloaded的库,可以提取所有图标大小,而不仅仅是32x32。这是链接https://github.com/MrMarnic/JIconExtractReloaded

只需编写:

BufferedImage image = JIconExtract.getIconForFile(128,128,"C:\\Windows\\explorer.exe");

而且你有图标。


0
如果您正在寻找如何在 Mac 上处理此问题,您可以使用第三方库 Quaqua
import java.awt.image.BufferedImage;
import java.io.File;

public class SystemIconMac {
    public static BufferedImage getIconImage(File file, int size) {
        return  ch.randelshofer.quaqua.osx.OSXFile.getIconImage(file, size);
    }
}

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