SFPSDWriter 0.3.1

SFPSDWriter 0.3.1

测试已测试
Lang语言 Obj-CObjective C
许可证 BSD
发布上次发布2014年12月

Konstantin Erokhin维护。



  • Shiny Frog

SFPSDWriter 是一个 Objective-C 库,用于写入 PSD 文件。在我们 Shiny Frog,我们需要一种方法来写入具有 多图层 的 PSD 文件,这个库是我们经过几天头痛后得到的结果。

它具有以下特点:

  • 创建多图层 PSD
  • 层分组
  • 支持 Unicode 层名
  • 一些层配置(如层的混合模式)
  • 图层和组的基准效果:阴影、内部阴影、外部发光、内部发光、斜面、实心填充
  • ARC(自动引用计数)

SFPSDWriter 不具备以下功能:

  • 读取 PSD 文件的能力

使用方法

简洁来说

  • 创建一个 SFPSDWriter 对象实例
  • 添加您想要的层数量
  • 最终修改层的属性
  • 如果您想要,添加一些层效果
  • 检索由 SFPSDWriter 生成的 NSData 并将其存储在您想要的位置

当然,一些代码

Mac OS X

    // The images we want to insert in the PSD
    NSImage *firstImage = [NSImage imageNamed:@"firstImage"];
    NSImage *secondImage = [NSImage imageNamed:@"secondImage"];

    // SFPSDWriter instance
    SFPSDWriter *psdWriter = [[SFPSDWriter alloc] initWithDocumentSize:NSSizeToCGSize(firstImage.size) andResolution:300.0 andResolutionUnit:SFPSDResolutionUnitPPI];

    // We want all our layers to be included in a group...
    SFPSDGroupOpeningLayer *firstGroup = [psdWriter openGroupLayerWithName:@"We ♥ groups!"];

    // ... and the group should be open at file opening
    [firstGroup setIsOpened:YES];

    // Adding the first image layer
    [psdWriter addLayerWithCGImage:[[[firstImage representations] objectAtIndex:0] CGImage]
                           andName:@"First Layer"
                        andOpacity:1
                         andOffset:NSMakePoint(0, 0)];

    // I mean, we really love groups
    // This time we don't need to change group's attributes so we don't store the reference
    [psdWriter openGroupLayerWithName:@"You'll have to open me!"];

    // The second image will be in the second group, offsetted by (116px, 66px), semi-transparent...
    SFPSDLayer *secondLayer = [psdWriter addLayerWithCGImage:[[[secondImage representations] objectAtIndex:0] CGImage]
                                                     andName:@"Second Layer"
                                                  andOpacity:0.5
                                                   andOffset:NSMakePoint(116, 66)];

    // ... and with "Darken" blend mode
    [secondLayer setBlendMode:SFPSDLayerBlendModeDarken];

    // We'll prepare the Drop Shadow Effect Layer information
    SFPSDDropShadowEffectLayerInformation *dropShadowInformation = [[SFPSDDropShadowEffectLayerInformation alloc] init];
    dropShadowInformation.enabled = YES;
    dropShadowInformation.size = 100;
    dropShadowInformation.angle = 90;
    dropShadowInformation.distance = 30;
    dropShadowInformation.color = [[NSColor redColor] CGColor];
    dropShadowInformation.blendMode = SFPSDLayerBlendModeNormal;
    dropShadowInformation.useGlobalLight = NO;
    dropShadowInformation.opacity = 100;

    // We'll set the Drop Sahdow on the second layer (we can add it to the SFPSDGroupOpeningLayer too)
    [secondLayer setDropShadowEffectLayerInformation:dropShadowInformation];

    // Other available Effect Layers are:
    // - Inner Shadow (SFPSDInnerShadowEffectLayerInformation)
    // - Outer Glow (SFPSDOuterGlowEffectLayerInformation)
    // - Inner Glow (SFPSDInnerGlowEffectLayerInformation)
    // - Bevel (SFPSDBevelEffectLayerInformation)
    // - Solid Fill (SFPSDSolidFillEffectLayerInformation)

    // We have to close every group we've opened
    [psdWriter closeCurrentGroupLayer]; // second group
    [psdWriter closeCurrentGroupLayer]; // first group

    // We can change the embedded color profile of the document (for example with an "sRGB IEC61966-2.1")
    [psdWriter setColorProfile:SFPSDSRGBColorProfile];

    // We'll write our test file to the Desktop
    NSString *basePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Desktop"];
    NSString *fullFilePath = [basePath stringByAppendingPathComponent:@"SFPSDWriter Test File.psd"];

    // Retrieving the PSD data
    NSError *error = nil;
    NSData * psd = [psdWriter createPSDDataWithError:&error];

    // Checking for errors
    if (nil != error) {
        NSLog(@"There was an error writing the PSD: %@", [error description]);
        return;
    }

    // Writing the data on disk
    [psd writeToFile:fullFilePath atomically:NO];

    // Opening the newly created file! :)
    [[NSWorkspace sharedWorkspace] openFile:fullFilePath];

iOS

    // The images we want to insert in the PSD
    UIImage *firstImage = [UIImage imageNamed:@"firstImage"];
    UIImage *secondImage = [UIImage imageNamed:@"secondImage"];

    // SFPSDWriter instance
    SFPSDWriter *psdWriter = [[SFPSDWriter alloc] initWithDocumentSize:firstImage.size andResolution:300.0 andResolutionUnit:SFPSDResolutionUnitPPI];

    // We want all our layers to be included in a group...
    SFPSDGroupOpeningLayer *firstGroup = [psdWriter openGroupLayerWithName:@"We ♥ groups!"];

    // ... and the group should be open at file opening
    [firstGroup setIsOpened:YES];

    // Adding the first image layer
    [psdWriter addLayerWithCGImage:[firstImage CGImage]
                           andName:@"First Layer"
                        andOpacity:1
                         andOffset:CGPointMake(0, 0)];

    // I mean, we really love groups
    // This time we don't need to change group's attributes so we don't store the reference
    [psdWriter openGroupLayerWithName:@"You'll have to open me!"];

    // The second image will be in the second group, offsetted by (116px, 66px), semi-transparent...
    SFPSDLayer *secondLayer = [psdWriter addLayerWithCGImage:[secondImage CGImage]
                                                     andName:@"Second Layer"
                                                  andOpacity:0.5
                                                   andOffset:CGPointMake(116, 66)];

    // ... and with "Darken" blend mode
    [secondLayer setBlendMode:SFPSDLayerBlendModeDarken];

    // We'll prepare the Drop Shadow Effect Layer information
    SFPSDDropShadowEffectLayerInformation *dropShadowInformation = [[SFPSDDropShadowEffectLayerInformation alloc] init];
    dropShadowInformation.enabled = YES;
    dropShadowInformation.size = 100;
    dropShadowInformation.angle = 90;
    dropShadowInformation.distance = 30;
    dropShadowInformation.color = [[UIColor redColor] CGColor];
    dropShadowInformation.blendMode = SFPSDLayerBlendModeNormal;
    dropShadowInformation.useGlobalLight = NO;
    dropShadowInformation.opacity = 100;

    // We'll set the Drop Sahdow on the second layer (we can add it to the SFPSDGroupOpeningLayer too)
    [secondLayer setDropShadowEffectLayerInformation:dropShadowInformation];

    // Other available Effect Layers are:
    // - Inner Shadow (SFPSDInnerShadowEffectLayerInformation)
    // - Outer Glow (SFPSDOuterGlowEffectLayerInformation)
    // - Inner Glow (SFPSDInnerGlowEffectLayerInformation)
    // - Bevel (SFPSDBevelEffectLayerInformation)
    // - Solid Fill (SFPSDSolidFillEffectLayerInformation)

    // We have to close every group we've opened
    [psdWriter closeCurrentGroupLayer]; // second group
    [psdWriter closeCurrentGroupLayer]; // first group

    // We can change the embedded color profile of the document (for example with an "sRGB IEC61966-2.1")
    [psdWriter setColorProfile:SFPSDSRGBColorProfile];

    // We'll write our test file into the documents folder of the application
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *fullFilePath = [documentsDirectory stringByAppendingPathComponent:@"SFPSDWriter Test File.psd"];

    // Retrieving the PSD data
    NSError *error = nil;
    NSData * psd = [psdWriter createPSDDataWithError:&error];

    // Checking for errors
    if (nil != error) {
        NSLog(@"There was an error writing the PSD: %@", [error description]);
        return;
    }

    // Writing the data on disk
    // When using the simulator we can find the file in
    // /Users/<Username>/Library/Application\ Support/iPhone\ Simulator/<Simulator Version>/Applications/<Application>/Documents
    [psd writeToFile:fullFilePath atomically:NO];

示例项目

示例项目是 使用方法 部分中的代码的复制和粘贴

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification // Mac OS X

- (void)applicationDidBecomeActive:(UIApplication *)application // iOS

还有一个用于压力测试库的调试项目。您可以在 Example Projects/SFPSDWriter Stress Tester 中找到它。

状态

库已满足我们的需求,因此没有计划对其做进一步的改进。显然,如果我们找到一些问题,我们会解决问题或加快速度。

目前没有计划让这个库能够读取 PSD 文件。或者更确切地说:有一个具体的计划不让这个库读取 PSD 文件。

在此,我想邀请您阅读这个 著名的评论,让您了解与 PSD 文件工作意味着什么。必须承认,我觉得这个评论很有激励性,但我是个变态。如果可以的话,不要玩 PSD 文件。 :)

贡献

我们很乐意评估接受拉取请求的可能性,如果您有任何建议欢迎告诉我们。

致谢

此库受到了来自Ben GotowPSDWriter的启发。它在结构上进行了一些重组,将信息的编写和通道委托给层,并在这里和那里增加了一些内容。

如果没有Gus Mueller@ccgus)提供的一些专业技巧,此库将无法实现!这些技巧讲述了PSD组的神秘行为。