如何在MacOS上用C编写的应用程序中打开JPG图像

qf9go6mv  于 2023-01-08  发布在  Mac
关注(0)|答案(1)|浏览(239)

我想用C写一个简单的图像浏览器,然后为MacOs做一个捆绑包。
问题是,当我试图从Finder的上下文菜单中打开JPG文件时,我遇到了一个警告。

I compiled my code, I prepared a iViewGtk.app bundle with Info.plist file.
信息列表如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>CFBundleExecutable</key>
        <string>iViewGtk</string>
        <key>CFBundleName</key>
        <string>iViewGtk</string>
        <key>CFBundleGetInfoString</key>
        <string>5.0</string>
        <key>CFBundleTypeName</key>
        <string>3r23rfewfwefwef343f</string>
        <key>CFBundleTypeOSTypes</key>
        <array>
            <string>****</string>
        </array>
        <key>CFBundleTypeMIMETypes</key>
        <string>image/jpeg</string>
        <key>CFBundleIconFile</key>
        <string>icon.icns</string>
        <key>CFBundleIdentifier</key>
        <string>net.bean.gtk.iview</string>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>LSMinimumSystemVersion</key>
        <string>10.14</string>
        <key>NSPrincipalClass</key>
        <string>NSApplication</string>
        <key>CFBundleShortVersionString</key>
        <string>5.0</string>
        <key>CFBundleDocumentTypes</key>
        <array>
            <dict>
                <key>CFBundleTypeExtensions</key>
                <array>
                    <string>bmp</string>
                    <string>cur</string>
                    <string>gif</string>
                    <string>icns</string>
                    <string>ico</string>
                    <string>jpeg</string>
                    <string>jpg</string>
                    <string>jpe</string>
                    <string>jfi</string>
                    <string>jfif</string>
                    <string>pbm</string>
                    <string>pgm</string>
                    <string>png</string>
                    <string>ppm</string>
                    <string>svg</string>
                    <string>svgz</string>
                    <string>tif</string>
                    <string>tiff</string>
                    <string>wbmp</string>
                    <string>webp</string>
                    <string>xbm</string>
                    <string>xpm</string>
                    <string>ani</string>
                    <string>apng</string>
                    <string>avif</string>
                    <string>avifs</string>
                    <string>bw</string>
                    <string>exr</string>
                    <string>hdr</string>
                    <string>heic</string>
                    <string>heif</string>
                    <string>jxl</string>
                    <string>kra</string>
                    <string>ora</string>
                    <string>pcx</string>
                    <string>pic</string>
                    <string>psd</string>
                    <string>ras</string>
                    <string>rgb</string>
                    <string>rgba</string>
                    <string>sgi</string>
                    <string>tga</string>
                    <string>xcf</string>
                </array>
                <key>CFBundleTypeRole</key>
                <string>Viewer</string>
            </dict>
        </array>
        <key>NSSupportsAutomaticGraphicsSwitching</key>
        <true />
        <key>NSHighResolutionCapable</key>
        <true />
    </dict>
</plist>

实际上,Info.plist文件是来自工作应用程序qView的Info.plist文件的副本,可以使用brew install qview安装qView。
除此之外,我还可以单击捆绑包并通过单击打开应用程序。
我将应用程序复制到应用程序文件夹中,似乎Finder将其识别为可以打开图像文件的应用程序。

由于我不知道Finder中的参数是如何提供给我的应用程序的,我没有实现打开和显示图像的部分。我认为,这对MacOS来说不应该是一个问题,应该是?main. c看起来如下:

int main(int argc, char **argv)
{
    struct ApplicationContext *appContext = malloc(sizeof(appContext));
    GtkApplication *app;
    int status;

    app = gtk_application_new("net.bean.app", G_APPLICATION_HANDLES_OPEN);
    g_signal_connect(app, "activate", G_CALLBACK(activate), appContext);
    g_signal_connect(app, "open", G_CALLBACK(app_open), appContext);
    status = g_application_run(G_APPLICATION(app), argc, argv);
    g_object_unref(app);

    return status;
}

有人能告诉我为什么MacOS显示警告吗?
这是否与一些Macos的安全策略有关,这些策略禁止向未知应用程序打开文件?
谢谢你。

vltsax25

vltsax251#

只有.plist文件是不够的,还需要处理代码。
顺便说一下,对于常规的Cocoa Objective-C应用程序也是如此,如果没有实现相应的可选NSApplicationDelegate方法(如application:openURLs:),则会出现问题中的对话框。
对于GTK3应用程序,https://www.gtk.org/docs/installations/macos中有一些重要说明:
与GTK的Quartz后端连接可以将你的应用程序连接到Mac的本地显示管理器、键盘和指针设备。只需一点额外的代码和gtk-mac集成,你就可以:
...

  • 从Finder接收打开的事件。
  • ...
    • 小但完全独立的示例**

这是用GTK 3.24.36测试过的,对于GTK 4.x,它看起来肯定会有一点不同。

#include <gtk/gtk.h>
#include <assert.h>
#include <gtkosxapplication.h>

static  GtkWidget *
new_window(void) {
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    assert (window != NULL);
    gtk_widget_show_all(window);
    return window;
}

static gboolean
app_open_file_cb (GtkosxApplication *app, gchar *path, gpointer user_data) {
    printf("open file '%s'\n", path);
    //do sth with file
    return TRUE;
}

int main(int argc, char **argv) {
    gtk_init (&argc, &argv);
    GtkApplication *app  = g_object_new (GTKOSX_TYPE_APPLICATION, NULL);
    GtkWidget *window = new_window();
    g_signal_connect (app, "NSApplicationOpenFile",
                      G_CALLBACK (app_open_file_cb), NULL);
    gtkosx_application_ready (app);
    gtk_main ();
    g_object_unref(app);
    return 0;
}
    • CFBundleTypeExtensions已弃用**

这应该适用于您的.plist文件,但CFBundleTypeExtensions自OS X v10.5起已弃用。有关详细信息,请参阅https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
要查看.jpeg文件,您应该使用类似以下的命令:

<key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeName</key>
            <string>JPEG File</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSHandlerRank</key>
            <string>Alternate</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.jpeg</string>
            </array>
        </dict>
    </array>
    • 测试**

创建iViewGTK应用程序包后,您可以使用上面的测试程序运行一个快速测试-如果您从命令行运行它,您甚至可以在控制台上看到prinft的输出:

iViewGTK.app/Contents/MacOS/iViewGTK

在Finder中右键单击. jpeg文件并从上下文菜单中选择Open With/iViewGTK来打开文件时,将出现以下内容:

因此没有错误对话框,并且文件路径被成功传递给GTK应用程序。

相关问题