Skip to page content or skip to Accesskey List.
Search evolt.org
evolt.org login: or register

Work

Main Page Content

Storage and re-use of images using PHP/GD - Part 2

Rated 4.12 (Ratings: 7) (Add your rating)

Log in to add a comment
(8 comments so far)

Want more?

 
Picture of gvtulder

Gijs van Tulder

Member info | Full bio

User since: February 05, 2002

Last login: September 17, 2007

Articles written: 6

Publishing images on the web is nice, but tedious. It would be nice if we could use a system that automates the uploading, storage, converting and resizing of our images. We could feed that system our images once, and retrieve them later in many different formats. In this article, we will write some scripts that come close to this ideal system. PHP and the GD-library will provide us with an easy method of uploading, searching and publishing our images. (This article is a follow-up on part 1).

In this second part, we will write scripts that you can use to retrieve images and search your image database. To be able to use these scripts, you should have read the first part of this article and saved the scripts we wrote there. You also need the image resize script explained in an earlier article. (This was also stated in part 1.)

What we will do in this second part

We will write scripts that allow us to:

  1. automatically generate an appropriate img tag for an image;
  2. search and find our images;
  3. a popup that shows us a larger version of an image. (This isn't that difficult, but it's a nice example of how we can use our scripts to create img tags.)

Creating the img tag

First, we need a function that, when provided with an image name, does this:

  1. looks up the image information in the database;
  2. calculates the height and width of the image after resizing;
  3. builds the URL to the image retrieval script;
  4. combines these three parts in a nice img tag for use in our html.

The function

In imgtag.php, we start with defining the name of the table containing the image info and connecting to the database. Then, we open a function called img_tag, that will return the img tag.

// define database table containing image info
$img_table = "images";

// connect with database
mysql_connect("yourhost", "youruser", "password");
mysql_select_db("yourdb");

// generates and returns an img-tag
function img_tag($img_file, $attrib) {
	global $img_table;

To create an img tag, our function needs the following arguments passed:

  • $img_file: the 13-character filename of the image, as saved in the database and in the filesystem;
  • $attrib: an array describing how we want the image to be. This associative array consists of the same one-letter keys we used in the resize script.

Preserving the attributes

Not only will the information in $attrib be used in this function, but it will also get passed to the image resize script. The data in $attrib gets changed later in the function, so we should preserve it now to put it in the img tag. The values in the array get concatenated and saved as a string in $attribs.

	// concatenate the attributes in $attrib
	$attribs = "";
	foreach ($attrib as $key => $value) {
		$attribs .= '+'."$key($value)";
	}

Retrieving the image from the database

Now, we have to look in the database and see if our image can be found. We use the provided $img_name to find the right entry.

	// retrieve image info from database
	$result = mysql_query("SELECT * FROM $img_table ".
	            "WHERE img_file='$img_file'");

	// check that an entry is found
	if (mysql_num_rows($result)!=1) {
		return false;
	}

	// get this row
	$img_info = mysql_fetch_array($result);

Calculating image height and width

We've got the image information in the $img_info array. We've also got any possible resize instructions in the $attrib array. Using this information, we can calculate what proportions the image will have. We can then specify the height and width in our img tag.

We use a slightly modified version of the code we used in the image resize script to calculate the new width and height.

	// check for maximum width and height
	if (isset($attrib["x"])) {
		if ($attrib["x"] < $img_info["img_width"]) {
			$attrib["w"] = $attrib["x"];
		}
	}
	if (isset($attrib["y"])) {
		if ($attrib["y"] < $img_info["img_height"]) {
			$attrib["h"] = $attrib["y"];
		}
	}
	
	// check for need to resize
	// convert relative to absolute
	if (isset($attrib["w"])) {
		if (strstr($attrib["w"], "%")) {
			$attrib["w"] = (intval(substr($attrib["w"], 0, -1)) / 100) *
			              $img_info["img_width"];
		}
	}
	if (isset($attrib["h"])) {
		if (strstr($attrib["h"], "%")) {
			$attrib["h"] = (intval(substr($attrib["h"], 0, -1)) / 100) *
			              $img_info["img_height"];
		}
  }

  // resize
  if (isset($attrib["w"]) and isset($attrib["h"])) {
		$out_w = $attrib["w"];
		$out_h = $attrib["h"];
  } elseif (isset($attrib["w"]) and !isset($attrib["h"])) {
		$out_w = $attrib["w"];
		$out_h = $img_info["img_height"] * ($attrib["w"] / $img_info["img_width"]);
  } elseif (!isset($attrib["w"]) and isset($attrib["h"])) {
		$out_w = $img_info["img_width"] * ($attrib["h"] / $img_info["img_height"]);
		$out_h = $attrib["h"];
  } else {
		$out_w = $img_info["img_width"];
		$out_h = $img_info["img_height"];
  }

The img tag

The last thing our function has to do, is actually create the img tag and return that.

	// create and return the img-tag
	$img = '<img src="img.php?f('.$img_file.')'.$attribs.'" '.
	       'width="'.$out_w.'" height="'.$out_h.'" '.
	       'alt="'.$img_info["img_alt"].'" border="0">';

	return $img;
}

The search form

To search the images, we start with a simple form. We can search by title, description, alt-text and image size. Save the form as, for example, search.html. You can change the form to suit your needs, but basically it would look like this:

<form enctype="multipart/form-data" method="post" action="search.php">
<b>Search image</b><br>
Title: <input name="title" type="text"><br>
Description: <input name="descr" type="text"><br>
Alt-text: <input name="alt" type="text"><br>
Width: <select name="width_expr"><option value="=">=</option><option value="&gt;">&gt;</option><option value="&lt;">&lt;</option></select> <input name="width" type="text"><br>
Height: <select name="height_expr"><option value="=">=</option><option value="&gt;">&gt;</option><option value="&lt;">&lt;</option></select> <input name="height" type="text"><br>
Bytes: <select name="bytes_expr"><option value="=">=</option><option value="&gt;">&gt;</option><option value="&lt;">&lt;</option></select> <input name="bytes" type="text"><br>
Type: <select name="type"><option value="">any</option><option value="JPG">JPG</option><option value="PNG">PNG</option></select><br>
<input type="submit" value="Search">
</form>

The search script

The input from the search form is sent to search.php. We will write this script now. After doing a search, it should return the images with the appropriate data. The user should also be able to click on the images for a popup larger version.

The first step is the inclusion of the img tag-script. Normally, you would also have to connect to the database. We already did that in the included script, so that's not necessary here.

include("imgtag.php");

The query

Using the data posted by the form, we can now build a search query. (We only search for width, height and bytes if a value is given.)

// build query
$query = "SELECT * FROM images WHERE ";

// title
$query .= "img_title LIKE '%".$HTTP_POST_VARS["title"]."%' AND ";

// description
$query .= "img_descr LIKE '%".$HTTP_POST_VARS["descr"]."%' AND ";

// alt
$query .= "img_alt LIKE '%".$HTTP_POST_VARS["alt"]."%' AND ";

// width
if (trim($HTTP_POST_VARS["width"])!="") {
	$query .= "img_width".$HTTP_POST_VARS["width_expr"].
	           $HTTP_POST_VARS["width"]." AND ";
}

// height
if (trim($HTTP_POST_VARS["height"])!="") {
	$query .= "img_height".$HTTP_POST_VARS["height_expr"].
	           $HTTP_POST_VARS["height"]." AND ";
}

// bytes
if (trim($HTTP_POST_VARS["bytes"])!="") {
	$query .= "img_bytes".$HTTP_POST_VARS["bytes_expr"].
	           $HTTP_POST_VARS["bytes"]." AND ";
}

// type
$query .= "img_alt LIKE '%".$HTTP_POST_VARS["type"]."%' AND ";

// finish the query (we ended every part with AND)
$query .= "1";

Execute and count the results:

// execute the query
$result = mysql_query($query);

// get the number of results
$num_rows = mysql_num_rows($result);

The results

We start with a basic html-page. We also include a JavaScript function (borrowed from www.vpro.nl) to display the popup with a larger version of the image.

?><html>
<script language="javascript">
/* source: www.vpro.nl */
function bigImage(name) { 
 if (navigator.appName=="Netscape") {
  var imagewindow = window.open('bigimage.php?f='+name,'imagewindow'+name, 'resizable=yes,scrollbars=no,status=1,innerWidth=450,innerHeight=402');
 }
 else {
  var imagewindow = window.open('bigimage.php?f='+name,'imagewindow'+name, 'resizable=yes,scrollbars=yes,status=1,width=450,height=402');
 }
}
</script>
<body>
<h1>Search Results</h1>
<table><?php

Per image, we display one table row. We add a popup link to bigimage.php, a script that displays a larger version of the image. We just link to it for now, we will write bigimage.php in the next step. The img_tag function is used to generate the img tag.

// one row for each result
for ($i=0; $i<$num_rows; $i++) {
	// fetch row
	$img_info = mysql_fetch_array($result);

	// start table row
	echo '<tr><td><a href="bigimage.php?f='.$img_info["img_file"].'" '.
	     'target="_new" onclick="bigImage('."'".$img_info["img_file"]."')".
	     '; return false;">';

	// generate the image tag
	echo img_tag($img_info["img_file"], array("x"=>"250"));

	// echo image information
	echo "</a></td><td><b>".$img_info["img_title"]."</b><br>".
	     $img_info["img_descr"]."<hr><b>Alt:</b> ".$img_info["img_alt"].
	     "<br><b>Pixels:</b> ".$img_info["img_width"]."x".
	     $img_info["img_height"]."<br><b>Bytes:</b> ".
	     $img_info["img_bytes"]."<br><b>Type:</b> ".
	     $img_info["img_type"]."</td></tr>\n";
}

Now just close the table, body and html tags and your search script is finished.

Bigimage.php

As said, this script isn't very complicated. It uses the img_tag function to display a larger version of the image. That image links to the full-size version of the image. Save the code as bigimage.php and you're ready.

<html>
<body>
<?php
include("imgtag.php");

echo '<a href="img.php?f('.$HTTP_GET_VARS["f"].')">';
echo img_tag($HTTP_GET_VARS["f"], array("x"=>"400"));
echo '</a>';
?>
</body>
</html>

What we did in part 2

In this last instalment, we wrote an easy-to-use function that generates img tags based on database data. We also made a search script to find the images in the database. In the last section of the article, we tried writing a real script using our newly created function.

If you're finished with these two parts, you've now got the following files and directories:

  • imgtag.php: the script that generates the img tag;
  • search.html: the search form;
  • search.php: the search script;
  • upload.html: the upload form;
  • upload.php: the upload script;
  • bigimage.php: the pop-up script;
  • img.php: the script that does the actual resizing;
  • bin/: a directory containing the external conversion software;
  • img/: the directory containing the images.

You can also download the complete directory structure as a tar.gz (102 kB).

Gijs van Tulder is a Dutch student. He likes to play with all things web related and fancies himself as a part-time amateur web developer.

Isn't this just Gallery?

Submitted by phule on July 10, 2002 - 09:31.

I'm by far no closer to understanding PHP than linguists are to understanding Linear-A but it seems that you've recreated http://gallery.sourceforge.net here... Is this the case?

login or register to post comments

No, this isn't Gallery

Submitted by gvtulder on July 11, 2002 - 06:04.

Phule,

No, I didn't recreate the Gallery. These scripts are to be used in other scripts, not like the Gallery. The Gallery is a gallery. My scripts can be used in a gallery script. You can use these scripts almost everywhere. Use them on your home page to display a thumbnail and a pop-up. Use them in your CMS to display images on pages.

The Gallery is a complete script, my script can be used in your own script. That's the difference.

login or register to post comments

Fantastic! Very Educational... just what I needed

Submitted by dcweeks on March 11, 2003 - 12:28.

Thanks for a very informative lesson in handling images. This explanation couldn't be more clear. And to counter phule's point... I installed gallery in hopes of using that, but it certainly isn't something that is easy to tightly integrate with my application. Gallery is a fantastic piece of work, but it's going to be faster/cleaner to write what I need from scratch after this lesson than it would be to strip gallery down/mold it to my purpose.

login or register to post comments

Where's the File Extension?

Submitted by nappyhead on October 10, 2005 - 15:34.

My files are uploading, but without the file extension that allows the user to view them. What causes this?

login or register to post comments

Re-sizing in this script

Submitted by zyko on November 11, 2005 - 11:07.

Hello! This script helped me to make a big step forward... But, as I am still newbie I am having problems with re-sizing outputed images. It's now the third day that I am trying to make it work but without effect. Can someone please explain what is the procedure for assigning different dimensions for $img_out... Thanks

login or register to post comments

Did you ever find out the problem nappyhead?

Submitted by 3xca1ibur on November 14, 2005 - 16:18.

I am having a similar problem with the code, did you ever resolver you issue? Rob

login or register to post comments

Re-sizing in this script

Submitted by zyko on November 16, 2005 - 10:53.

I managed to re-size images with defining x; login or register to post comments

Re-sizing in this script

Submitted by zyko on November 16, 2005 - 10:54.

I managed to re-size images with defining x;

img src="img.php?f(blabla)&x(200)

but if you want to get nice image you must use imagecreatetrucolor() and imagecopyresampled()

BUT... as there is no more valid $HTTP_POST_VARS and $HTTP_POST_FILES they should be renamed to $_POST and $_FILES

IMPORTANT! This script does not work if register_globals is set on OFF. That is my problem now.

Anyone with solution?

login or register to post comments

The access keys for this page are: ALT (Control on a Mac) plus:

evolt.orgEvolt.org is an all-volunteer resource for web developers made up of a discussion list, a browser archive, and member-submitted articles. This article is the property of its author, please do not redistribute or use elsewhere without checking with the author.