25.7.13

Creating A Color Space

So far I've shown a few tricks that I haven't been able to find on other people's blogs but they're nothing too spectacular. Now it's time to flex that programming muscle, which in my case is located in the middle finger of my right hand, my most dominant finger when typing, and show some really bad code.

It's almost as bad as this but with an added twist of converting to an entirely new colour space. Because every exercise should have some purpose, the purpose of this one is to replicate the way some people experience colour, in particular the group of people with a colour deficiency most certainly named after an undiscovered Saturn moon, Tritanopia.

People with tritanopia experience the world differently in that they don't experience blue and yellow the way most people do. Instead, they experience it in a red-green hue. Below are two images: the original I took several weeks ago, and the same image with Tritanopia filter applied to it. If you don't see any difference between the two images, I have bad news for you.

Tritanopia Hot Pokers 

Original Hot Pokers






















Making an educated guess about how someone else's algorithm might work or should work without actually looking at the code is a superpower, of which I'm quite proud. Rest assured, I only use it for legal causes. The rgb2tritan function below is just that - an educated guess. However, you can test it with the rainbow from wikipedia, or whatever test you see fit. Below is the code all in one .php file.

 <?php  
 /* -------------------------------------------------  
 This content is released under the MIT License  
 http://www.opensource.org/licenses/mit-license.php  
 Author: Marina Ibrishimova (http://ibrius.net)  
 Version: 1.0  
 ---------------------------------------------------- */   
 function rgb2tritan($r, $g, $b)  
 {  
      //set the tritanopia vector  
      $v1=125;$v2=140;$v3=150;  
      $rgb1 = $v1 + $v2 + $v3;  
      $rgb2 = ($r + $g + $b)/3;   
      $vector = array($v1/$rgb1,$v2/$rgb1,$v3/$rgb1);  
      //blue has the strongest intensity so convert the pixel to tritanopia equivalent   
      if($b > $g && $g >= $r)   
      {  
           $newR = $r;  
           $newG = $rgb2;  
           $newB = $r*$vector[0] + $g*$vector[2] + $b*$vector[1];   
      }   
      else  
      {  
           $newR = $r;  
           $newG = $newB = $g;  
      }  
      return array($newR, $newG, $newB);  
 }  
 function tritanopia($filename)  
 {  
      $im = '/path_to_your/images/'.$filename;  
      if (file_exists($im))  
      {  
           $im = imagecreatefromjpeg($im);  
           if ($im == FALSE)  
           return FALSE;  
           $height = imagesy($im);  
           $width = imagesx($im);  
           //because you really don't want to loop through more that this  
           if ($width >= 900 || $height >= 1000)  
           return FALSE;  
           //let the looping begin  
           for($x=0; $x<$width; $x++)  
           {  
            for($y=0; $y<$height; $y++)  
            {  
                 $rgb = ImageColorAt($im, $x, $y);  
                 $r = ($rgb >> 16) & 0xFF;  
                 $g = ($rgb >> 8) & 0xFF;  
                 $b = $rgb & 0xFF;  
                 list($newR, $newG, $newB) = rgb2tritan($r, $g, $b);  
                 imagesetpixel($im, $x, $y, imagecolorallocate($im, $newR, $newG, $newB));  
             }  
          }   
          if(imagejpeg($im, '/path_to_your/temp_imgs/'.$filename))  
          return TRUE;  
          imagedestroy($im);  
     }  
 return FALSE ;  
 }  
 ?>  
 <!DOCTYPE HTML>  
 <head>  
 <title>Tritanopia</title>  
 <meta charset="utf-8" />  
 </head>  
 <body>  
  <?php  
  //the crop will be 50% of the original, and it will be at the center of the image  
  if(tritanopia('your_filename.jpg'))  
  {  
        echo "<img src=\"/path_to_your/temp_imgs/your_filename.jpg\" > <img src=\"/path_to_your/images/your_filename.jpg\" style=\"float:right;\">";  
  }  
  else  
  {  
        echo "Oops, you either messed up the path, gave the wrong file, or the wrong file size. Happy bug hunting!";  
  }  
  ?>  
 </body>  
 </html>