.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?
JavaFX16 警告:不支持的 JavaFX 配置:类是从“未命名模块 @***”加载的
如何更改delphi7中窗体(form)左上角的图标?都支持那些类型的图标,如,ico,jpe?为何更改图标后显示出错呢?不