What a lot of acronyms. We want to automate converting colour spaces in a web app. It's not easy.

CMYK, RGB and PHP

04 July 2006 - PHP

Brighter by the dozenA month or so ago, we were putting the finishing touches to the Lena White website, which sells OPI nail lacquer, among other things.

Lacquer is all about colour, so we wanted to give shoppers a way to quickly and visually browse all the available colours with colour swatches, rather than the more traditional product shot route. This makes particular sense because all lacquer bottles look pretty much the same, photos of them give a poor impression of the actual colour, and they take up way more screen estate than is helpful to anyone.

Swatches

You can see how the swatches look on the left, or in context here, compared to a screen where we were forced to use product shots here.

Getting hold of standardised colour information for the products was nigh on impossible. After a week or so of tracking and calls to the US, Japan, UK and back the only information we were able to collect was rough CMYK data used to print colour approximations. We needed to translate all these colours into RGB, to display on-screen.

The trouble with CMYK

RGB - CMYKIf you know about CMYK, you'll understand what a problem this is.

In standard 4-colour printing, four plates are created, one for each of Cyan, Magenta, Yellow and Key (which is black). Each plate is printed to the paper in turn, leaving dots of colour on the page. When viewed up close, you can see these quite clearly. When viewed from a normal reading distance, the colour dots mix like paint to form the myriad other colours you can see.

The trouble with CMYK is it's pretty rough. The technique is only capable reproducing some 60 or 70% of 16.7 million colours visible to the human eye, and which we can display on a computer screen. The RGB model can represent every one of these colours, and therefore every colour that CMYK can represent; but the converse is not true. The diagram on the right shows some of CMYK's closest approximations to some bright screen colours.

By starting with an inaccurate source, our RGB colours would never be particularly accurate, which can be a real problem on a website selling a colour-oriented product - particularly where many of the colours, such as red lacquers, are quite similar in the first place.

Converting CMYK to RGB - pass 1

Nevertheless, this is what we had to work with, so we decided to press on and convert the colours. Rather than spending an age droppering and converting in PhotoShop, I decided to write a quick PHP function to handle the job.

Well. I assumed I could write a quick PHP function to do the job.

A little internet research - and I apologise, I don't remember my sources here - turned up a couple of techniques that looked promising. Here's one, translated into PHP:

/**
* @param int $c
* @param int $m
* @param int $y
* @param int $k
* @return object
*/
function cmyk_to_rgb($c, $m, $y, $k)
{
$r = 255 - round(2.55 * ($c+$k)) ;
$g = 255 - round(2.55 * ($m+$k)) ;
$b = 255 - round(2.55 * ($y+$k)) ;

if($r<0) $r = 0 ;
if($g<0) $g = 0 ;
if($b<0) $b = 0 ;

$o->r = $r ;
$o->g = $g ;
$o->b = $b ;

return $o ;
}

Taking four integers as arguments, this function returns an object with the properties r, g, b, which can be fairly easily converted into hex for web use.

So, how does it work? 255 is the maximum value for any of R, G or B. When all three are set to 255, the colour produced is white, because RGB is an additive colour model. When all three are at 0, the colour is black.

By contrast, CMYK is a subtractive colour model, and the maximum for each value is 100, meaning 100%. The percentage here is - I think - of ink coverage: 50% Cyan means the dots of cyan ink cover 50% of that area, leaving the rest clear. Please correct me if I am wrong on this.

In RGB, you mix up a pure cyan using 100% blue and 100% green - or 0,255,255. Similarly, a pure magenta is red and blue - 255,0,255 - and a pure yellow is red and green - 255,0,255.

If we assume that this cyan, magenta and yellow are the same as the cyan, magenta and yellow of CMYK; and the amount of this cyan, magenta and yellow is inversely proportional to the K value in CMYK (because RGB is additive) - all we need is a little arithmetic to carry out the transformations, which is what's happening above. (Although not being a mathematician, I'm stuck on explaining it).

Pass 1 results

Sounds cool. Here is the result, comparing some original CMYK swatches to the results generated by this function, along with Adobe Illustrator's conversions for comparison.


Pass 1 results

For some purposes, this is jsut fine. But not for nail lacquer - the colours are just way to bright. Yet you can see the maths and logic in the colour codes, if you compare the raw CMYK to the function output. Conversely, the colour codes in Illustrator's conversions make little sense, but the colours are just right.

What's going on? Phyiscally, RGB can represent every CMYK colour, so what's the problem?

CMYK to RGB - pass 2: Voisen.org

Like many of these things, we started to run out of time. We just had to get this issue solved, and press on with other areas of the site. We were already unhappy to be starting with a CMYK source. We were doubly unhappy not to have an easy to convert this data. We decided to go back to square one and dropper the colours in PhotoShop. We launched the website, and now it's doing great, and we have a very happy client.

But not a very happy me. Time for some more internet research at http://www.google.co.uk/search?hl=en&q=cmyk+to+rgb+function

Voisen.org has an ActionScript method that is similar to the above, but has a slightly different treatment of the K value. Promising. Here is it, verbatim:

// voisen.org
Color.prototype.2rgb = function( c, m, y, k )
{
// Convert percentages to 0 – 255 range
c = (0xFF * c) / 100;
m = (0xFF * m) / 100;
y = (0xFF * y) / 100;
k = (0xFF * k) / 100;

r = this.dec2hex( Math.round( ((0xFF – c) * (0xFF – k)) / 0xFF ) );
g = this.dec2hex( Math.round( (0xFF – m) * (0xFF – k) / 0xFF ) );
b = this.dec2hex( Math.round( (0xFF – y) * (0xFF – k) / 0xFF ) );
return “0x”+r+g+b;
}

Remembering that 0xFF = 255, and we don't need the decimal to hex conversions, let's convert the maths to PHP:

 function cmyk_to_rgb2($c, $m, $y, $k)
{
$c = (255 * $c) / 100;
$m = (255 * $m) / 100;
$y = (255 * $y) / 100;
$k = (255 * $k) / 100;

$r = round(((255 - $c) * (255 - $k)) / 255) ;
$g = round((255 - $m) * (255 - $k) / 255) ;
$b = round((255 - $y) * (255 - $k) / 255) ;

$o->r = $r ;
$o->g = $g ;
$o->b = $b ;

return $o ;
}

A quick test shows that this function returns the exact same results as pass 1 for the colours tested above, which is what we'd expect, because they all have 0K. But what about other CMYK mixes?

Using Adobe's SVG export to give me a quick(ish) list of accurate RGB for 180 CMYK mixes (60 different hues each with 0K, 33K and 66K), I put together this PHP script to quickly test and compare different methods, and provide a visual table of results. (It could do with some tidying up, but nevermind).

Pass 2 results

Take a quick look at the results below, or view a larger HTML table of swatches - in the table, you can also hover over the swatches to view the source CMYK and output hex colours.

Pass 2 results

Voisen's method is coming up with almost the same RGB colours, except for the darker browns and greens, where there is a marked improvement. The K handling is better; but the purer colours are still far too bright.

Where next?

CMYK to RGB - pass 3: Wikipedia

Back at http://www.google.co.uk/search?hl=en&q=cmyk+to+rgb+function, another result heads to Wikipedia, where there is a mathematical equation for converting CMYK to CMY and then on to RGB. Here it is:

RGB = {1 - C(1 - K) - K, 1 - M(1 - K) - K, 1 - Y(1 - K) - K}

Where both RGB and CMYK are on a scale of 0-1, rather than 0-255 and 0-100. Bearing this in mind, we can translate to code without too much pain:

function cmyk_to_rgb3($c, $m, $y, $k)
{
$c = $c/100 ;
$m = $m/100 ;
$y = $y/100 ;
$k = $k/100 ;

$r = 1 - ($c * (1 - $k)) - $k ;
$g = 1 - ($m * (1 - $k)) - $k ;
$b = 1 - ($y * (1 - $k)) - $k ;

$o->r = round($r * 255) ;
$o->g = round($g * 255) ;
$o->b = round($b * 255) ;

return $o ;
}

In fact, this function maps directly to Voisen.org's, and a quick preview here confirms it.

So, where does this leave us?

A bit stuck I'm afraid.

A look round the internet brings up thousands of converters, calculators, functions and equations. But all the ones I've looked at boil down the maths above, which isn't good enough any for serious design work. Comments welcome. I'll write to the ImageMagick developers if I get a moment.

Comments

Sean - 23 July 2006 18:14 - Visit >

Should've saved you the trouble ... If I remember correctly, I translated that very same Wikipedia equation to create my method in the first place :) I haven't found anything better either, but if you find something, let me know ...

Vlado - 26 July 2006 05:07 - Visit >

I was excited findig your web site solving CMYK to RGB conversion I was looking for, but at the end disapointed as well because there was finally no solution. So I decided to do it my way....

From my experience the best cmyk to rgb conversion tool is Photoshop. So I created an CMYK image file (cmyk_colorspace.psd) as a colors space and conversion table (cmyk_colorspace.png). Advantage is, you can save this file from Photoshop as RGB image using different profile set in Photoshop. Using PHP function "imagecolorat" I can get RGB value of pixel at certain position represented CMYK value.

This way is conversion 100% right, ok not really, plus-minus 5% because of rounding by 5 to save image size. But 5% is nothing compared to differences between different displays or printers in real life.

Check it at: www.12345.com.au/cmyk2rgb/ All files are availablel: www.12345.com.au/cmyk2rgb/cmyk_colorspace.zip

Regards, Vlado

samba - 31 July 2006 06:40

Sir, I very much enjoy about your codings, but i want to remember the codes of cmyk in hex decimal in logical way. For example y 0%, m 20%, c 10%, k 0% the color code is #DDEFC4 i unable to remember this type of codes when the combination changes. Could kindly give an idea to remember cmyk hex codes

Vlado - 03 August 2006 03:09

Hi Samba, thanks but what do you exactly mean by "remember the codes"? There is no mathematical equation in my CMYK to RGB (WEB) coversion script. There is conversion image table instead. And how you gonna use my PHP conversion script is up to you, mate :-) Feel free to send me an email if it's not clear...

Chris - 17 July 2007 10:39

Hi

having trouble converting an image from RGB to CMYK, vlado you speak of a conversion script, is this just the mathmatical values for the colours? As i need a function to actually put in an rgb image, convert it to CMYK, and output

is this possible?

Nick Nettleton - 14 August 2007 13:36

Hi Chris - if you're looking to convert a bitmap image from RGB to CMYK within a web application, give ImageMagick a go - it's a command line application which you can call from PHP. Take a look at www.imagemagick.org.

Shout back if you get stuck and I may add a tutorial on this.

wow power leveling - 07 May 2008 02:53 - Visit >

The fourth wow power leveling latest game in wow power leveling Warcraft series is ‘wow power leveling’. Also known as wow power leveling, it represents a wow power leveling multiplayer online wow power leveling game, the best of wow power leveling kind. Initially, it was wow gold it be released in 2001, but wow powerleveling was delayed wow powerleveling 2004, thus wow powerleveling the 10 years ofwow powerleveling franchise of thiswow gold series. The world of warcraft power leveling was not world of warcraft power levelingfulfilling, because wow power levelproblems with wow power level server’s stability power leveling wow performance occurred, but power leveling wow game still power leveling wow a financial success powerleveling wow the most powerleveling wow game of its kind. The number cheap wow power leveling users that play Maple Story mesos, exceeds 8.5 MapleStory mesos, worldwide.As a form ms mesos,recognition for mesos,outstanding popularity, the game SilkRoad Gold, received aSRO Gold, of awards. Now the question eq2 plat, why is eq2 gold, game eq2 Platinum, popular? For anyoneEverQuest 2 Platinum, played the previous EverQuest 2 gold, and EverQuest 2 plat, already initiated lotro gold, the mysterious world lotr gold, the breathtaking Lord of the Rings online Gold, this Rolex Replica nothing but an Replica Rolex adventure that continues the story of ‘Warcraft III: Frozen Throne’, four years after conclusion, in the world of Azeroth. The game is online role-playing, the previous versions being online and offline strategy games. The major thrills and unique features are present as in every Blizzard game.

wsx - 08 May 2008 10:35 - Visit >

Nanjing East Inflatables Manufacturing Co.,Ltd. is a fast growing Inflatables field portal. We offer high quality Inflatable Bouncers, Inflatable Castle, Inflatable Games, Inflatable Arch and much. These Inflatable products that we provide are cheaper than others, our recommendatory product is Inflatable Toys, most of chindren like it!

wsx - 08 May 2008 10:36 - Visit >

Pass 4 Sure is your source for the Comptia A+ exam. With our IBM Certification Exam Resources, you can be rest assured that you will pass your MBS exam on Your First Try. Our exams are written and formatted by top senior IT Professionals working in today's prospering companies and data centers. All of our practice exams including the Comptia A+ exam guarantee you success on your First Try. You will find the great selection of silver Pendants at Tiffany Jewelry Store. All our silver tiffany pendants are stamped with a fineness mark of "925" or "Sterling" or "Ster" to indicate silver purity. Moreover, the tiffany pendant are crafted with the quality of being beautiful and delicate in appearance, and they are inspected for a fineness mark to ensure quality.

nokia - 10 May 2008 08:24

/ مسجات رمضان / مسجات رومانسية / مسجات شوق / مسجات عتاب / مسجات اشتياق / النغمات / نغمات نوكيا / تنزيل نغمات / تحميل نغمات / نغمات mp3 / نغمات 2007 / نغمات 2007 / نغمات 2008 / نغمات اسلامية / موقع نغمات / نغمات صوتية / نغمات mar جوال نوكيا / برامج نوكيا / ثيمات / مسجات / نغمات / برامج 6600 / برامج 3250 / برامج n70 / برامج n95 / برامج n73 / برامج الجيل الثالث / ثيمات n73 / ثيمات n70 / ثيمات 3250 / ثيمات 6300 / ثيمات 6600 / ثيمات 6630 / ثيمات e50 / ثيمات n70 / ثيمات n80 / ثيمات nth / مسجات / المسجات / احلى مسجات / مسجات حب / مسجات حلوة

yy - 11 May 2008 08:23

太陽光発電 不動産担保ローン 横浜中華街 不動産 賃貸 害虫駆除 結婚指輪 結婚式 演出 吉原 ソープ 債務整理 ウィークリーマンション 治験 介護 基礎化粧品 法律事務所 求人 葬儀 東京 看護師 会社設立 転職 ウィークリーマンション メル友 自動車ガラス ダイビング ECサイト構築 ウェディングドレス ウェディング バイアグラ 有料老人ホーム データ復旧 カラコン キャッシング 副業 清掃 特許事務所 永代供養 永代供養 永代供養 ペット 求人 広告業界 美容学校 マンションリフォーム 住宅リフォーム スカッシュ DVD 1

Add a comment

Related