以编程方式从 iPhoto 图库中读取

发布于 2024-12-19 22:27:18 字数 442 浏览 2 评论 0原文

我想创建一个连接到 iPhoto 图库的应用程序。所以现在我想从图书馆阅读事件和图片本身。

有没有一种优雅/简单的方法来做到这一点,或者我是否必须手动读取 iPhoto 用户数据的捆绑结构?

到目前为止,我只找到了一个拍照器: Is there a UIImagePicker for the Mac 桌面

更新:我发现了另一个相关的 SO 帖子:在 cocoa 应用程序中选择 iPhoto 图像

I want to create an Application that connects to the iPhoto Library. So now I would like to read the Events and the pictures themselves from the library.

Is there an elegant / easy way to do this or do I have to manually read the Bundle Structure of the iPhoto User Data?

So far I have only found a picture taker: Is there a UIImagePicker for the Mac Desktop

Update: I found another relevant SO post: Selecting iPhoto images within a cocoa application

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

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

发布评论

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

评论(2

绝對不後悔。 2024-12-26 22:27:18

您可以使用 NSAppleScript 来完成。这是我的应用程序中的一些复制/粘贴,只是为了展示这个想法而进行了一些修改。

    NSAppleEventDescriptor d = .. compile this script ..
        @"tell application \"iPhoto\" to properties of albums"

    for (int i = 0; i < [d numberOfItems]; i++)
    {
        NSAppleEventDescriptor *albumDesc = [d descriptorAtIndex:i];

        // <NSAppleEventDescriptor: 'ipal'{ 
        //  'ID  ':4.265e+09, 
        //  'purl':'utxt'("http://www.flickr.com/photos/..."), 
        //  'pnam':'utxt'("Vacation"), 
        //  'alTy':'pubs', 
        //  'alCh':[  ], 
        //  'alPx':'msng' }>

        NSString *albumName = [[albumDesc descriptorForKeyword:'pnam'] stringValue];
        NSString *albumId = [[albumDesc descriptorForKeyword:'ID  '] stringValue];

您可以执行相同的操作来查找图像

NSString *scp = 
    [NSString stringWithFormat:@"tell application \"iPhoto\" to properties of photos of album id %@",
     [album objectForKey:@"id"]];

NSAppleEventDescriptor *d = ... compile scp ...

// 1 based!?
for (int i = 1; i <= [d numberOfItems]; i++)
{
    NSAppleEventDescriptor *photoDesc = [d descriptorAtIndex:i];

    // Yes.. this happens.  Not sure why?!
    if (!photoDesc)
        continue;

    // <NSAppleEventDescriptor: 'ipmr'{ 
    // 'pnam':'utxt'("IMG_0058.JPG"), 
    // 'pwid':768, 
    // 'pdim':[ 768, 1024 ], 
    // 'alti':1.79769e+308, 
    // 'filn':'utxt'("3133889525_10975ba071_b.jpg"), 
    // 'ipth':'utxt'("/Users/lagnat/Pictures/iPhoto Library/Masters/2010/11/10/20101110-002341/3133889525_10975ba071_b.jpg"), 
    // 'idat':'ldt '($F57C69C500000000$), 
    // 'rate':0, 
    // 'titl':'utxt'("IMG_0058.JPG"), 
    // 'phit':1024, 
    // 'itpt':'utxt'("/Users/lagnat/Pictures/iPhoto Library/Thumbnails/2010/11/10/20101110-002341/3133889525_10975ba071_b.jpg.jpg"), 
    // 'ID  ':4.295e+09, 
    // 'lati':'msng', 
    // 'pcom':'utxt'(""), 
    // 'opth':'utxt'("/Users/lagnat/Pictures/iPhoto Library/Masters/2010/11/10/20101110-002341/3133889525_10975ba071_b.jpg"), 
    // 'lngt':'msng', 
    // 'tiln':'utxt'("3133889525_10975ba071_b.jpg.jpg") }>

    NSString *path = [[photoDesc descriptorForKeyword:'ipth'] stringValue];
    NSString *imgname = [[photoDesc descriptorForKeyword:'pnam'] stringValue];

You can do it with NSAppleScript. This is some copy/paste from my app, hacked up a bit just to show the idea.

    NSAppleEventDescriptor d = .. compile this script ..
        @"tell application \"iPhoto\" to properties of albums"

    for (int i = 0; i < [d numberOfItems]; i++)
    {
        NSAppleEventDescriptor *albumDesc = [d descriptorAtIndex:i];

        // <NSAppleEventDescriptor: 'ipal'{ 
        //  'ID  ':4.265e+09, 
        //  'purl':'utxt'("http://www.flickr.com/photos/..."), 
        //  'pnam':'utxt'("Vacation"), 
        //  'alTy':'pubs', 
        //  'alCh':[  ], 
        //  'alPx':'msng' }>

        NSString *albumName = [[albumDesc descriptorForKeyword:'pnam'] stringValue];
        NSString *albumId = [[albumDesc descriptorForKeyword:'ID  '] stringValue];

You can do the same thing to find the images

NSString *scp = 
    [NSString stringWithFormat:@"tell application \"iPhoto\" to properties of photos of album id %@",
     [album objectForKey:@"id"]];

NSAppleEventDescriptor *d = ... compile scp ...

// 1 based!?
for (int i = 1; i <= [d numberOfItems]; i++)
{
    NSAppleEventDescriptor *photoDesc = [d descriptorAtIndex:i];

    // Yes.. this happens.  Not sure why?!
    if (!photoDesc)
        continue;

    // <NSAppleEventDescriptor: 'ipmr'{ 
    // 'pnam':'utxt'("IMG_0058.JPG"), 
    // 'pwid':768, 
    // 'pdim':[ 768, 1024 ], 
    // 'alti':1.79769e+308, 
    // 'filn':'utxt'("3133889525_10975ba071_b.jpg"), 
    // 'ipth':'utxt'("/Users/lagnat/Pictures/iPhoto Library/Masters/2010/11/10/20101110-002341/3133889525_10975ba071_b.jpg"), 
    // 'idat':'ldt '($F57C69C500000000$), 
    // 'rate':0, 
    // 'titl':'utxt'("IMG_0058.JPG"), 
    // 'phit':1024, 
    // 'itpt':'utxt'("/Users/lagnat/Pictures/iPhoto Library/Thumbnails/2010/11/10/20101110-002341/3133889525_10975ba071_b.jpg.jpg"), 
    // 'ID  ':4.295e+09, 
    // 'lati':'msng', 
    // 'pcom':'utxt'(""), 
    // 'opth':'utxt'("/Users/lagnat/Pictures/iPhoto Library/Masters/2010/11/10/20101110-002341/3133889525_10975ba071_b.jpg"), 
    // 'lngt':'msng', 
    // 'tiln':'utxt'("3133889525_10975ba071_b.jpg.jpg") }>

    NSString *path = [[photoDesc descriptorForKeyword:'ipth'] stringValue];
    NSString *imgname = [[photoDesc descriptorForKeyword:'pnam'] stringValue];
带刺的爱情 2024-12-26 22:27:18

如果在 App Store 上发布应用程序,您现在需要使用沙盒,这会阻止之前的 AppleScript 方法工作(iPhoto 应用程序启动,但返回空集)。

iPhoto 库由包含照片、数据库和 XML 文件的目录结构组成。内容随 iPhoto 的每个版本而变化,因此手动访问这些文件时要小心。

如果您只需要专辑详细信息,您可以解析文件AlbumData.xml。

如果您想要照片,您可以浏览Masters 文件夹。文件结构遵循日期而不是 iPhoto 中配置的集。

有关 iPhoto 图库内部结构的更多信息,请参见此处:
http://www.fatcatsoftware.com/iplm/Help/iphoto%20library %20internals.html

大多数数据库都是 SQLite 格式,因此可以通过 Objective C 以编程方式访问,不过您可以预期不同版本的数据库之间的架构会发生变化i照片。感兴趣的主要数据库是 Database/apdb 中的 Library.apdb 和 Properties.apdb。


如果您仍然想使用 Apple 脚本方法,这里是之前答案的一个版本,其中包含 Apple 脚本执行部分:

NSAppleScript *script = [[NSAppleScript alloc] initWithSource:@"tell application \"iPhoto\" to properties of albums"];
NSAppleEventDescriptor *d = [script executeAndReturnError:nil];

NSLog(@"photo library count: %ld", (long)[d numberOfItems]);

for (int i = 0; i < [d numberOfItems]; i++)
{
    NSAppleEventDescriptor *albumDesc = [d descriptorAtIndex:i];

    NSString *albumName = [[albumDesc descriptorForKeyword:'pnam'] stringValue];
    NSLog(@"%@", albumName);
}

If releasing apps on the App Store you are now required now required to use the Sandbox, this stops the previous AppleScript method from working (the iPhoto app launches but an empty set is returned).

iPhoto libraries consist of a directory structure containing photos, databases and XML files. The contents changes with each version of iPhoto so be careful if manually accessing these files.

If you just want the album details you can parse the file AlbumData.xml

If you would like photos you can browse the Masters folder. The files structure follows date rather than by the sets configured in iPhoto.

More information can be found on the internals of the iPhoto library here:
http://www.fatcatsoftware.com/iplm/Help/iphoto%20library%20internals.html

The majority of the databases are in SQLite format and so can be programmatically accessed through Objective C, though again you can expect schema changes between different versions of iPhoto. The main databases of interest are Library.apdb and Properties.apdb in Database/apdb.


If you still want to use the Apple Script method, here's a version of the previous answer with the Apple script execution part included:

NSAppleScript *script = [[NSAppleScript alloc] initWithSource:@"tell application \"iPhoto\" to properties of albums"];
NSAppleEventDescriptor *d = [script executeAndReturnError:nil];

NSLog(@"photo library count: %ld", (long)[d numberOfItems]);

for (int i = 0; i < [d numberOfItems]; i++)
{
    NSAppleEventDescriptor *albumDesc = [d descriptorAtIndex:i];

    NSString *albumName = [[albumDesc descriptorForKeyword:'pnam'] stringValue];
    NSLog(@"%@", albumName);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文