使用Core Graphics通过AppleScriptObjC

时间:2019-06-22 06:33:36

标签: core-graphics nsimage applescript-objc cgcolorspace

我已经有一些代码可以使用NSIMage和NSColorSpace满足我的大部分需求。不幸的是,我试图重新创建在Photoshop中发生的色彩空间/配置文件更改,这比NSColorSpace可以完成的操作要复杂得多。您可以在这里看到该帖子: Using ApplescriptObjC to convert color spaces of an image using NSColorSpace and iccProfileData

所以我需要帮助的是从CGColorSpace中添加以下内容,或者重新创建脚本的某些部分,以便它们从Core Graphics开始就可以使用。我要完成的功能是: 使用kCGRenderingIntentPerceptual的CGColorRenderingIntent kCGColorConversionBlackPointCompensation 加上将抖动作为此颜色空间转换的一部分,但是我似乎在Apple Objective-C文档中找不到用于此的选项。 NSColor确实具有NSColorRenderingIntentPerceptual,但在NSColor下似乎没有BlackPointCompensation。

我想我已经确定了构建此脚本所需的所有部分。我认为该脚本已经编写了一半。我只需要一些帮助将最后几位粘合在一起。

我相信该脚本仍需要将配置文件打开到NSData中(该文件是我正在使用的ICC配置文件的POSIX文件引用)

set theData to current application's NSData's dataWithContentsOfFile:theFile

现在我需要打开图像,我希望无论使用NSColor还是CGColor都一样:

set theInput to (choose file with prompt "Choose RGB file")
set theOutput to (choose file name default name "Untitled.jpg")
set theImage to current application's NSImage's alloc()'s initWithContentsOfURL:theInput
set imageRep to theImage's representations()'s objectAtIndex:0

这是我最需要帮助的代码行。实际上,这是使用NSColorSpace进行颜色转换的地方:

set targetSpace to current application's NSColorSpace's alloc's initWithICCProfileData:theData

似乎我应该将CGColorSpaceCreateICCBased与CGDataProviderRef一起使用,然后再使用theFile,但是我怀疑我是否可以将它们替换为NSColorSpace和initWithICCProfileData。我还需要使用kCGRenderingIntentPerceptual和kCGColorConversionBlackPointCompensation(如果存在该选项,则使用抖动)将CGColorRenderingIntent移植到此行或新行中。

我不确定接下来的两行是否需要更新,但是我很确定第三行可以保持不变(或者我真的很愚蠢,请原谅我)。

set theProps to current application's NSDictionary's dictionaryWithObjects:{1.0, true} forKeys:{current application's NSImageCompressionFactor, current application's NSImageProgressive}
set jpegData to bitmapRep's representationUsingType:(current application's NSJPEGFileType) |properties|:theProps
jpegData's writeToURL:theOutput atomically:true

因此,输入将是具有通用sRGB配置文件的RGB,而输出将是具有特定CMYK配置文件(准确地说是GRACoL2013_CRPC6.icc)的CMYK文件。

1 个答案:

答案 0 :(得分:0)

  

输入将是具有通用sRGB配置文件的RGB,输出将是具有特定CMYK配置文件(GRACoL2013_CRPC6.icc)的CMYK文件

如果这能准确地概括出目标,则您应该能够使用 Image Events (这是一个AppleScriptable不露面程序来处理图像)进行此操作。

玩过图像事件,但是似乎并不需要嵌入新的颜色配置文件(应该有可能),并且仍然保留原始颜色配置文件。

所以我写了等效的AppleScriptObjC:

use framework "Foundation"
use framework "AppKit"
use scripting additions

property this : a reference to the current application
property nil : a reference to missing value
property _1 : a reference to reference

property NSBitmapImageRep : a reference to NSBitmapImageRep of this
property NSColorSpace : a reference to NSColorSpace of this
property NSData : a reference to NSData of this
property NSImage : a reference to NSImage of this
property NSString : a reference to NSString of this
property NSURL : a reference to NSURL of this

property JPEG : a reference to 3
property PNG : a reference to 4
property NSFileType : {nil, nil, "jpg", "png"}
property options : {NSImageCompressionFactor:0.75, NSImageProgressive:true ¬
    , NSImageColorSyncProfileData:a reference to iccData}

property NSColorRenderingIntent : {Default:0, AbsoluteColorimetric:1 ¬
    , RelativeColorimetric:2, Perceptual:3, Saturation:4}
--------------------------------------------------------------------------------
# IMPLEMENTATION:
set iccProfile to loadICCProfile("~/Path/To/GRACoL2013_CRPC6.icc")
set image to _NSImage("~/Path/To/SourceImage.jpg")
set path of image to "~/Path/To/OutputImage.jpg" -- omit to overwrite source
set iccData to iccProfile's space's ICCProfileData()

my (write image for iccProfile given properties:contents of options)
--------------------------------------------------------------------------------
# HANDLERS & SCRIPT OBJECTS:
# __NSURL__()
#   Takes a posix +filepath and returns an NSURL object reference
to __NSURL__(filepath)
    local filepath

    try
        NSURL's fileURLWithPath:((NSString's ¬
            stringWithString:filepath)'s ¬
            stringByStandardizingPath())
    on error
        missing value
    end try
end __NSURL__

# new()
#   Instantiates a new NSObject
on new(_nsObject)
    local _nsObject
    _nsObject's alloc()
end new

# _NSImage()
#   Creates a new NSImage instance with image data loaded from the +filepath
on _NSImage(filepath)
    local filepath

    script
        property file : __NSURL__(filepath)
        property data : new(NSImage)
        property kind : JPEG
        property path : nil -- write path (nil = overwrite source)
        property size : nil
        property name extension : NSFileType's item kind

        to init()
            my (data's initWithContentsOfURL:(my file))
        end init

        to lock()
            tell my data to lockFocus()
        end lock

        to unlock()
            tell my data to unlockFocus()
        end unlock
    end script

    tell the result
        init()
        set its size to its data's |size|() as list
        return it
    end tell
end _NSImage

# ICCProfile()
#   Loads a ColorSync profile from the +filepath and creates a new NSColorSpace
#   instance 
to loadICCProfile(fp)
    local fp

    script
        property file : __NSURL__(fp)
        property data : NSData's dataWithContentsOfURL:(my file)
        property space : new(NSColorSpace)
        property mode : NSColorRenderingIntent's Perceptual

        to init()
            (my space)'s initWithICCProfileData:(my data)
        end init
    end script

    tell the result
        init()
        return it
    end tell
end loadICCProfile

# write
#   Writes out the +_NSImage data optionally converting it to a new colorspace
to write _NSImage for ICC : missing value ¬
    given properties:(opt as record) : missing value
    local _NSImage, ICC, kind, path, options


    set ImageRep to new(NSBitmapImageRep)

    _NSImage's lock()

    ImageRep's initWithFocusedViewRect:{{0, 0}, _NSImage's size}
    ImageRep's bitmapImageRepByConvertingToColorSpace:(ICC's space) ¬
        renderingIntent:(ICC's mode)
    result's representationUsingType:(_NSImage's kind) |properties|:opt
    set ImageRep to the result

    _NSImage's unlock()


    set fURL to __NSURL__(_NSImage's path)
    if fURL = missing value then set fURL to NSImage's file
    set ext to _NSImage's name extension
    if fURL's pathExtension() as text ≠ ext then ¬
        fURL's URLByDeletingPathExtension()'s ¬
        URLByAppendingPathExtension:ext

    ImageRep's writeToURL:fURL atomically:yes
    if the result = true then return fURL's |path|() as text
    false
end write
---------------------------------------------------------------------------❮END❯

如您所述,转换颜色空间时,Core Graphics的kCGColorConversionBlackPointCompensation似乎没有等效的Foundation类选项。因此,我可能没有为您提供任何脚本功能,而您还无法做到。但是,我观察到的是,如果 GRACoL 颜色配置文件从网站上获取后,如果尝试按原样使用它们,则会导致AppleScript引擎崩溃。无论出于何种原因,必须首先在 ColorSync Utility.app 中打开配置文件,然后将其保存(另存为... )或将其导出(导出。 )。覆盖原始文件就可以了,之后AppleScript会显示使用它的内容。对于已经保存在系统中的其他配置文件,这似乎不是问题。