To call it as “photo tagging” is outright wrong, to be precise it should be called as image annotation or even sticky notes, which is the process of super-imposing a piece of information or data( called as tags) to a specific part of an image without changing the underlying image. You can have one or more tags for a single image. Most of us are already familiar with tags marked over group photos on social media sites, but this type of tagging information onto an image serves wider purpose. Annotation or Image tagging ( to sound familiar ) can be used in the following scenarios.

  • To highlight errors or provide some corrections, write comments or suggestions on any kind of design.
  • Can be helpful as a presentational markup.
  • Annotation on plans and designs will be helpful in remembering the concept and idea and discussing it further.
  • Markup on graphs and scientific images.
  • Name of people or person on photos. ( I bet you already know this he..he.. )

image-taggingAll right, my intent was to write a piece of software code with PHP and jQuery to annotate images, store them in database and retrieve them when a particular image is loaded. Then I came across various photo tagging scripts and plugins, some are too complex, some are simple but doesn’t have the expected feature. Here is what I came up with, a simple code without any plugin or complexity. But before getting into the code I would like to present a basic workflow on how image annotation works.


Now lets take a look into the code.  Here is the break-up of what is to be done.

  1. Present an image( it can be one within a gallery, or an image embedded in an article ).
  2. When the image has been loaded, we send an ajax request to retrieve the annotations for the particular image and load them if available.
  3. Setup interactivity for all the annotations with jQuery. So that each annotation appears only when mouse pointer moves over annotated or tagged area.
  4. Setup event handlers to create and remove annotations.

The PHP that presents the image to the user.

 <div id="container"> <div id="imgtag"> <?php $sql = "SELECT * FROM picture WHERE id=1"; $qry = mysql_query( $sql ); $rs = mysql_fetch_array( $qry ); ?> <img id="<?php echo $rs['id']; ?>" src="<?php echo $rs['name']; ?>" /> <div id="tagbox"> </div> </div> <div id="taglist"> <ol> </ol> </div> </div> 

Every image we insert into gallery or article will be given unique id, which will be used to retrieve the image. So you can see in the above code we construct a query with id=1, which is image id. You can make this dynamic by replacing the number with a variable or value from query string. We have also placed the image within a div name imgtag, along with 2 more div elements which will be used to place the annotation data. Now after presenting the image, the rest is taken care by jQuery.

jQuery Code for capturing the Click event on the image.

 $("#imgtag img").click(function(e) { // make sure the image is clicked var imgtag = $(this).parent(); // get the div to append the tagging list mouseX = ( e.pageX - $(imgtag).offset().left ) - 50; // x and y axis mouseY = ( e.pageY - $(imgtag).offset().top ) - 50; $( '#tagit' ).remove( ); // remove any tagit div first //insert an input box with save and cancel operations. $( imgtag ).append( '<div id="tagit"><div class="box"></div><div class="name"><div class="text">Type any name or tag</div><input type="text" name="txtname" id="tagname" /><input type="button" name="btnsave" value="Save" id="btnsave" /><input type="button" name="btncancel" value="Cancel" id="btncancel" /></div></div>' ); $( '#tagit' ).css({ top:mouseY, left:mouseX }); $('#tagname').focus(); });

Now when the user clicks on the image, the above code will place an input box with save and cancel buttons, so user can enter the required tag or info to be saved. Clicking save after entering the tag will send an ajax request to save the tag. The following jQuery code will send the x and y position and the tag to the server.

 $( document ).on( 'click', '#tagit #btnsave', function(){ name = $('#tagname').val(); var img = $('#imgtag').find( 'img' ); var id = $( img ).attr( 'id' ); $.ajax({ type: "POST", url: "savetag.php", data: "pic_id=" + id + "&name=" + name + "&pic_x=" + mouseX + "&pic_y=" + mouseY + "&type=insert", cache: true, success: function(data){ viewtag( id ); $('#tagit').fadeOut(); } }); });

The following PHP code will store the annotated area, that is x and y position and the user entered tag into database.

if( !empty( $_POST['type'] ) && $_POST['type'] == "insert" ) { $id = $_POST['pic_id']; $name = $_POST['name']; $pic_x = $_POST['pic_x']; $pic_y = $_POST['pic_y']; $sql = "INSERT INTO image_tag (pic_id,name,pic_x,pic_y) VALUES ( $id, '$name', $pic_x, $pic_y )"; $qry = mysql_query($sql); } 

Now we have successfully stored the tag in to the database. All we have to do is retrieve the X and Y position of the annotated area and the tags  associated with the image. You may have multiple annotations per image( e.g  a group photo or a natural scenery ), we must load them all. We will load two kinds of data here.

  1. Tag boxes with data to be placed over the image.
  2. The list of tags with an option to remove the tag.

jQuery code to retrieve the tags.

$.post( "taglist.php" , "pic_id=" + pic_id, function( data ) { $('#taglist ol').html(data.lists); $('#tagbox').html(data.boxes); }, "json");

You can see in the above code snippet, we are expecting a json object which contains two different data

  • boxes – those are the tag boxes to be place on the image.
  • lists – those are list with optional tag removing feature.

Now you take a look into the PHP code that sends json object.

$sql = "SELECT * FROM image_tag WHERE pic_id=" . $_POST[ 'pic_id' ] ; $qry = mysql_query($sql); $rs = mysql_fetch_array($qry); $data['boxes'] = ''; $data['lists'] = ''; if ($rs){ do{ $data['boxes'] .= '<div class="tagview" style="left:' . $rs['pic_x'] . 'px;top:' . $rs['pic_y'] . 'px;" id="view_'.$rs['id'].'">'; $data['boxes'] .= '<div class="square"></div>'; $data['boxes'] .= '<div class="person" style="left:' . $rs['pic_x'] . 'px;top:' . $rs['pic_y'] . 'px;">' . $rs[ 'name' ] . '</div>'; $data['boxes'] .= '</div>'; $data['lists'] .= '<li id="'.$rs['id'].'"><a>' . $rs['name'] . '</a> (<a class="remove">Remove</a>)</li>'; }while($rs = mysql_fetch_array($qry)); } echo json_encode( $data ); 

In the above code we place the div in $data[‘boxes’] and lists in $data[‘lists’] and send it as a json object, we did this way so that we can eliminate two separate ajax requests for tag boxes and lists.

Now we have placed the tag boxes over the image, but it should not appear unless the user hovers the mouse over the image. the trick lies in the CSS code, we just set the opacity of the div to 0(zero), so that the div disappears completely. So when the user hover the mouse over the annotated/tagged area we set the opacity of the div to 1, so it appears. Here is the jQuery code that does the trick.

 // mouseover the tagboxes that is already there but opacity is 0. $( '#tagbox' ).on( 'mouseover', '.tagview', function( ) { var pos = $( this ).position(); $(this).css({ opacity: 1.0 }); // div appears when opacity is set to 1. }).on( 'mouseout', '.tagview', function( ) { $(this).css({ opacity: 0.0 }); // hide the div by setting opacity to 0. }); 

So we have chained the mouseover and mouseout events which sets the opacity to 1 and 0 respectively for the tag boxes which has the class name “tagview“. we have done the same to capture the mouse hover on the lists, and display the tags accordingly. We also have implemented remove tag feature which basically sends an ajax request and removes the tag. You can download the full working code here. Hope you like it.


Subscribe to Download

We will never send you spam. Ever! Probably!

Powered by Capture and Convert

Simple photo tagging with PHP and jQuery


3D modeler and Web designer. Founder of Techlister. Love to build sites using Wordpress and Joomla. Interested in Astronomy.

Leave a Reply

Your email address will not be published. Required fields are marked *