Image Maps

image map

rectangle circle pentagon the hidden spot! everywhere else

Image maps are a good example of something that will "impress the rubes", because it is not immediately obvious how to create them. Image maps turn portions of the image into clickable links. There are 2 basic styles: server-side and client-side. The difference is in where the map information is stored and processed: on the server itself or on the client's web browser. My feeling is that the PC on most people's desks is much more powerful than is necessary, so it makes sense to offload some of the processing onto the client rather than waste server resources on it. Thus, I am going to stick wtih client-side image maps.

The image map needs an image, which you can create as a PNG file with the GD module. For this example, the file "image_map.pl" in the BIOS546 HTML directory will create a suitable image and map. The code to generate the image, as well as the HTML code it generates, are shown below.

On the HTML page you normally call up the image with a tag like: <img src="image_map.png">. To make this into an image map, add the "USEMAP" attrribute, whose value is a URL to a <map> tag elsewhere on the page: <img src="image_map.png" USEMAP="#this_map">. The name of the <map> tag is "this_map"; the "#" that preceeds it indicates that the map is found elsewhere on the same page. It is (probably) possible to have the map in a separate file--investigate this if you wish. It is also nice to use the "alt" attribute, to display a bit of text if the image fails or if the user has a non-graphical browser: <img src="image_map.png" USEMAP="#this_map" alt="image map test">

The map section itself starts with the map tag, which is given the "name" attribute using the same name as you used in the <img> tag, without the "#": <map name="this_map>. The map section ends in a </map> tag. Within the map section are the <area> tags that describe the individual hot areas.

The <area> tag is an empty tag: it does not need a closing </area> tag. All information about the area is in the form of attributes: name="value" pairs within the <area> tag itself. There are 3 required attrributes: "shape", "coords" and "href". The shape attribute should be one of: "rect" (a rectangle), "circle", "poly" (a polygon), or "default". The coords are a comma-separated list of pixel coordinates on the image. The required coordinates differ for the different shapes:

The href attribute is the URL that you go to when the hot area is clicked. You can also use "NOHREF" in place of the href attribute if you want to no link in the area.

The <area> tag can also take an "alt" attribute, which will appear as a "tool tip" on the browser. Here is a complete area tag for a rectangle: <area shape ="rect" coords="10, 10, 80, 150" href="rect.htm" alt="rectangle">

Another useful attribute of an <area> tag is "target". If you use target="_blank" (note the underscore!), the new HTML page appears in a separate window. See the rectangle example below.

It is also possible to pass parameters to a CGI program as part of the value in an href attribute. Immediately after the path and name of the CGI program, put a "?" follwed by the name=value pairs of the parameters. Separate different parameters with "&". If you want to have a blank space in the parameter value, you can use the HTML entity "&emsp;", an em space (i.e as wide as the letter m) or "&ensp;", an en space (as wide as the letter n).

It is not necessary to have a visible image where the hot spots are. Thus you can create hidden hot spots by simply not marking them in the PNG image. There is a "hidden" rectangle in the image map above.

You can find a number of image map tutorials on the web, but I find that the best way to get definitive information is to look at the W3.org specifications for HTML 4.0: it is section 6 in the linked document.


image_map.pl, a program to generate an image map

#!/usr/bin/perl -w

# generates a simple client-side image map

use strict;
use GD;

    # open the image file
open PICFILE, ">/home/httpd/html/bios546/image_map.png" or die "Couldn't open image file: $!\n";
open HTMLFILE, ">/home/httpd/html/bios546/image_map.htm" or die "Couldn't open html file: $!\n";

   # create new image object
my $im = new GD::Image(760, 200);

    # create a set of colors
my $white = $im->colorAllocate(255,255,255);
my $black = $im->colorAllocate(0, 0, 0);
my $red = $im->colorAllocate(255, 0, 0);
my $blue = $im->colorAllocate(0, 0, 255);
my $green = $im->colorAllocate(50, 200, 0);
my $purple = $im->colorAllocate(200, 0, 255);
my $orange = $im->colorAllocate(255, 200, 0);                        

    # set background and interlacing
$im->transparent($white);
$im->interlaced('true');

    # draw a border around the image
$im->rectangle(0, 0, 759, 199, $black); 

    # draw a rectangle
my @rect = ( "rect", 10, 10, 80, 150);
$im->filledRectangle($rect[1], $rect[2], $rect[3], $rect[4], $black); 
$im->string(gdSmallFont, $rect[3] + 30, $rect [2] + 100, "Click on the image to find out what it is!", $black);

	#draw a circle (for PNG: x_center, y_center, width, height, start_degrees, end_degrees, color)
	# for HTML image map: x_center, y_center, radius
my @circle = ("circle", 200, 50, 30);
$im->arc($circle[1], $circle[2], $circle[3] * 2, $circle[3] * 2, 0, 360, $red);
$im->fill($circle[1], $circle[2], $blue);


	# draw a pentagon
my @pent = ("poly", 300, 50, 360, 70, 330, 90, 270, 90, 240, 70);
my $poly = new GD::Polygon;

$poly->addPt($pent[1], $pent[2]);
$poly->addPt($pent[3], $pent[4]);
$poly->addPt($pent[5], $pent[6]);
$poly->addPt($pent[7], $pent[8]);
$poly->addPt($pent[9], $pent[10]);

$im->filledPolygon($poly, $purple);


print PICFILE $im->png;
close PICFILE;        
################
   #do the HTML

print HTMLFILE <<END;
<html>
<head>
<title>Image map test </title>
</head>

<body>
<h2 align="center">Image map test</h2>

<p><img src="image_map.png" USEMAP="#this_map" alt="image map"></p>

<map name="this_map">

<area shape =\"$rect[0]\" coords=\"$rect[1], $rect[2], $rect[3], $rect[4]\" href="rect.htm" alt="rectangle" target="_blank">
<area shape = \"circle\" coords= \"$circle[1], $circle[2], $circle[3]\" href="circle.htm" alt="circle">
<area shape="$pent[0]" coords="$pent[1], $pent[2], $pent[3], $pent[4],
$pent[5], $pent[6], $pent[7], $pent[8], $pent[9],
$pent[10]" href="/cgi-bin/bios546/pentagon.cgi?input=Shock&emsp;and&ensp;Awe&input2=Harry&emsp;Potter" alt="pentagon">
<area shape="rect" coords="400, 50, 600, 250" href="hidden.htm" alt="the hidden spot!">
<area shap="default" coords = "0, 0, 749, 199"  href="default.htm" alt="everywhere else">

</map>

<body>
</html>
END



HTML code generated by image_map.pl


<html>
<head>
<title>Image map test </title>
</head>

<body>
<h2 align="center">Image map test</h2>

<p><img src="image_map.png" USEMAP="#this_map" alt="image map"></p>

<map name="this_map">

<area shape ="rect" coords="10, 10, 80, 150" href="rect.htm" alt="rectangle" target="_blank">
<area shape = "circle" coords= "200, 50, 30" href="circle.htm" alt="circle">
<area shape="poly" coords="300, 50, 360, 70, 330, 90, 270, 90, 240,
70" href="/cgi-bin/bios546/pentagon.cgi?input=Shock&emsp;and&ensp;Awe&input2=Harry&emsp;Potter" alt="pentagon">
<area shape="rect" coords="400, 50, 600, 250" href="hidden.htm" alt="the hidden spot!">
<area shap="default" coords = "0, 0, 749, 199"  href="default.htm" alt="everywhere else">

</map>

<body>
</html>