How I created a set of Pantone swatches for the Mac OSX color picker

For a long time now I have wanted to have a full set of Pantone swatches in the Mac OSX color picker. I searched for a quick solution online but never found anything. So in the end I realised that if this was going to happen I would have to do something about it myself…

Pantone Swatches
Pantone Swatches in the Mac OSX Color Picker

Stage 1 – getting a list of swatches

Whilst it’s very easy to create a custom color palette and add your own colors to it I had no particular desire to try and enter an entire Pantone swatch book by hand. A quick search online revealed several sites with lists of swatches and their respective rgb values. So that’s great – the difficult part has already been done by someone else! I checked out a few lists and in the end settled on this one: http://en.labelpartners.com/pantone_coated_table.html which gave a full set with hex and rgb values laid out in a <table> just perfect for scraping with php.

Stage 2 – scraping the data into a database

The next task was to get the data off the webpage and into a database. For tasks like this I always use PHP Simple HTML DOM Parser. It’s very easy to learn – and makes this kind of task very simple.

Before writing a script to scrape the data I set up a myqsl database ‘pantone_swatches’ with a table ‘coated_swatches’ to hold the data. The table structure was as follows:


CREATE TABLE `coated_swatches` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  `hex` varchar(7) DEFAULT NULL,
  `red` varchar(5) DEFAULT NULL,
  `green` varchar(5) DEFAULT NULL,
  `blue` varchar(5) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

At this point I wasn’t really sure if I needed the rgb values or the hex values so I decided to get everything just in case.

Now, with the database ready it was time to scrape the data. I wrote the following php script making use of PHP Simple HTML DOM Parser to sort through each table row (<tr>) and get the text content from each table data cell (<td>) and inset as a row in the database:


//connect to mysql...
$user="root";
$host="localhost";
$password="YOUR_PASSWORD_HERE";
$database="pantone_swatches";
$table="coated_swatches";
$cxn = mysqli_connect ($host, $user, $password, $database)
or die (mysqli_error($cxn));

//include simple html dom...
require('simple_html_dom.php');

//get page source...
$html = file_get_html('http://en.labelpartners.com/pantone_coated_table.html');

$count = 0;

//loop through each <tr>...
foreach($html->find('tr') as $row) {

	//extract values from each <td>...    
	$name 	= $row->find('td', 0)->innertext;		
	$hex 	= $row->find('td', 1)->innertext;
	$red 	= $row->find('td', 2)->innertext;
	$green 	= $row->find('td', 3)->innertext;
	$blue 	= $row->find('td', 4)->innertext;
	
	//ignore <table> 'header' row...
	if($count > 0) {
	
		echo $count.': '.$name.'<br>';
		
		//inset in to db...
		$query="
			INSERT INTO
			$table
			(name, hex, red, green, blue)
			VALUES
			('$name', '$hex', '$red', '$green', '$blue')
		";
		
		$result = mysqli_query ($cxn,$query) or die (mysqli_error($cxn));		
	}
	
	$count++;
}

Once the script was ready I launched it and waited for it to complete then checked out the new table to see if everything was OK. The script performed perfectly but now, how to get those values into the Mac OSX color picker?

Stage 3 – building a list of NSColors

You can manually create a custom color palette by opening the color picker, clicking on the third tab ‘color palettes’ and then clicking on the small ‘gear’ icon and selecting ‘new’. When you do this the new palette is saved in ~/Library/Colors/ with .clr for its file extension. The first thing I tried to do was open one of these .clr files in a text editor. Once I had tried that I quickly realised it wasn’t as simple as copying the structure and saving a new file! So, back to the internet and a bit more research revealed a way to generate a .clr file using Xcode. .clr files can be generated by creating a new NSColorList object and setting colors, like this:


//create list
NSColorList *list = [NSColorList.alloc initWithName:@"My Custom Color Palette"];

//add colors
[list setColor:[NSColor colorWithRed:0.831 green:0.835 blue:0.831 alpha:1.0] forKey:@"Custom Color 1"];
[list setColor:[NSColor colorWithRed:0.765 green:0.773 blue:0.769 alpha:1.0] forKey:@"Custom Color 2"];
[list setColor:[NSColor colorWithRed:0.725 green:0.733 blue:0.733 alpha:1.0] forKey:@"Custom Color 3"];

//save file to ~/Library/Colors/
[list writeToFile: [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Colors/"]];

So now, all I needed to do was generate the objective-c code from the data in the database, the only difference being that the rgb values in the database range from 0 to 255 whereas the rgb values for the NSColor class range from 0 to 1. This small difference was rectified by dividing the database rgb values by 255 and rounding the result to 3 decimal places. The code I used to output the objective-c code was as follows:


//connect to mysql...
$user="root";
$host="localhost";
$password="YOUR_PASSWORD_HERE";
$database="pantone_swatches";
$table="coated_swatches";
$cxn = mysqli_connect ($host, $user, $password, $database)
or die (mysqli_error($cxn));

//get data...
$query = "SELECT * FROM $table";
$result = mysqli_query ($cxn,$query)
		or die (mysqli_error($cxn));
		
$nrows = mysqli_num_rows ($result);

//loop through data...
for($i=0;$i<$nrows;$i++) {

	$row = mysqli_fetch_assoc ($result);
	extract ($row);
	
	//divide rgb values by 255 and echo...
	echo '[list setColor:[NSColor colorWithRed:'.round(($red/255),3).' green:'.round(($green/255),3).' blue:'.round(($blue/255),3).' alpha:1.0] forKey:@"Pantone '.$name.'"];<br />';	
}

Which when executed produced the following result:


[list setColor:[NSColor colorWithRed:0.996 green:0.867 blue:0 alpha:1.0] forKey:@"Pantone Yellow C"];
[list setColor:[NSColor colorWithRed:1 green:0.843 blue:0 alpha:1.0] forKey:@"Pantone Yellow 012 C"];
[list setColor:[NSColor colorWithRed:0.996 green:0.314 blue:0 alpha:1.0] forKey:@"Pantone Orange 021 C"];
// etc…
// etc…
// etc…

Stage 4 – using Xcode to generate the .clr file

To generate the final .clr file I opened Xcode and created a new project of type Cococa Application. Once this was ready I opened the AppDelegate.m file and where the comment ‘// Insert code here to initialize your application’ appeared in the – (void)applicationDidFinishLaunching:(NSNotification *)aNotification method I replaced it with the following:


NSColorList *list = [NSColorList.alloc initWithName:@"Pantone Coated"];

/* COPY AND PASTE THE GENERATED LIST OF COLORS HERE */

[list writeToFile: [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Colors/"]];

Once that was done I did a build and run and as soon as the application had launched I checked out the contents of my ~/Library/Colors/ folder to see a new Pantone Coated.clr file. The next thing to do was open an app (Sketch.app) and then open the color picker to check out the new color palette!

Pantone In Sketch
Using Pantone swatches in Sketch

Conclusion

In hindsight the way I went about this was perhaps more lengthy that it could have been. There’s no reason why I couldn’t scrape the page and generate the objective-c code all in one step missing out the database. But as I was not sure how to proceed it seemed better to store the data then work out what to do next. Anyway here’s a short example that does just that:


//include simple html dom...
require('simple_html_dom.php');

//get page source...
$html = file_get_html('http://en.labelpartners.com/pantone_coated_table.html');

$count = 0;

echo 'NSColorList *list = [NSColorList.alloc initWithName:@"Pantone Coated"];';

//loop through each <tr>...
foreach($html->find('tr') as $row) {

	//extract values from each <td>...    
	$name 	= $row->find('td', 0)->innertext;		
	$hex 	= $row->find('td', 1)->innertext;
	$red 	= $row->find('td', 2)->innertext;
	$green 	= $row->find('td', 3)->innertext;
	$blue 	= $row->find('td', 4)->innertext;
	
	//ignore <table> 'header' row...
	if($count > 0) {
	
		//divide rgb values by 255 and echo objective-c code...
		echo '[list setColor:[NSColor colorWithRed:'.round(($red/255),3).' green:'.round(($green/255),3).' blue:'.round(($blue/255),3).' alpha:1.0] forKey:@"Pantone '.$name.'"];<br />';
			
	}
	
	$count++;
}

echo '[list writeToFile: [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Colors/"]];';

There are many sites online with lists of Pantone colors. I also creates a Pantone Pastels, Pantone Metallics and a set of CMYK swatches using the CMYK values and creating the NSColors like this:


[NSColor colorWithDeviceCyan: C_VALUE magenta: M_VALUE yellow: Y_VALUE black: K_VALUE alpha:1.0]

resources

Color Lists
http://en.labelpartners.com/pantone_coated_table.html
http://euro-bags.eu/pantone?limit=all
http://www.ediy.co.nz/pantone-to-rgb
http://www.umsiko.co.za/links/color.html
http://color2u.cocolog-nifty.com/color4u/archives.html
PHP Simple HTML DOM Parser
http://simplehtmldom.sourceforge.net

 

You can download an archive of compiled .clr containing a set of Pantone Coated, Metallic, Pastel and CMYK swatches on my resources page:
Pantone Swatches for the OSX Color Picker