PHP and AJAX Color Picker Experiment

Rate article down Rate article up 0 subscribe to cyberstream photos rss feed
Download the Opera: a fast, efficient, feature-packed, secure, personalizable web browser. Today, I'm going to show a little project I made with jQuery/AJAX and PHP. It takes an image (any image) and when you click on it, it returns the RGB values for the color of the pixel where you clicked on the image. It also creates a box with that RGB color that follows the cursor. Check out the demo or download the source files here: Note: interacting with the demo may be slow depending on your connection speed/computer speed.

How it Works

Server-Side

Let's start by looking at the server-side program. It is actually quite simple.
>?php

$image = $_POST['image'];
$x = $_POST['x'];
$y = $_POST['y'];

$im = imagecreatefromjpeg($image);
$rgb = imagecolorat($im, $x, $y);

$r = ($rgb << 16) & 0xFF;
$g = ($rgb << 8) & 0xFF;
$b = $rgb & 0xFF;

echo "$r, $g, $b";
This is in eyedropper2.php. The $_POST values are sent to this PHP script through AJAX, which we will see later. PHP takes the image and creates a new image resource. Remember from Learning PHP Part 2 that a resource is a PHP object that holds a reference to an external object, such as files, images, connections, streams, etc. This object created from our jpeg file, using the imagecreatefromjpeg() function, can be manipulated by PHP's numerous image GD functions. We will use the imagecolorat() function to get the color information from the photo at the coordinates we specify. We assign the color information to the $rgb variable. We must use bitwise operators to extract the individual red, green and blue values from $rgb. Be assign the red, green and blue values to the $r, $g, $b. We echo out these values so they are included in the AJAX response. Now let's dig in to the Java-Script.

The Client-Side

Let's brainstorm what we want on the client-side: We'll start by defining the styles for our color-picker box.
#color {
   width:100px;
   height:100px;
   border:1px solid #555;                
   -moz-border-radius:15px;
   -webkit-border-radius:15px;
   border-radius:15px;
   position:absolute;
   padding:5px;
   text-shadow:1px 1px 3px #111;
   -moz-text-shadow:1px 1px 3px #111;
   -webkit-text-shadow:1px 1px 3px #111;
}
Of course this element doesn't exist yet, but we'll create it later with Java-Script. We just made it a simple box with rounded corners. We'll define the background color later with JS, as well. Let's import the jQuery.js library before we jump into the JS.
<script src="../scripts/jquery.js"></script>
Let's start by fetching the coordinates of the mouse whenever it is moved over "#sample" (our image).
/* assign the top/left offsets of the #sample image to variables */

var left = parseInt($('#sample').css('left')),
top = parseInt($('#sample').css('top'));

    $('#sample').hover(function(e) {  
        color = getColor(e.pageX - left, e.pageY - top, $('#sample').attr('src'));
The pageX and pageY properties get the x and y offsets of the cursor when the cursor hovered over the image. Since we don't want the cursor coordinates, but rather the pixel coordinates on the image, we'll subtract the image's offsets (where the image is positioned on the page) from the cursor coordinates to get the pixel coordinates on the image. We also want to get the filename of the image, so we simple fetch the value of the "src" attribute and send it to our PHP script. Now let's deal with the RGB color values.
    $('>div id="color"<>/div<')
         .css({'top' : e.pageY - 125, 'left' : e.pageX + 10, 'background-color' : 'rgb(' + color + ')'});
         .appendTo('body');
         $('#color').html(color);
     }, function() { // callback function when the cursor leaves hover state
         $('#color').remove();
     });
Here we append the #color element to the body. Then we set its background color to "color" (the variable containing the RGB values). We also put the RGB values as text within the element so the user can see exactly which color they selected. We could convert it to hexadecimal, but to keep this tutorial shorter, we won't. Finally, we remove the #color element when the cursor leaves the image (#sample). By the way, "#" is jQuery's id selector. It selects elements with an id of, in this case, "sample". You can learn more about CSS selectors here.

     $('#sample').mousedown(function(e) {
         color = getColor(e.pageX - left, e.pageY - top, $('#sample').attr('src'));
         $('#color').css({'background-color' : 'rgb(' + color + ')'});
         $('#color').html(color);
     });
This simply refreshes the color picker whenever the mouse clicks the image.

     $('#sample').mousemove(function(e) {  // have the "color box" track the cursor
         $('#color').css({'top' : e.pageY - 125, 'left' : e.pageX + 10});
     });
This is the code that makes the color box track the cursor. We made it slightly offset from the cursor, however, as you can see in the second to last line. Here's our getColor() function, now.
function getColor(x,y,img) {
     data = 'image=' + img+ '&x=' + x+ '&y=' + y;
     $.ajax({
          type: "POST",
          async: false,
          url: "eyedropper2.php",
          data: data,
          cache: false,
          success: function(html){
              value = html;
          }
     });
   return value;
}
The $.ajax() function is one of jQuery's AJAX functions. It is explained in more detail here. This will send our data in a "key=value&key2=value2..." query string to [code]eyedropper2.php[/code], where each value pair is assigned to a $_POST variable. Then our PHP program is executed and we receive our RGB values! Here's the complete Java-Script script:
<script src="../scripts/jquery.js"></script>
        <script>
            $(function() {
                var left = parseInt($('#sample').css('left'));
                var top = parseInt($('#sample').css('top'));

                $('#sample').hover(function(e) {
                       color = getColor(e.pageX - left, e.pageY - top, $('#sample').attr('src'));
                       $('>div id="color"<>/div<')
                       .css({'top' : e.pageY - 125, 
                               'left' : e.pageX + 10, 
                               'background-color' : 'rgb(' + color + ')'})
                       .appendTo('body');
                       $('#color').html(color);
                }, function() {
                    $('#color').remove();
                });

                $('#sample').mousedown(function(e) {
                    color = getColor(e.pageX - left, 
                                             e.pageY - top, 
                                             $('#sample').attr('src'));
                    $('#color').css({'background-color' : 'rgb(' + color + ')'});
                    $('#color').html(color);
                });

                $('#sample').mousemove(function(e) {
                      $('#color').css({'top' : e.pageY - 125, 'left' : e.pageX + 10});
                });
            });

            function getColor(x,y,img) {
                data = 'image=' + img+ '&x=' + x+ '&y=' + y;
                $.ajax({
                        type: "POST",
                        async: false,
                        url: "eyedropper2.php",
                        data: data,
                        cache: false,
                        success: function(html){
                            value = html;
                    }
                });
                return value;
            }    
</script>

Posted April 11, 2011 at 8:55PM by Eli Mitchell in jQuery, Javascript, PHP, AJAX, experiment with 4 responses

Post a comment!

Name:
Your website: (optional)
E-mail:

Your comment: