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 1

Rated 4.03 (Ratings: 9) (Add your rating)

Log in to add a comment
(13 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 an extension of an earlier article, which described how to write a script that can resize and convert images on the fly. You will need that script here.

Our wish list

We want to have a system that we can use to:

  1. upload and store our images;
  2. search our image database;
  3. publish our images on our web site;
  4. maintain a central list of alt-tags.

We also want our system as flexible as possible. To make it easy to use, it has to accept and convert the following range of image types: jpeg, gif, png, bmp. Those formats have to be converted to jpeg and png, and stored for later use. When retrieving our images, it would be nice if we could resize them as we need.

In this first of two instalments, we will build the scripts that upload, convert and store the images. In the second instalment, we will write a simple search function and the image retrieval-part.

What we need

The mission described above can be accomplished using the following open-source tools and libraries:

  • PHP, compiled with the GD-library, MySQL and jpeg-support;
  • a working MySQL-server for storing the image info;
  • a working instance of the image conversion and resizing script I described in this article;
  • the following converters found in the netpbm-toolkit: bmptoppm, , pngtopnm, pnmtopng, ppmtogif;
  • the gif2png utility.

You can compile your own versions of these conversion utilities. You can also download the binary versions I compiled for Linux i386 (97 kB download).

The database layout

When uploading, we will store the image information in a MySQL-table for later use. In the database, we will store the following information:

  • the filename of the image (the generated 13 character name);
  • the image type (jpeg or png);
  • the image width and height;
  • the size of the image in bytes;
  • the title of the image for our own search purposes;
  • a description of the image, also to search and find;
  • the alt-tag of the image, to display when publishing the image.

Create the database using the following SQL-query.

CREATE TABLE images (
  img_id mediumint(9) NOT NULL auto_increment,
  img_file varchar(13) NOT NULL default '',
  img_type enum('JPG','PNG') NOT NULL default 'JPG',
  img_height smallint(6) NOT NULL default '0',
  img_width smallint(6) NOT NULL default '0',
  img_bytes mediumint(9) NOT NULL default '0',
  img_title tinytext NOT NULL,
  img_descr mediumtext NOT NULL,
  img_alt tinytext NOT NULL,
  PRIMARY KEY  (img_id)
) TYPE=MyISAM;

Part 1: The upload script

In this first instalment, we will write the scripts that handle the uploading, converting and storing of the image. We will concentrate on the scripting; you can design your own interface.

The form

The user will fill in a simple html-form to add an image to the database. Save this form as upload.html.

<form enctype="multipart/form-data" method="post" action="upload.php">
<b>Upload image</b><br>
Select image: <input name="file" type="file"><br>
Title: <input name="title" type="text"><br>
Description: <textarea name="descr"></textarea><br>
Alt-text: <input name="alt" type="text"><br>
<input type="submit" value="Upload">
</form>

The script

The form is sent to upload.php. Save the script as upload.php.

Settings

// define the base image dir 
$base_img_dir = "./img/";

// define location of image conversion programs
$img_conv_dir = "./bin/";

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

// connect with database
mysql_connect("yourhost", "youruser", "yourpass");
mysql_select_db("yourtable");

Moving the file

// generate unique id for use in filename
$uniq = uniqid("");

// new file name
$filename = $base_img_dir.$uniq;

// move uploaded file to destination
move_uploaded_file($HTTP_POST_FILES["file"]["tmp_name"], $filename);

First, we generate a 13 characters long, unique name for our image. This name will be used to save the image in the file system. We save the value of $uniq in the database, to identify the image. The uploaded file is moved to its destination.

Handling the image

// retrieve image info
$imginfo = getimagesize($filename);

// handle image according to type
switch ($imginfo[2]) {
    case 1: // gif
        // convert gif to png using shell command
        $command = $img_conv_dir."gif2png $filename";
        exec($command);
        
        // remove original gif file and rename converted png
        unlink($filename);
        rename("$filename.png", $filename);
        
        // check png image by loading and saving the file
        //  to prevent wrong uploaded files and errors
        $img = imagecreatefrompng($filename);
        imagepng($img, $filename);
        imagedestroy($img);
        
        // set image type to png
        $img_type = "PNG";
        break;

We start handling the file by retrieving the image info using the getimagesize()-method. $imginfo[2] contains a number identifying the image type. In case of a gif-file, we first need to convert it to the more usable png-format. With the gif2png shell command, the image is converted and saved as $filename.png. We then just have to save the image with the original filename, without extension, to continue.

To check for wrong uploaded files, not-png for instance, we let PHP load the image and save it again. By doing so, we get possible errors when uploading, not when retrieving.

    case 2: // jpeg
        // check jpeg image by loading and saving the file
        //  to prevent wrong uploaded files and errors
        $img = imagecreatefromjpeg($filename);
        imagejpeg($img, $filename);
        imagedestroy($img);
        
        // set image type to jpeg
        $img_type = "JPG";
        break;

    case 3: // png
        // check png image by loading and saving the file
        //  to prevent wrong uploaded files and errors
        $img = imagecreatefrompng($filename);
        imagepng($img, $filename);
        imagedestroy($img);
        
        // set image type to png
        $img_type = "PNG";
        break;

Png and jpeg-images are handled just like gif-files, with the only exception that they do not have to be converted to a png-file.

    case 4: // bmp
        // rename file to bmp
        rename($filename, "$filename.bmp");
        
        // convert bmp to png using shell command
        $command = $img_conv_dir."bmptoppm $filename.bmp | ".
                   $img_conv_dir."pnmtopng > $filename";
        exec($command);
        
        // remove original bmp
        unlink("$filename.bmp");
        
        // check png image by loading and saving the file
        //  to prevent wrong uploaded files and errors
        $img = imagecreatefrompng($filename);
        imagepng($img, $filename);
        imagedestroy($img);
        
        // set image type to png
        $img_type = "PNG";
        break;

    default:
        break;
}

The bmp format needs to be converted. We use the programs bmptoppm and pnmtopng to get a nice png. bmptoppm for some reason only accepts files that have a .bmp-extension, so we will have to rename the uploaded file before running it.

Collecting the last bits of information

// retrieve image file size
$imgbytes = filesize($filename);

After we have asked filesize() for the size of the image, we now know the following about our image:

  1. the unique filename ($uniq);
  2. the image type ($img_type);
  3. the image height ($imginfo[1]);
  4. the image width ($imginfo[0]);
  5. the image size ($imgbytes);
  6. the image title ($ title );
  7. the image description ($descr);
  8. the image alt-tag ($alt).

The last step is the actually saving of this information in the database and displaying a message for the user.

// insert image into db
mysql_query("INSERT INTO $img_table (img_file, img_type, img_height,
   img_width, img_bytes, img_title, img_descr, img_alt)
  VALUES('$uniq', '$img_type', ".$imginfo[1].", ".$imginfo[0].",
         $imgbytes, '".addslashes($HTTP_POST_VARS["title"])."', '".
         addslashes($HTTP_POST_VARS["descr"])."',
         '".addslashes($HTTP_POST_VARS["alt"])."');");

// display some information
echo "Image uploaded.<br><img src=\"img.php?f($uniq)+x(300)\"><br>".
     "URL: img.php?f($uniq)";

What we did in part 1

We just made our user an image upload form, with which we can submit the information and the image. We also wrote a script that handles the upload. The image is then converted from jpeg, png, bmp or gif to a better usable jpeg of png format and saved. After this step, the information about the image is saved to the database for later use.

You can download the full script we wrote in this article.

Part 2

In part 2 we will build the other half of our image storage system, containing an image search function and an PHP-object to get the image from the database and generate the appropriate img-tag.

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.

Nice...

Submitted by jesteruk on May 20, 2002 - 16:51.

I take it you like the GD library huh? hehe, well-written article, interesting.

login or register to post comments

Supernice...

Submitted by deadL0ck on June 1, 2002 - 03:37.

I have always wanted to know how to do this!

login or register to post comments

move_uploaded_file()

Submitted by tmote on July 11, 2002 - 09:29.

I am using a shared server @ Interland and cannot upgrade (nor convince them to upgrade) to PHP v 4.0.3+ which is required to use the move_uploaded_file function. Currently I am running PHP v4.0.1pl2. What fucntion(s) will I need to accomplish this task?

login or register to post comments

move_uploaded_file()

Submitted by gvtulder on July 11, 2002 - 09:48.

move_uploaded_file() isn't required for this task. It's just more safe. You can replace the move_uploaded_file()-line with:

copy($HTTP_POST_FILES["file"]["tmp_name"], $filename);

That copies the file to its destination. The temporary file will be automatically deleted by PHP at the end of the script.

login or register to post comments

Multiple images

Submitted by driver on July 16, 2002 - 02:06.

I have edited this script to suit myself. I have added extra fields in the db and form. But what I cant seem to do is manage to upload more than one image at the same time. I can get the image into the 'img' folder on my server, but I cant get the image data to be written to the db so I can retrieve later when serching. Any suggestions??

login or register to post comments

Database saves only the link to the image.

Submitted by kyizin on March 14, 2003 - 17:41.

When I tested this scripts and looked at the database creation scripts. I found out that the script saves only image information and link to the image on the disk. What I want to know is how to save the actual image file as BLOB datatype and how to retrieve the image from database.

login or register to post comments

Re: Database saves only the link to the image

Submitted by gvtulder on March 15, 2003 - 03:39.

Saving the images as a normal file is a more efficient solution for normal use, but if you really need it, it's possible. I found this article that explains how to save binary data in a MySQL database.

login or register to post comments

can't see pictures except placeholders / netscape

Submitted by publicname on March 24, 2003 - 01:50.

This is a fantastic script, however I am not able to see any image exept empty placeholder when i retrieve search result into IE from LOACLHOST server. if I drag /IMG/files into IE, i am able to see the pictures but still not via scripts. Generally is there any way to force extension to be written into /IMG/filename? I wish to modify so that able to upload zip .txt and ... extensions. it seems it is not compatible with netscape, any reason for that?

login or register to post comments

Same problem: can't see pictures except placehold

Submitted by weem on March 1, 2004 - 05:47.

Is it because I use GD2? Have the same problem with other gd examples. is this a configuration problem or are the function names in GD2 different.

login or register to post comments

grayscale?

Submitted by devision on March 10, 2005 - 06:39.

Everything worked great with this process, very well written artcile.. however i'm experiencing an issue where images (jpgs) are made grayscale when they are ran through the script? however, gifs work properly -- am i left to believe that it is an issue with the jpeg conversion tools in netpbm? can anyone offer an idea of why this is happening?

login or register to post comments

storage and reuse of images

Submitted by patrickoul on March 12, 2007 - 01:48.

The article is greate and the example is not working form me. Do Ineed to do something else. In case anybody is ready to help appreciate that.

login or register to post comments

Can not see Image

Submitted by ashafak on February 10, 2010 - 15:06.

Script is working perfectly but i can not see image in it . Kindly suggest solution for the same

login or register to post comments

can not see image also

Submitted by moonknight77tt on October 22, 2010 - 12:43.

hello im having the same problem with the image not being displayed. any suggestions?

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.