JavaFX 2.2对.ico的图像支持?

Spo*_*ted 7 image ico javafx-2

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

我想到了.ico格式(我可以存储所有不同的图标并让操作系统显示最佳)但javafx.scene.image似乎没有支持它(我还没有找到任何关于它的确认) ).

以下是我设置图标的方法

stage.getIcons().add(new Image(getClass().getResourceAsStream("/path/to/icon.ico")));
Run Code Online (Sandbox Code Playgroud)

在这种情况下,永远不会显示图标.如果我将此图标转换为.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")));
Run Code Online (Sandbox Code Playgroud)

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

jew*_*sea 7

功能要求

查看相关功能请求:

该功能目前尚未分配给版本,但如果您愿意,可以对其进行投票或评论.

使用第三方库加载ico文件

在此期间,您可以使用各种实用程序以java.awt.image.BufferedImage格式创建图标,然后使用它们将它们转换为JavaFX SwingFXUtils.haraldK在他的回答中提供了这种方法的样本.另一个例子是使用image4j的柳树浏览器fav图标获取器,尽管haraldK的十二个猴子库可能是更好的库.您的另一种选择是将一个基于awt的图标库的源代码移植到JavaFX,使用a .WritableImage

忠告

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

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

补充问题

如果根据尺寸,图像并不总是相同的,那该怎么办?

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

  • @jewelsea我尝试提供多个大小不同的图像,但是行为有点奇怪:所选图像似乎总是最大的(需要时缩小尺寸)。 (2认同)

har*_*ldK 5

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

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

请注意,阅读器只是按照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);
Run Code Online (Sandbox Code Playgroud)