Does anyone knows how to get a list of the current loaded ICC profiles.
In the past this could be done using the colorsyncScripting application which was included in the OS.
This application has now been removed.
Is there an alternative within the objective-c frameworks/ASOC to get information about icc profiles in general.
Thanks Shane.
I indeed was using : current application’s NSColorSpace’s availableColorSpacesWithModel_(-1)
This works but the only problem is that I do not get all the profile types as colorsyncscripting did.
I compared the output of the two methods and there is a difference.
I think the ASOC way does not see profiles of type input and some other types too.
This is a beginning but it should be nice to have a good replacement for the colorsyncscripting app.
I did, the drawbacks are performance and the way the system loads the profiles (folder depths within the /Profiles/ directory, and the use of aliases (links) to other locations.
Listing is fast enough but the further handling to get the internal names of the profiles and excluding duplicates (from the internal names) makes the processing time take longer.
On my system ( a recent MacBook Pro) it takes about 8 seconds.
Here I have the code, maybe you have other suggestions about getting more performance. or using other methods.
Thanks
-- KDGetprofiles.applescript
script KDGetprofiles
property parent : class "NSObject"
on getLoadedProfiles()
try
set starttime to time of (current date)
-- Get all profile locations
set paths to NSSearchPathForDirectoriesInDomains(current application's NSLibraryDirectory, current application's NSAllDomainsMask, true) as list
set profilesPath to current application's NSString's stringWithString_("/Colorsync/Profiles/")
repeat with i from 1 to (count paths)
set cur_path to (item i of paths) as string
set fullpath to (cur_path & profilesPath) as string
set item i of paths to fullpath
end repeat
-- list all profiles
set laptime1 to time of (current date)
set all_profiles to {}
repeat with i from 1 to (count paths)
set profile_location to item i of paths
set {cur_profiles, cur_folders} to getProfilesFromLocation_(profile_location)
set all_profiles to all_profiles & cur_profiles
repeat with j from 1 to (count cur_folders)
set cur_folder to (item j of cur_folders) as string
set {cur_profile_list, cur_folder_list} to getProfilesFromLocation_(cur_folder)
if cur_profile_list is false then error cur_folder_list
if cur_profile_list is not {} then set all_profiles to all_profiles & cur_profile_list
end repeat
end repeat
-- get internal profile names
set laptime2 to time of (current date)
set {internal_names, color_spaces, not_duplicate_indexes} to getInternalProfileNameFromList_(all_profiles)
-- get unique names
set laptime3 to time of (current date)
set {profileNames, profileSpaces, profilePaths} to {{}, {}, {}}
repeat with i from 1 to (count not_duplicate_indexes)
set cur_index to (item i of not_duplicate_indexes)
set end of profileNames to item cur_index of internal_names
set end of profilePaths to item cur_index of all_profiles
set end of profileSpaces to item cur_index of color_spaces
end repeat
set laptime4 to time of (current date)
set stoptime to time of (current date)
log "get locations " & laptime1 - starttime
log "list all profiles " & laptime2 - laptime1
log "get internal names " & laptime3 - laptime2
log "remove duplicates " & laptime4 - laptime3
log "Total time is " & stoptime - starttime
log (count all_profiles)
log (count profileNames)
log (count profilePaths)
log profileNames
log profilePaths
log profileSpaces
return {stoptime - starttime, profileNames, profilePaths, profileSpaces}
on error errmsg
log "main " & errmsg
return false
end try
end getLoadedProfiles
on getProfilesFromLocation_(cur_path)
try
set cur_path to cur_path as string
set folderlist to {}
set profileList to {}
set localFileManager to current application's NSFileManager's alloc()'s init()
set localWorkspace to current application's NSWorkspace's alloc()'s init()
set cur_list to localFileManager's contentsOfDirectoryAtPath_error_(cur_path, missing value)
if cur_list is missing value then
set cur_list to {}
else
set cur_list to cur_list as list
repeat with j from 1 to (count cur_list)
if (item j of cur_list) is not in {missing value, ".DS_Store"} then
set cur_item to (cur_path & (item j of cur_list) as string) as string
set {itemExists, isFolder} to localFileManager's fileExistsAtPath_isDirectory_(cur_item, reference)
if (isFolder as boolean) and (itemExists as boolean) then
set end of folderlist to (cur_item & "/") as string
else
-- is file
set {didFindIt, appPath, theExtension} to localWorkspace's getInfoForFile_application_type_(cur_item, reference, reference)
set isProfile to ((appPath as string) contains "Colorsync") or ((theExtension as string) is in {"icc", "icm", "pf"}) as boolean
if isProfile then set end of profileList to cur_item as string
end if
end if
end repeat
end if
localFileManager's release()
localWorkspace's release()
return {profileList, folderlist}
on error errmsg
log "getProfilesFromLocation_ " & errmsg
try
localFileManager's release()
localWorkspace's release()
end try
return {false, errmsg}
end try
end getProfilesFromLocation_
on getInternalProfileNameFromList_(all_profiles)
set all_description_names to {}
set color_spaces to {}
set notDuplicates to {}
repeat with i from 1 to (count all_profiles)
set cur_item to (item i of all_profiles) as string
set theResult to paragraph 2 of (do shell script "sips -g description " & quoted form of cur_item)
set theString to current application's NSString's stringWithString_(theResult as string)
set parsedItems to theString's componentsSeparatedByString_((" " & "description" & ": "))
set cur_description_name to (item 2 of parsedItems) as string
if cur_description_name is not in all_description_names then
set end of notDuplicates to i
end if
set end of all_description_names to cur_description_name
try
set theResult to paragraph 2 of (do shell script "sips -g space " & quoted form of cur_item)
set theString to current application's NSString's stringWithString_(theResult as string)
set parsedItems to theString's componentsSeparatedByString_((" " & "space" & ": "))
set cur_color_space to (item 2 of parsedItems) as string
set end of color_spaces to cur_color_space
on error errmsg
log "getInternalProfileNameFromList_ " & errmsg
set end of color_spaces to "missing value"
end try
end repeat
return {all_description_names, color_spaces, notDuplicates}
end getInternalProfileNameFromList_
end script
Well your logs show where the time is being taken, and thus where to focus. As a general comment, things like this:
set theString to current application's NSString's stringWithString_(theResult as string)
set parsedItems to theString's componentsSeparatedByString_((" " & "description" & ": "))
set cur_description_name to (item 2 of parsedItems) as string
are pretty inefficient. Going from text to NSString and back to text for something text item delimiters can do may well be costing you time. But if you do go to NSString, you might want to stay in Cocoa classes, and use an NSMutableArray and addObject_ rather than “set end of list…”.
Hi Shane,
Thanks again for your reaction. It’s a good feeling when learning new things all the time.
I suddenly remembered that the “Image Events.app” from /System/Library/CoreServices/ is still there while ColorSyncScripting.app has been removed.
With the Image Events.app I can do things from the ColorSync and from the sips applications.
After some tests I have now the result I wanted with performance. With the image events I can get all the properties of the profiles from the internal names (description) whenever needed.
Here is the strongly reduced code need.
Again thanks for your support.
script KDGetprofiles
property parent : class "NSObject"
on getLoadedProfiles()
try
set starttime to time of (current date)
set stoptime to time of (current date)
set {unique_profile_names, unique_profile_locations} to getProfiles()
set stoptime to time of (current date)
log "done in "&stoptime-starttime
return {stoptime - starttime, unique_profile_names, unique_profile_locations, {}}
on error errmsg
log "main " & errmsg
return false
end try
end getLoadedProfiles
on getProfiles()
set unique_profile_names to {}
set unique_profile_locations to {}
tell application "Image Events"
set all_profile_names to name of profiles
set all_profile_locations to POSIX path of location of profiles
repeat with i from 1 to (count all_profile_names)
set cur_profile_name to item i of all_profile_names
if cur_profile_name is not in unique_profile_names then
set end of unique_profile_names to cur_profile_name
set end of unique_profile_locations to item i of all_profile_locations
end if
end repeat
end tell
return {unique_profile_names, unique_profile_locations}
end getProfiles
end script