Использование Core Graphics для изменения профиля цветового пространства изображений с помощью AppleScriptObjC - PullRequest
0 голосов
/ 22 июня 2019

У меня уже есть некоторый код, который будет делать большую часть того, что мне нужно, используя NSIMage и NSColorSpace.К сожалению, я пытаюсь воссоздать изменение цветового пространства / профиля, которое происходит в Photoshop, и это немного сложнее, чем то, что может сделать NSColorSpace.Вы можете увидеть этот пост здесь: Использование ApplescriptObjC для преобразования цветовых пространств изображения с использованием NSColorSpace и iccProfileData

Так что мне нужна помощь, либо добавление следующего из CGColorSpace или воссоздание определенных частейсценария, чтобы они работали с самого начала с Core Graphics.Я хочу выполнить следующие функции: CGColorRenderingIntent с использованием kCGRenderingIntentPerceptual kCGColorConversionBlackPointCompensation Plus, использующий сглаживание как часть этого преобразования цветового пространства, но я не могу найти вариант для этого в документации Apple Objective-C.NSColor имеет NSColorRenderingIntentPerceptual, но не похоже, что есть BlackPointCompensation под NSColor.

Я думаю, что я определил все части, необходимые для создания этого скрипта.Я думаю, что сценарий уже частично написан.Мне просто нужна помощь, чтобы склеить последние несколько битов.

Я считаю, что скрипту все равно нужно будет открыть профиль в NSData (файл представляет собой ссылку на файл POSIX для профиля ICC, который я использую)

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.Мне также нужно внедрить эту строку или новую строку, CGColorRenderingIntent, используя kCGRenderingIntentPerceptual и kCGColorConversionBlackPointCompensation (с дизерингом, если эта опция вообще существует).

Я не уверен, нужно ли обновлять следующие две строки, но я уверен, что третья строка может остаться прежней (или я действительно глуп, простите меня).

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

Таким образом, входными данными будет RGB с универсальным файлом профиля sRGB, а выходными данными будет файл CMYK с определенным профилем CMYK (точнее GRACoL2013_CRPC6.icc).

1 Ответ

0 голосов
/ 24 июня 2019

На входе будет RGB с общим файлом профиля sRGB, а на выходе будет файл CMYK с определенным профилем CMYK (GRACoL2013_CRPC6.icc)

Если этоТочно суммируя цель, вы должны быть в состоянии сделать это, используя 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.Поэтому я, возможно, не предоставил вам ничего такого, что вы не могли бы сделать по сценарию.Однако я заметил, что цветовые профили GRACoL вызывают сбой механизма AppleScript, если кто-то пытается использовать их «как есть» после получения их с веб-сайта.По какой-либо причине профиль сначала должен быть открыт в ColorSync Utility.app , а затем сохранен ( Сохранить как ... ) или экспортирован ( Экспорт ... ).Хорошо перезаписать исходный файл, после чего у AppleScript появится контент для его использования.Похоже, что это не проблема с другими профилями, уже сохраненными в системе.

...