colorBar

ColorPicking on images

This tutorial is about how to pick the color of a pixel or pixel range of an image with javaScript and PHP
(see also http://dematte.at/colorPicker/#demo).

It's about correct coordinates calculation, AJAX and some PHP using the GD-library.
I will only give you explainations on the idea itself, and won't get to deep into the functions.

Table of contents:

Bookmark and Share

The following box shows an image, an input field for the color result and a selection box whit that you can choose the area around the picked pixel that should be included in the color calculation.
Click on the image to recieve the color value:

blume

Color:  within 
^ back to top

Main idea:

You need to:

^ back to top

The HTML:

<img src="blume.jpg" style="cursor:crosshair" alt=""            
     onmousedown="getColor(event,
                           this,
                           document.getElementById('result'),
                           document.getElementById('range').value);" />
 
<input value="" id="result" size="7" maxlength="7" />
 
<select name="range" id="range">
  <option value="1">1 pixel</option>
  <option value="3" selected="selected">3 x 3 pixels</option>
  <option value="5">5 x 5 pixels</option>
  <option value="11">11 x 11 pixels</option>
  <option value="31">31 x 31 pixels</option>
  <option value="51">51 x 51 pixels</option>
  <option value="101">101 x 101 pixels</option>
</select>

^ back to top

The javaScript:

function getColor(e,img,resObj,range,scriptPath) {
  var req = false;
  if (window.XMLHttpRequest) req = new XMLHttpRequest();
  else if (window.ActiveXObject) {
    try { req = new ActiveXObject('Msxml2.XMLHTTP');}
    catch (e) {
      try { req = new ActiveXObject('Microsoft.XMLHTTP');}
      catch (e) {}
    }
  }
  if (!req) return false;
  else {
    req.open('GET',(scriptPath || '')+
                   'getColor.php?coords='+getMousePos(e,getOrigin(img))+
                   '&range='+range+'&img='+img.src, true);
    req.setRequestHeader('X-Referer', document.location);
    req.send(null);
    req.onreadystatechange = function(){
      if(req.readyState == 4) if(req.status == 200) {
        resObj.value = req.responseText;
        resObj.style.backgroundColor = req.responseText;
      }
    };
  }
}
  

function getMousePos (e,relXY) {
  if(!e) var e = window.event;
  if(typeof e.pageX === 'number') return [e.pageX - relXY[0], e.pageY - relXY[1]];
  else return [e.clientX + document.body.scrollLeft +
               document.documentElement.scrollLeft - relXY[0],
               e.clientY + document.body.scrollTop +
               document.documentElement.scrollTop - relXY[1]];
}
  
function getOrigin(obj) {
  var parent=box=null, pos=[];
  
  this.getStyle = function (prop) {
    if (obj.currentStyle) return obj.currentStyle[prop];
    else if (window.getComputedStyle) return
        document.defaultView.getComputedStyle(obj,null).getPropertyValue(prop);
  }
  
  if (obj.parentNode === null || this.getStyle('display') == 'none') return false;
  if (obj.getBoundingClientRect) { // IE
    box = obj.getBoundingClientRect();
    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    var scrollLeft = document.documentElement.scrollLeft
                     || document.body.scrollLeft;
  
    return [Math.round(box.left) + scrollLeft, Math.round(box.top) + scrollTop];
  } else if (document.getBoxObjectFor) { // gecko
    box = document.getBoxObjectFor(obj);
    pos = [box.x, box.y];
  } else { // safari/opera
    pos = [obj.offsetLeft, obj.offsetTop];
    parent = obj.offsetParent;
    if (parent != obj) {
      while (parent) {
        pos[0] += parent.offsetLeft;
        pos[1] += parent.offsetTop;
        parent = parent.offsetParent;
      }
    }
    var ua = navigator.userAgent.toLowerCase();
    if (ua.indexOf('opera') != -1 ||
       (ua.indexOf('safari') != -1 &&
        this.getStyle('position') == 'absolute')) {
          pos[1] -= document.body.offsetTop;
    };
  }
  if (obj.parentNode) parent = obj.parentNode;
  else parent = null;
  while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML') {
    pos[0] -= parent.scrollLeft;
    pos[1] -= parent.scrollTop;
    if (parent.parentNode) parent = parent.parentNode;
    else parent = null;
  }
  return pos;
}

^ back to top

The PHP:

$prefix = isset($_GET['prefix']) ? $_GET['prefix'] : '#';
 
if (!$_GET['coords'] or !strpos($_GET['coords'],',')) die($prefix.'000000');
$coords = explode(',',$_GET['coords']);
 
$img = $_GET['img'] ? $_GET['img'] : 'blume.jpg';
$ext = explode('.',$img);
$ext = strtolower($ext[count($ext)-1]);
if ($ext == 'jpg' or $ext == 'jpeg') $img = @imagecreatefromjpeg($img);
else if ($ext == 'gif') $img = @imagecreatefromgif($img);
else if ($ext == 'png') $img = @imagecreatefrompng($img);
else die($prefix.'000000');
if (!$img) die($prefix.'000000');
$imgW = imagesx($img);
$imgH = imagesy($img);
 
$range = $_GET['range'] ? (int) $_GET['range'] : 2;
while(abs($range)%2 != 0) $range--;
if ($range<0) $range = 0;
$range /= 2;

for ($n=-$range; $n<=$range; $n++) {
  for ($m=-$range; $m<=$range; $m++) {
    $x = $coords[0]+$m; $x = $x > $imgW ? $imgW : $x < 0 ? 0 : $x;
    $y = $coords[1]+$n; $y = $y > $imgH ? $imgH : $y < 0 ? 0 : $y;
    $rgb = imagecolorat($img, $x, $y);
    $rgb = imagecolorsforindex($img, $rgb);
    $r += $rgb['red'] & 0xFF;
    $g += $rgb['green'] & 0xFF;
    $b += $rgb['blue'] & 0xFF;
  }
}
imagedestroy($img);

$r = dechex($r/pow($range*2+1,2));
$g = dechex($g/pow($range*2+1,2));
$b = dechex($b/pow($range*2+1,2));

echo $prefix.((strlen($r)<2)?'0'.$r:$r).
             ((strlen($g)<2)?'0'.$g:$g).
             ((strlen($b)<2)?'0'.$b:$b);

^ back to top
dematte
madeinheaven  branch office Amsterdam