JavaFX 2.2 图像支持 .ico?

发布于 2025-01-16 03:09:29 字数 884 浏览 4 评论 0 原文

我正在开发一个必须有自定义图标的应用程序。所提供的图标在所有尺寸(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 从未显示在应用程序的左上角(尽管这是最接近的尺寸)。

I am developing an application that must have a custom icon. The provided icon is the same in all sizes (256x256, 48x48, 32x32) except in 16x16 where the icon is simplified.

I thought about the .ico format (where I can store all the differents icons and let the OS showing the best) but it doesn't seem to be supported by the javafx.scene.image (I haven't found any confirmation about that).

Here is how I set up my icon

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

In this case the icon is never displayed. If I convert this icon into a .png image, this works but enforces to always display the same icon (even in 16x16).

Is there a way in JavaFX 2.2 to display a .ico (even in an hacky way) or do I have to use other image formats ?

Update

I separated my .ico into multiple png (one for each size) and then loading them one by one.

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

The 256x256 and the 16x16 are two different images but the 16x16 is never showed in the top left of the application (despite this is the nearest size).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

美人迟暮 2025-01-23 03:09:29

功能请求

请参阅相关功能请求:

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

使用第三方库加载 ico 文件

同时,您可以使用各种实用程序在 java.awt.image.BufferedImage 格式,然后使用 SwingFXUtils。 haraldK 在他的回答中提供了这种方法的示例。另一个例子是 willow 浏览器最喜欢的图标获取器,它使用 image4j 库haraldK 的十二只猴子库可能是更好用的库。您的另一种选择是将基于 awt 的图标库之一的源移植到 JavaFX,使用 WritableImage

建议

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

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

其他问题

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

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

Feature Request

See the related feature request:

The feature is currently not allocated to a release, but you can vote or comment on it if you like.

Loading ico files using third party libraries

In the meantime, you can use various utilities for creating icons in java.awt.image.BufferedImage format and then convert them to JavaFX using SwingFXUtils. haraldK provides a sample of this approach in his answer. Another example is the fav icon fetcher for the willow browser, which uses the image4j library, though haraldK's twelve monkeys library is likely the better library to use. Your other alternative is to port the source of one of the awt based icon libraries to JavaFX, making use of a WritableImage.

Advice

Your reasoning for not using png because it always displays 16x16 is a bit strange to me, because the stage.getIcons() documentation returns a list of images you can add to (you aren't limited to adding single icon). From the javadoc:

Gets the icon images to be used in the window decorations and when minimized. The images should be different sizes of the same image and the best size will be chosen, eg. 16x16, 32,32.

Additional question

What if, depending on the size, the image is not always the same

It's probably OK to provide different images. If the system interpolates provided images to create icons of sizes which are not provided, that could cause an issue - but I think that it is highly unlikely that the system would do that. "Images should be different sizes of the same image" is more of a guideline than an actual rule. If you need different images at different sizes, try supplying multiple png images for that and see what happens.

何必那么矫情 2025-01-23 03:09:29

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

但是,您可以使用我的 ImageIO 的 ICO 插件 读取 ICO 文件,并使用 Image href="http://docs.oracle.com/javafx/2/api/javafx/embed/swing/SwingFXUtils.html#toFXImage(java.awt.image.BufferedImage,%20javafx.scene.image.WritableImage)" rel ="nofollow">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);

I don't think JavaFX supports the ICO format directly. I'm pretty sure the list is JPEG, GIF and PNG only, but I've yet to find an official source that confirms this.

However, you could use my ICO plugin for ImageIO to read the ICO file, and convert the image to an FX Image using SwingFXUtils.toFXImage(bufferedImage, null).

Note that the reader simply returns the icons in the order they are found in the ICO file, so ImageIO.read(...) will not give you the icon you want (it will only read the first). Instead you need to read each icon, convert and add all the icons to your stage. And FX will select correct size for you. :-)

Something like:

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);
阳光下的泡沫是彩色的 2025-01-23 03:09:29

使用 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);

Use 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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文