Index: imageapi.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/imageapi/imageapi.module,v
retrieving revision 1.25
diff -d -u -r1.25 imageapi.module
--- imageapi.module	6 Feb 2009 09:26:33 -0000	1.25
+++ imageapi.module	16 Feb 2009 21:55:07 -0000
@@ -430,3 +430,99 @@
   return array($r, $g, $b, $a);
 }
 
+/**
+ * Parse and convert RGB colors between formats.
+ *
+ * @param $color
+
+ *   A RGB(A) color either as an integer, array or a string.  Integers are
+ *   treated as 24 bits RGB values and may be specified as hex literals in the
+ *   form 0xRRGGBB.  Arrays acts just like the CSS' rgb() or rgba() functions
+ *   with the exception that all channels are integers between 0-255.  No
+ *   percent, no floats.  The alpha channel is an integer between 0-255.  0
+ *   means full transpacency, 255 full opacity.  Example: array(255,0,0) for
+ *   red and array(0,255,0,64) for green with 25% opacity.  The string version
+ *   accepts the following formats, all intepreted as hex values:
+ *   '0xRGB', '0xRRGGBB', '0xRGBA', '0xRRGGBBAA',
+ *    '#RGB',  '#RRGGBB',  '#RGBA',  '#RRGGBBAA',
+ *     'RGB',   'RRGGBB',   'RGBA',   'RRGGBBAA'.
+ *   For the alpha channel, '00' means full transparency, 'FF'
+ *   means full opacity.
+ *   
+ * @param $format
+ *   How to format the returned color. The following formats are supported:
+ *   - 'web'   returns a string with color in web format. Example: '#FF00FF'.
+ *   - 'array' returns the RGBA channels as an array of integers between 0-255.
+ *   - 'rgb'   returns a string with the RGB channels in hex. Example: 'FF00FF'.
+ *   - 'rgba'  returns a string with the RGBA channels in hex. Example: 'FF00FF80'.
+ * @return
+ *   A color representation of $color according to $format or false if $color
+ *   could not be parsed.
+ */
+function imageapi_color_convert($color, $format = 'web')
+{
+  // Internal representation of the color. Channels are stored as integers
+  // between 0-255.
+  $rgba = array();
+
+  if (is_int($color)) {
+    $rgba[] = ($color & 0xff0000) >> 16;
+    $rgba[] = ($color & 0x00ff00) >> 8;
+    $rgba[] = ($color & 0x0000ff);
+  }
+  elseif (is_array($color)) {
+    $channel_num = count($color);
+    if ($channel_num < 3 || $channel_num > 4) {
+      return false;
+    }
+    // Clip channels values to be between 0-255. This is also done in CSS2's rgb() function.
+    foreach ($color as $channel) {
+      $rgba[] = min(max(intval($channel), 0), 255);
+    }
+  }
+  elseif (is_string($color)) {
+    $hex = preg_replace('/^(0x|#)?([0-9a-f]+)$/i', '$2', $color);
+    if (! preg_match('/^[0-9a-f]{3,8}$/i', $hex)) {
+      return false;
+    }
+    $length = strlen($hex);
+    switch ($length) {
+      case 3:
+      case 4:
+        for ($i = 0; $i < $length; $i++) {
+          $rgba[] = str_repeat($hex{$i}, 2);
+        }
+        break;
+      case 6:
+      case 8:
+        $rgba = str_split($hex, 2);
+        break;
+      default:
+        return false;
+    }
+    foreach ($rgba as $i => $channel) {
+      $rgba[$i] = hexdec($channel);
+    }
+  }
+  else {
+    return false;
+  }
+  // Add alpha channel if not present
+  if (count($rgba) == 3) {
+    $rgba[] = 255;
+  }
+  // Conversion done.  Return color in desired format.
+  switch($format) {
+    case 'web':
+      return sprintf("#%02x%02x%02x", $rgba[0], $rgba[1], $rgba[2]);
+    case 'array':
+      return $rgba;
+    case 'rgb':
+      return sprintf("%02x%02x%02x", $rgba[0], $rgba[1], $rgba[2]);
+    case 'rgba':
+      return sprintf("%02x%02x%02x%02x", $rgba[0], $rgba[1], $rgba[2], $rgba[3]);
+    default:
+      return false;
+  }
+}
+
