Java如何加载本机NSImages?

时间:2015-08-19 05:17:13

标签: java image macos toolkit

我一直在阅读OS X Java开发人员工具,以帮助我的应用程序更加“本机化”操作系统。我在这个section中发现了一些有趣的东西。 (强调我的)

  

要将应用程序包的Res​​ources文件夹中与分辨率无关的 tiff,icns, pdf 文件加载到Java应用程序中,请使用getImage() java.awt.Toolkit的方法。您传入getImage()的字符串格式为"NSImage://MyImage"。不要包含图像的文件扩展名。另请注意,当用户界面比例因子的值不为1.0时,将禁用Sun 2D渲染器。使用Quartz渲染器可以使图像平滑缩放。

熟悉javax.imageio,这是一个完全的惊喜,因为我还不知道任何其他方式将其他文件类型加载到图像中。特别是对于过时的平台,绝对不支持.tiff等文件。例如,我的计算机上的快速测试给了我:

Supported read formats: [jpg, bmp, gif, png, wbmp, jpeg]
Supported write formats: [jpg, bmp, gif, png, wbmp, jpeg]
'JPEG' reader: com.sun.imageio.plugins.jpeg.JPEGImageReader@5e9f23b4
'JPEG' reader: com.sun.imageio.plugins.jpeg.JPEGImageWriter@378fd1ac

我尝试加载一个简单的.tiff图像并对其进行测试:

static Image n;

public static void main(String[] args) {
    JFrame f = new JFrame();
    JPanel p = new JPanel() {
        @Override
        public void paintComponent(Graphics graphics) {
            graphics.drawImage(n, 0, 0, null);
        }
    }
    f.add(p);
    n = Toolkit.getDefaultToolkit().getImage(("/Users/zinedine/Desktop/test_image.tiff");
    f.setVisible(true)
}

没有任何结果:

enter image description here

我再次尝试:这一次,将图像添加到我的java项目的基本文件夹中,并以字符串形式输入:"NSImage://test_image.tiff"。就像我做的一切一样,它不起作用。

但是,如果我将我的花式路径字符串更改为NSImage字符串,例如"NSImage://NSApplicationIcon" ...

enter image description here

有效。我做了一个快速的聚光灯搜索NSImage,并找到了一个。看起来这些图像的文件类型是.png。这有点令人不安,因为我预计会有一个合适的图像。请注意,我也有点期待它:如果它需要"NSImage://something"形式的参数,那么它可能会忽略其他任何东西。

显然,我有几个问题:

  • Toolkit如何加载图像?如果我尝试从桌面加载.tiff图片,这就是我拨打.toString()时收到的内容:

    sun.awt.image.ToolkitImage@25f38edc // Also can't be cast to java.awt.BufferedImage
    
  • 读者(和编写者,如果有的话)是否是公共API的一部分?换句话说,我可以调用一些东西将我的.tiff文件加载到Image(然后我可以将其转换为`BufferedImage?

  • 然后,如果读者/作者是API的一部分,为什么javax.imageio包找不到它们?

这可能看起来很少,(是的,我很抱歉在这个问题上毁了你的一天),但对我来说,这看起来像预期的,但同时也是错误的行为。加分标记:是否有任何可以处理.tiff文件(和其他)的友好(即开放源代码)成像API(非JAI)?

1 个答案:

答案 0 :(得分:1)

您在这里提出了多个问题,但我会尽力解释这一切。 : - )

使用Toolkit加载图片(java.awt.Image和朋友)是" old"异步生产者/消费者映像API,可能会感到有点尴尬。它可以完全加载打包的图标和类似图标,但不太适合加载大型用户提供的图像,因为你没有进度跟踪,如果出现任何问题,反馈很少,等等。

如果您想要执行任何类型的图像处理,这些图像也比BufferedImage更有用。你不能将它们转换为BufferedImage,但你可以"转换"将它们涂在BufferedImage上。

Toolkit类是抽象的,您使用Toolkit.getToolkit()获取具体实例。此具体实例是特定于平台的,并且最终使用系统特定的本机调用来处理大多数方法,例如加载图像。

Apple Java实现确实有一些额外的功能,例如允许您使用特殊的URI方案加载Apple系统映像。它似乎也可以通过这种方式加载捆绑的图像,使用@2x命名约定,甚至是OS X中的多尺度TIFF或可缩放PDF,用于应用程序的独立分辨率图形。

请注意,要使其正常工作,您需要将应用程序打包为应用程序包,并将图像放在捆绑包的Res​​ources文件夹(即Contents/Resources)中。并且您必须使用其基本名称引用图像,而不使用扩展名。据我所知,您不能使用此功能来读取未随应用程序打包的随机TIFF文件(即用户提供的内容)。

此外,此功能特定于Apple JRE ,并且仅适用于Apple自己的JRE和OS X.它不是公共Java的一部分API,它不会跨平台工作。我建议谨慎使用该功能,并且只在OS X上进行更好的系统集成(即使您的应用程序看起来更原生)。

要读取(并写入)任何TIFF(或任何其他格式),您应该使用ImageIO和一些适当的插件。由于某些原因,JRE没有附带TIFF格式的插件,但存在多个第三方插件。

如果您不想使用JAI(通过jai_imageio.jar),我可以推荐自己的TwelveMonkeys library which supports TIFF以及其他一些格式。它使用商业友好的开源BSD许可证。

还有Apache Commons ImagingiCafe以及可能读/写TIFF的其他人,但这些都有自己的自定义API,这使得它们的灵活性降低,IMO也更加专有。