.ico 的 JavaFX 2.2 图像支持?

Posted

技术标签:

【中文标题】.ico 的 JavaFX 2.2 图像支持?【英文标题】:JavaFX 2.2 Image support for .ico? 【发布时间】:2015-04-13 00:44:02 【问题描述】:

我正在开发一个必须具有自定义图标的应用程序。所提供的图标在所有尺寸(256x256、48x48、32x32)中都是相同的,但在 16x16 中图标被简化了。

我考虑过 .ico 格式(我可以在其中存储所有不同的图标并让操作系统显示最佳),但 javafx.scene.image 似乎不支持它(我还没有找到任何关于那个)。

这是我设置图标的方式

stage.getIcons().add(new Image(getClass().getResourceAsStream("/path/to/icon.ico")));

在这种情况下,图标永远不会显示。如果我将此图标转换为 .png 图像,这可以工作,但会强制始终显示相同的图标(即使在 16x16 中)。

JavaFX 2.2 中是否有显示 .ico 的方法(即使是一种 hacky 方式)还是我必须使用其他图像格式?

更新

我将我的 .ico 分成多个 png(每种尺寸一个),然后一个接一个地加载它们。

stage.getIcons().add(new Image(getClass().getResourceAsStream("/path/to/icon_16x16.png")));
stage.getIcons().add(new Image(getClass().getResourceAsStream("/path/to/icon_256x256.png")));

256x256 和 16x16 是两个不同的图像,但 16x16 从未显示在应用程序的左上角(尽管这是最接近的尺寸)。

【问题讨论】:

【参考方案1】:

功能请求

查看相关功能请求:

JDK-8092240 Support for the .ico file format

该功能目前未分配给某个版本,但您可以根据需要对其进行投票或评论。

使用第三方库加载 ico 文件

同时,您可以使用各种实用程序来创建java.awt.image.BufferedImage 格式的图标,然后使用SwingFXUtils 将它们转换为JavaFX。 haraldK 在他的回答中提供了这种方法的示例。另一个例子是fav icon fetcher for the willow browser,它使用image4j 库,虽然haraldK 的十二只猴子库可能是更好用的库。您的另一种选择是将基于 awt 的图标库之一的源代码移植到 JavaFX,使用 WritableImage

建议

您之所以不使用 png,因为它始终显示 16x16,这对我来说有点奇怪,因为 stage.getIcons() 文档返回了您可以添加的图像列表(您不仅限于添加单个图标)。来自 javadoc:

获取要在窗口装饰和最小化时使用的图标图像。图像应该是同一图像的不同尺寸,并且将选择最佳尺寸,例如。 16x16, 32,32。

补充问题

如果根据大小,图像并不总是相同的怎么办

提供不同的图像可能没问题。如果系统插入提供的图像以创建未提供大小的图标,这可能会导致问题 - 但我认为系统不太可能这样做。 “图像应该是同一图像的不同尺寸”更多的是指导而不是实际规则。如果您需要不同尺寸的不同图像,请尝试为此提供多个 png 图像,看看会发生什么。

【讨论】:

+1 提到你可以只使用多个 PNG(这是我们通常做的)。不过我已经投票了,所以我不能给你加分... ;-) PS:为什么Kenai JIRA 密码受到保护? @haraldK 这不仅仅是密码保护。它只需要您在阅读/发布任何内容之前注册。但是,为什么他们强制读取访问权限是没有意义的。 @jewelsea 使用这种方法,所有图像应该是相同的图像(但大小不同)。如果根据大小,图像并不总是相同怎么办? @jewelsea 我尝试提供多个不同尺寸的图像,但行为有点奇怪:选择的图像似乎总是最大的(需要时缩小)。【参考方案2】:

使用image4j:

ArrayList<Image> lImages = new ArrayList<>();
ICODecoder.read(Global.FILE_ICON).stream().forEach((lBufferedImage) -> lImages.add(SwingFXUtils.toFXImage(lBufferedImage, null)));
this.getStage().getIcons().addAll(lImages);

【讨论】:

【参考方案3】:

我不认为 JavaFX 直接支持 ICO 格式。我很确定该列表只有 JPEG、GIF 和 PNG,但我还没有找到证实这一点的官方来源。

但是,您可以使用我的 ICO plugin for ImageIO 来读取 ICO 文件,并使用 SwingFXUtils.toFXImage(bufferedImage, null) 将图像转换为 FX Image

请注意,阅读器只是按照它们在 ICO 文件中的顺序返回图标,所以ImageIO.read(...) 不会给你你想要的图标(它只会读取第一个)。相反,您需要阅读每个图标,转换所有图标并将其添加到您的舞台。 FX 会为您选择正确的尺寸。 :-)

类似:

ImageInputStream stream = ImageIO.createImageInputStream(getClass().getResourceAsStream("/path/to/icon.ico"));
ImageReader reader = ImageIO.getImageReaders(stream).next();

reader.setInput(stream);
int count = reader.getNumImages(true);

List<Image> fxImages = new ArrayList<>(count);

for (int i = 0; i < count; i++) 
    BufferedImage bufferedImage = reader.read(i, null);
    Image fxImage = SwingFXUtils.toFXImage(bufferedImage, null);
    fxImages.add(fxImage);


stream.close(); // Remember to close/dispose in a finally block
reader.dispose();

// ...

stage.getIcons().addAll(fxImages);

【讨论】:

我赞成您的回答,但我最终会使用多个 png(预先计算),而不是为每次执行进行此计算。 @Spotted 对我来说很有意义。 :-)

以上是关于.ico 的 JavaFX 2.2 图像支持?的主要内容,如果未能解决你的问题,请参考以下文章

favicon.png 与 favicon.ico - 为啥我应该使用 PNG 而不是 ICO?

如何制作ico图标?

网页title加icon

JavaFX16 警告:不支持的 JavaFX 配置:类是从“未命名模块 @***”加载的

JavaFX。为标题栏和操作系统任务栏设置不同的图标

如何更改delphi7中窗体(form)左上角的图标?都支持那些类型的图标,如,ico,jpe?为何更改图标后显示出错呢?不