Updated post here

Today I want to show you how to make a image tagging function on your website.

It works about the same way than facebook does (or a least the way it worked some times ago because I deleted my facebook account)

Basicly you take an image and you “tag” people or stuff in it by marking what you want to tag with a rectangle.

This example is just a proof of concept and will give you a good idea on how to make it better for your website.

This script requires jquery and jquery-ui with draggable and resizable function(it’s included in the source).

note : I didnt have time to test it on IE so let me know if it works for you…

Here is the Demo and the Source.

Ok so first let’s explain the basics of this demo.

The script has two modes

  • The edit mode where you can add tags to a picture (there is no delete function but there should be one).
  • The view mode where you can view the tag on the picture.

I also use a simple database to store tags and pictures.

pictures table

CREATE TABLE IF NOT EXISTS `pictures` (
  `id` int(11) NOT NULL auto_increment,
  `title` varchar(50) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM;

We will supose that every pictures are jpgs and that there name is [id].jpg but you can change that of course

tag tables

CREATE TABLE IF NOT EXISTS `tags` (
  `id` int(11) NOT NULL auto_increment,
  `pictureid` int(11) NOT NULL,
  `top` int(11) NOT NULL,
  `left` int(11) NOT NULL,
  `width` int(11) NOT NULL,
  `height` int(11) NOT NULL,
  `description` varchar(50) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `pictureid` (`pictureid`)
) ENGINE=MyISAM;

now let’s see what will need

  1. A div where the picture will be displayed and the draggable “tagger” div will be stuck.
  2. The actual picture we want to tagg or display
  3. the tagger div, it will be 100×100 but will be resizable and draggable at will.
  4. A form to add the tag
  5. A info div per tag

Here is a simplified view of our html

<div id=taggingArea>
	<img src="./$pic.jpg" />

	<div id=drag>

	</div>
</div>

<div id=formArea>
	<form>

	</form>
</div>

and the CSS

#taggingArea{
        position:relative;
        width:auto;
        float:left;
}
#formArea{
        float:left;
}
#drag{
        position:absolute;
        top:0px;
        width:100px;
        height:100px;
        border:5px solid black;
        background:url('blank.gif');
}

Let’s make our form now so we know what to store in the db
To be able to store all the info we need 5 variables.

  1. The width
  2. The height
  3. The “top” position
  4. The “left” position
  5. The description to be added

The user will only have to input the description field of course.

<form method=post>
	<input type=hidden name=width id=width>
	<input type=hidden name=height id=height>
	<input type=hidden name=top id=top>
	<input type=hidden name=left id=left>
	Description : <input type=text name=description>
	<input type=submit value=save>
</form>

and now the JS

function updateForm(){
        $("#width").val($("#drag").attr("offsetWidth"));
        $("#height").val($("#drag").attr("offsetHeight"));
        $("#top").val($("#drag").attr("offsetTop"));
        $("#left").val($("#drag").attr("offsetLeft"));
}
$(document).ready(function(){
        updateForm();
        $("#drag").resizable({
                stop: function() {
                        updateForm();
        }
        });
        $("#drag").draggable({
               containment: 'parent',
                stop: function() {
                        updateForm();
        }
        });
});

This little code makes the “drag” div draggable and resizable and call up the function updateForm() everytime a drag or resize action is stopped.
The updateForm as for only purpose to update the hidden field of the form we created earlier.

once you have those values you can store it on your Db using a simple POST form handling ( if you don’t know how you can find an example in the sourcecode )

At this point you should be able to do all the tagging you want but now we need a way to display it on the image.

This can be done with adding a Div with the right style for each tag on the image.
Here is some example PHP

<div id="taggingArea">
        <img src="<?php echo $pic;?>.jpg" />
        <?php
        $getTags = mysql_query("select * from tags where pictureid = $pic");
        if(mysql_num_rows($getTags)>0){
                while($resTags = mysql_fetch_array($getTags)){
                ?>
                <div class=tag style="position:absolute;width:<?php echo $resTags['width'];?>px;height:<?php echo $resTags['height'];?>px;top:<?php echo $resTags['top'];?>;left:<?php echo $resTags['left'];?>;">
                        <?php echo $resTags['description'];?>
                </div>
                <?php
                }
        } ?>
</div>

To tweak things up a bit you can add a simple hover effect that will add a border on the tag.

.tagOn{
	border:1px solid black;
}
$(".tag").hover(
	function () {
		$(this).addClass("tagOn");
	},
	function () {
		$(this).removeClass("tagOn");
	}
);

Here is a complete example of a full php file to edit and view.

<?php

mysql_connect("localhost","root","**");
mysql_select_db("imageTagging");

if(isset($_GET[del])){
	mysql_query("delete from tags where id = ".addslashes($_GET[del]));
}

if(!isset($_GET[pic])){
	$pic = 1;
} else {
	$pic = addslashes($_GET[pic]);
}

	if($_POST){
		if($_POST[description]!=""){
			foreach($_POST as $id => $val){
				$$id = addslashes($val);
			}
			mysql_query("
				insert into tags (pictureid,top,`left`,width,height,description)
				values ($pic,$top,$left,$width,$height,'$description')") or die(mysql_error());
			header("location:demo.php");
		}
	}
?>
<html>
	<head>
		<script src="./js/jquery.js" language="JavaScript" type="text/javascript"></script>
		<script src="./js/jquery-ui.js" language="JavaScript" type="text/javascript"></script>
		<link type="text/css" href="./css/jquery-ui.css" rel="stylesheet" />
		<script>
			function updateForm(){
				$("#width").val($("#drag").attr("offsetWidth"));
				$("#height").val($("#drag").attr("offsetHeight"));
				$("#top").val($("#drag").attr("offsetTop"));
				$("#left").val($("#drag").attr("offsetLeft"));
			}
			$(document).ready(function(){
				updateForm();
				$("#drag").resizable({
					 stop: function() {
					  	updateForm();
					  }
				});
				$("#drag").draggable({
					  containment: 'parent',
					  stop: function() {
					  	updateForm();
					  }
				});
				$(".tag").hover(
				function () {
				$(this).addClass("tagOn");
				},
				function () {
				$(this).removeClass("tagOn");
				}
				);

			});
		</script>
		<style>
			.tagOn{
				border:1px solid black;
			}
			#taggingArea{
                                position:relative;
				width:auto;
				float:left;
			}
			#formArea{
				width:50%;
				float:left;
			}
			#drag{
				position:absolute;
				top:0px;
				width:100px;
				height:100px;
				border:2px solid black;
				background:url('blank.gif');
			}
		</style>
	</head>
	<body>
		<div id="taggingArea">
			<img src="<?php echo $pic;?>.jpg" />
			<?php if($_GET[mode]=="edit"){
				?><div id="drag" class="ui-widget-content"></div><?
			} else {
				$getTags = mysql_query("select * from tags where pictureid = $pic");
				if(mysql_num_rows($getTags)>0){
					while($resTags = mysql_fetch_array($getTags)){
						?>
						<div class=tag style="position:absolute;width:<?php echo $resTags['width'];?>px;height:<?php echo $resTags['height'];?>px;top:<?php echo $resTags['top'];?>;left:<?php echo $resTags['left'];?>;">
							<?php echo $resTags['description'];?>
						</div>
						<?php
					}
				}
			} ?>
		</div>
		<?php if($_GET[mode]=="edit"){ ?>
			<div id="formArea">
				<form method=post>
					<input type=hidden name=pic value="<?php echo $pic;?>">
					<input type=hidden name=width id=width>
					<input type=hidden name=height id=height>
					<input type=hidden name=top id=top>
					<input type=hidden name=left id=left>
					Description : <input type=text name=description>
					<input type=submit value=save>
				</form>
				<?php
				$getTags = mysql_query("select * from tags where pictureid = $pic");
				if(mysql_num_rows($getTags)>0){
					while($resTags = mysql_fetch_array($getTags)){
						echo "Tag #$resTags[id] $resTags[description] <a href=\"demo.php?del=$resTags[id]\">Delete</a><br />";
					}
				}
				?>
				<a href="demo.php">Go to view mode</a>
			</div>
		<?php } else { ?>
			<div id="formArea">
				<a href="demo.php?mode=edit">Go to edit mode</a>
			</div>
		<?php } ?>
	</body>
</html>

This is a pretty long tutorial for me and I’m not sure I was clear enough so let me know if you need any additional info !

Share

Related Posts: