I needed to convert RGB colors to hex and did some Google research. I found two solutions that might be of use in an AppleScript and have included those below. In limited testing, both solutions returned the same result, and these were consistent with the values returned by an RGB-to-HEX web site. The AppleScript solution was fastest, taking a fraction of a millisecond.
I thought I would post these should a forum member have this need in the future. Also, I would appreciate being informed of any errors in the returned results or any alternative methods that might be available. Thanks.
set redColor to 1
set greenColor to 99
set blueColor to 199
-- AppleScript Solution
set hexValue to getHexValue({redColor, greenColor, blueColor})
on getHexValue(rgbValues)
set hexValue to ""
set hexNumbers to "0123456789ABCDEF"
repeat with anRGBValue in rgbValues
set hexValue to hexValue & character ((anRGBValue div 16) + 1) of hexNumbers & character ((anRGBValue mod 16) + 1) of hexNumbers
end repeat
return "#" & hexValue
end getHexValue
-- AppleScript Shell Solution
set shellHexValue to (do shell script "printf " & quoted form of "#%02X%02X%02X" & " " & redColor & " " & greenColor & " " & blueColor)
-- check results
hexValue & space & shellHexValue --> "#0163C7 #0163C7"
I think (((anRGBValue / 16 mod 1) * 16) + 1) can be reduced to (anRGBValue mod 16 + 1).
Also, since it’s a single character that’s indexed each time, conventional wisdom would suggest the use of the character keyword rather than text. But it makes no practical difference and text is certainly less to type!
I thought the same regarding text vs character (although I’m pretty sure that I’ve written scripts that use ‘character’ to get a single letter). The ASLG is kind of misleading here as it offers a poor example… from Class Reference - Text (p129):
[format]The result of a similar statement using the character element instead of the text element is a list:
get characters 3 thru 7 of “Try this at home”
–result: {“y”, " ", “t”, “h”, “i”}[/format]
Nice, straightforward applescript solution. I don’t think it will generate any incorrect results.
A minor variation on your shell script that uses text delimiters and relocates the ‘#’ to form a more succinct printf argument:
-- AppleScript Shell Solution
set redColor to 1
set greenColor to 199
set blueColor to 99
set rgbValues to {redColor, greenColor, blueColor}
set AppleScript's text item delimiters to space
set shellHexValue to "#" & (do shell script "printf '%02X' " & rgbValues as text)
-- printf '%02X' 1 199 99 -- actual shell command
--> "#01C763"
Thanks Mockman for looking at my scripts and for the script suggestion, which works great.
BTW, I noted above that the AppleScript solution took a fraction of a millisecond. However, the printf solution only took a bit over 3 milliseconds and might be preferred for its brevity.
But for you case you just simply need the NSString section (with integerValues)
(Just need to convert to AsObjC)
// Convert the numbers to hex strings
redHexValue=[NSString stringWithFormat:@"%02x", redIntValue];
greenHexValue=[NSString stringWithFormat:@"%02x", greenIntValue];
blueHexValue=[NSString stringWithFormat:@"%02x", blueIntValue];
// Concatenate the red, green, and blue components' hex strings together with a "#"
return [NSString stringWithFormat:@"#%@%@%@", redHexValue, greenHexValue, blueHexValue];
technomorph. Thanks for the suggestion. I’m not accomplished at converting Objective-C to ASObjC and couldn’t get the following to work:
use framework "Foundation"
set redColor to 1
# set redColor to current application's NSNumber's numberWithInteger:redColor
set greenColor to 99
# set greenColor to current application's NSNumber's numberWithInteger:greenColor
set blueColor to 199
# set blueColor to current application's NSNumber's numberWithInteger:blueColor
set redHex to current application's NSString's stringWithFormat_("%02x", redColor)
set greenHex to current application's NSString's stringWithFormat_("%02x", greenColor)
set blueHex to current application's NSString's stringWithFormat_("%02x", blueColor)
set hexValue to current application's NSString's stringWithFormat_("#%@%@%@", redHex, greenHex, blueHex) --> (NSString) "#2e26fbe32e2699e32e263de3"
-- or as an alternative
# set hexValue to current application's NSString's stringWithFormat_("#%02x%02x%02x", redColor, greenColor, blueColor) --> (NSString) "#2e26fbe32e2699e32e263de3"
also I think you can’t use a straight NSNumber
You should create intVariables
set intRed to redColor’s intValue
I tested it and for some reason the NSString stringWithFormat isn’t working:
I checked some old code I had and it was similar to using the do shell script
set greenColor to 99
set greenHexA to do shell script "perl -e 'printf(\"%02X\", " & greenColor & ")'"
from my tests the other users shell script was slightly faster 1ms
use framework "AppKit"
use framework "Foundation"
use scripting additions
-- classes, constants, and enums used
property NSColorSpace : a reference to current application's NSColorSpace
property NSColor : a reference to current application's NSColor
set aRed1 to 244
set aGreen1 to 199
set aBlue1 to 199
set aTestColor to NSColor's magentaColor()
set aHex1 to my getHexValueForRedColor:aRed1 greenColor:aGreen1 blueColor:aBlue1
# ---> "#F4C7C7"
set aHex2 to my getHexValueForNSColor:aTestColor
# ---> "#FB00FF"
set {aRed2, aGreen2, aBlue2} to my getColorIntValuesForNSColor:aTestColor
# ---> {251, 0, 255}
on getHexValueForRedColor:aRedInt greenColor:aGreenInt blueColor:aBlueInt
set hexValue to (do shell script "printf " & quoted form of "#%02X%02X%02X" & " " & aRedInt & " " & aGreenInt & " " & aBlueInt)
return hexValue
end getHexValueForRedColor:greenColor:blueColor:
on getHexValueForNSColor:aColor
set {aRedColor, aGreenColor, aBlueColor} to my getColorIntValuesForNSColor:aColor
return my getHexValueForRedColor:aRedColor greenColor:aGreenColor blueColor:aBlueColor
end getHexValueForNSColor:
on getColorIntValuesForNSColor:aColor
set aColorSpace to aColor's colorUsingColorSpace:(NSColorSpace's genericRGBColorSpace())
set aRedColor to ((aColorSpace's redComponent()) * 255) as integer
set aGreenColor to ((aColorSpace's greenComponent()) * 255) as integer
set aBlueColor to ((aColorSpace's blueComponent()) * 255) as integer
return {aRedColor, aGreenColor, aBlueColor}
end getColorIntValuesForNSColor:
# ALT slightly slower 1ms version
on getAltHexValueForRedColor:aRedInt greenColor:aGreenInt blueColor:aBlueInt
set hexValuePerl to do shell script "perl -e 'printf(\"#%02X%02X%02X\", " & aRedInt & ", " & aGreenInt & ", " & aBlueInt & ")'"
return hexValuePerl
end getAltHexValueForRedColor:greenColor:blueColor: