User Contributed Notes 71 notes

If you are trying to get some of these examples working with a recent version of php and getting the error, "Filename cannot be empty in...", check your second parameter. You can no longer use "", but MUST use "null" (no quotes).

This breaking-change-with-no-note-or-warning may be true of other image functions.

/* * imageXXX() only has two options, save as a file, or send to the browser. * It does not provide you the oppurtunity to manipulate the final GIF/JPG/PNG file stream * So I start the output buffering, use imageXXX() to output the data stream to the browser, * get the contents of the stream, and use clean to silently discard the buffered contents. */ob_start();

I did an experiment with the image quality parameter of the imagejpeg() function when creating jpegs. I found the optimal image quality with file size is taken into account to be 80 - very close to the default value of 75.

Anything over 80 results in an unnecessary increase in file size without much increase in image quality.

Problem: The URL of the current page is displaying in the browser window as an image file. At the same time your manipulated image saves to a file.

Solution: Start with removal of the header() function if you plan to output to a file. The browser is expecting image information; therefore, if you are outputting to a file, you don't need a header() function at all.

If you are outputting to the browser check your imagejpeg() for parameter 2. Set it to 'null' if it has a file name.

Many of the examples programmers illustrate on the web output to the browser and do not save anything to the file system, therefore, the header() function seems essential to image manipulation for the first-time user of the GD library.

This page actually clearly shows the difference between "outputting" to a browser and "saving" to a file, but the code comments don't clearly state what the difference is.

Search for the page on the "header()" function on this website for more details.

Example: Let's say that you are outputting to a jpeg using imagejpeg(). Note the use of the header() function when outputting to the browser.

Every script I was writing was giving me an error.When writing the following code I was able, as a client, to browse the website and save the images (Save image as...) with IE. Yet with Firefox and family the browser tried to save them as 'script_name.php' instead of 'image_name.jpg'.

Don't be like me racking my brain for hours trying to figure out why my xxx.php file outputs http://localhost/xxx.php as a one line response.

Why?

Most likely, you have either:

1. whitespaces before or after the php tags2. need to set header('Content-type: image/jpeg');3. if you have required files...be sure nothing is outputted...no test print statements because page expects image information4. there is an error in your code

in my case, it was 4. there is a reason why the function call base64decode does not work...

it's actually: base64_decode()

by the way, other ways to validate your image encoded in base64 is to use the following tag:

I wanted a function that could resize an image and store the resulting thumbnail in a variable so I could manually save it. Here is the function. I basically strung together two snippets, one from this website (I think) and one by MrCoder here: http://www.webdeveloper.com/forum/showthread.php?t=188298.

I had a problem with denied permissions when trying to upload AND resize an image having safe_mode on. This caused that I couldn't create the new file in which I wanted to resampled the image with nor with imagejpeg() nor with touch() and imagejpeg() after it.

Here is my solution, I didn't test, but it's possible, it is biting some memory:

As you can see, the function moves the uploaded file where you want to save the resampled image (move_uploaded_file is not restricted by safe_mode) and then you can resample the image, because it was created by moving it already.

Note: the directory where you want to save the file must have permissions set to 0777.

for those who get the message "permission denied" or "unable to access": it looks like a problem with your writepermissions to this folder. no matter if you use windows- or linuxserver, be sure the correct user has the permission to write to the correct folder.

I came here looking for something similar to the getJPEGresolution function, but noticed the drawbacks that were pointed out in the last post. So, after drawing on some other code examples on the web, I put together the following function which should always properly return the correct values. (But remember that you still need to have the EXIF extension installed with your instance of PHP for this to work!)

I noticed through testing that my previous function would not always return the data requested... this is due to the fact that some cameras and software dont correctly write the DPI info in the JFIF header... So, my 2nd solution is to read the exif info (if available) and output the first non-zero value as the DPI...

I worked out a script that allows the transfer of alphanumeric data to be placed on an image. The HTML feature is img src and the php feature is imagettftext. This simple code will increment from 1 to 3 on images.

This of course assumes that ghostscript is installed on the server, you have permissions, yada...

Essentially this calls on ghostscript to do the conversion.

So, then, once the new .jpg is created, it needed to be resized to accomodate the UI. Though I could easily do it from the command line with "convert", I was having issues using this command from PHP ( it's not my first language ). I found this thread while groping for a different method, and found an unworkable solution that stimulated me to write the following:

( commented out lines were for debug, but might prove instructional for your own purposes, so I left them in )

[This function takes in a .jpg file to be converted to a thumbnail, the new width you want the thumbnail to be, and the name to which you want the thumbnail saved. It then creates the thumbnail]

Here is a function to resize an image and maintain aspect ratio. It will resize jpeg, gif or png and could easily be modified to add bmp. The name field is the destination of the file minus the file extension:

I could not find any information on changing the DPI information on a JPG file using the GD lib. Since changing this does not resize or scale the actual image, it is only a header-setting.The following snipplet will save your $image to $file and set the DPI to 150.

This is a function that I had developed for a CMS. The idea is that it runs from an upload form. The user uploads a hi-res image, which is copied to the server, a low res one is created (half the width/height of hi res) and a thumbnail is created.

The image is resized matching the smallest side of the image to the thumbnail size (in this example it is 70px). The other side is then resized proportionally (which will end up being more than 70px) and cropped and centered so that it too is 70px.

There is a mixture of imagecopyresized and imagecopyresampled, i have chosen the ones that work best in this situation but imagecopyresampled gives a much nicer image.

/******creating thumbnail******/ //see which is bigger, x or y axis, then resize smaller side to 70. //$resizewidth is the temporary width of the thumbnail, it is in fact the width when it has been resized //using the apect ration and before cropping, at this stage the thumb will not be 70px X 70px //unless it is a square. Same applies to height ($resizeheight). //$thumbx and $thumby are the positions of the cropping are for thumbnail, these are calculated //so that the cropped image is centered.

if ($ims[0]>$ims[1]) {//then the width is bigger $aspectRatio = $ims[1]/70;

Here's another on-the-fly thumbnail creation script.
When I scripted the pictuerviewer on my page, I had all the pictures only in full size and qualit, because I wanted the posibility für visitors to download the pictures.
But as Imagesizes of more than 4 MP are to large for websites, I created thumbnails and the smaller pictures on the fly. But I found out, that the Script needed too much RAM, especially in the thumbnail overview, when I had more then 50 thumbnails to create on the fly at the same time.

So I modified my image creator and my viewer to let them store images, that are created. So only the first visitor has to wait (which is usually me for controlling the uploads und updates), all other visitors get the stored images, which is much faster.

Create different folders. I have a main folder called 'imagesdb' and the tree subfolders full (Full quality images), show (images for the picture viewer) and thumb (for thumbnails in overview).

if($style=="show" || $style=="thumb") {
if(!file_exists($dest_file))
imagejpeg($image_small, $dest_file, 100);
}
// if you have set additional sizese put them in the
// if-arguments, too.
// if someone calls the image.php directly in the
// browser with imagenames allready existing, they
// won't be overwritten

As this website helped me for several times in the past and for creating this script, I hope I can help others with this script saving the time for developing a much more performant solution than an allways-on-the-fly-creating script.

Thanks to Stuart and Darren for the corrections to the create_thumbnail function. Another note on that function: imagecreatefromwbmp was incorrectly used. WBMPs are wireless bitmaps, not windows bitmaps (thanks to clambert at whitecrown), so the thumbnail routine as is will not be able to handle windows bitmaps. See the notes at http://us2.php.net/manual/en/function.imagecreatefromwbmp.php for tips on working with windows bitmaps.

Thanks to Chris dot Calo for the thumbnail snippet. The file type issue is easily resolved by getting the type from the file with getimagesize, and you can handle unsupported types at that stage too. Thus:

It assumes more than that, namely that the filename does not contain the strings '.gif', '.jpg', '.jpeg', '.bmp', or '.png' *anywhere* in the string. Some valid files with special filenames could break this; for example, a file named "used.to.be.a.png.file.gif" would cause this script to attempt to load the file as a PNG. Obviously this is a rare case, but the issue could be easily avoided by using "else ifs" (uses less CPU time) or checking that the extension abuts the end of the string or both.

That said, the whole business could be avoided if PHP didn't clutter the namespace with different functions to do the same thing with different image formats. Ick.

i forgot to say, src path must not be http:// but server path (e.g. for some linux server: src=/home/users/user1/public_html/images/image1.jpg) or relative path, as in example in script (src=test.jpg, src=../test.jpg, src=pictures/test.jpg...)

So.. after messing around with this beast of a function for hours, I discovered that it DOES NOT preserve the resource it is using the create the image, nor do imagepng() or imagegif(). By this I mean that you can not run two imagejpeg(), imagepng() or imagegif() calls on the same resource. Another possibly undocumented quirk... :-(

If you wish to capture the jpg data into a variable, rather than outputting it or saving it into a file (perhaps so you can put it in a database), you might want to consider output buffering. Something along these lines should work:

After trying to get imagejpeg (and imagegif and imagepng) to save an image to a file for some time, it finally dawned on me that perhaps the function would not automatically create the file named in the second parameter.

I then used fopen to create a file prior to the call to imagejpeg and the image was successfully written to the file. It did not seem to matter if fclose was called before or after the call to imagejpeg.

I also tried to create a file outside of php and use it as the target for output, but this initially failled because of permissions. Once I set all write permissions on this also accepted output from imagejpeg.

When displaying an image using imagepng or imagejpeg, you may want/need to call "header("Content-type: image/jpeg")" before the imagepng and imagejpeg functions.It appears that some servers/browers are striping out the default header so the image is not rendered and appears as raw data.(Firefox 1.02+ and OSX Safari for example)

Here is an example of uploading an image, changing its size (width/height) and saving it to a new file. It uses ftp to upload both the original and the resized image. This is usefull in situations where ftp is your only option.

It took me a while to figure it out, so I hope this will save someone else a lot of time :-)

The following assumes that the image is uploaded from a form with a filefield called 'gfx'. I have left out all error checking to keep it simple, so remember to modify the code, to suit your needs.

//$size_in_pixel : Size max of the label in pixel. The size of the picture being //proportional to the original, this value define maximum size //of largest side with dimensions of the picture. Sorry for my english !

Scenario: When pointing your browser directly at a script outputting an image, it displays without problem, but when using it in another page via html (i.e. : img src="x.php?yada=yada" ), you get a broken image.

Reason: *Any* extra data sent along with the image will cause it to not display on other pages. Extra data may include, whitespace characters (check the begginings and ends of your files), or a call to session_start(), which is what got me.

Summary: If you're going to send an image DONT START A SESSION in the script that is outputting the image, and make sure that the PHP delimiters are the first and last things in your file.

Regarding Olav's attempt at avoiding spambots, the code will produce a string of code like requests.php?string=<email_address>, and most spambots will parse that email address right out. You should either create static php scripts to output specific addresses, or do something like save a temporary file on the server with the address you want, and either pass the filename to the makeimage script or have the script open a specific file to check. If you put the address anywhere on the page the spambot will parse it out, including a tag like href="mailto:xxx". That's why people use forms to send email now.

Here is the simple, but powerful script for creating thumbnails on the fly. You can include the script directly to www page - just put it in <img src= tag. with width 150pix. This resizer respects the ASPECT RATIO.Here is the script:<?php// Use it this way: resize.php?pic=imageurl&width=width_in_pixels// kokesh@kokeshnet.com 2004header("Content-type: image/jpeg");$im = imagecreatefromjpeg($pic);$orange = imagecolorallocate($im, 220, 210, 60);$px = (imagesx($im) - 7.5 * strlen($string)) / 2;

I had problem wanting to insert stealth - copyrights into images. I could have done this easily with fopen and such, but I still wanted to use imagejpeg(); and it's quality feature. Well this is one kind of solution what I discovered, and seems to work fine.

As imagejpeg(); inserts imagedata into $ModImg, it does not show the image, but it seems to send headers in that point, so header(); is not needed before echoing variable. Text is viewable with Hex-editors etc.

Some people have never heard of spambots, searching the net for email adresses. How do you avoid this? Some people write emails like: olav-x AT volvo-power.net (mine btw), but this will confuse "stupid" users. The optimal sollution is to have an image with your email adress on.

* When using this function, you have to put it in a non-html php file.. eg. I put it in a makeimage.php file.so, how do you display it?

That way you avoid the overhead of reading and parsing the image, you simply send it directly to the browser.

This is particularly useful if you're using PHP to implement access controls, because it allows you to redirect files from areas of the filesystem browsers can't normally access (although the filename should always come from your script if possible, and not from a URL field, to prevent subverting it with URLs such as image.php?../../../etc/passwd).

Don't forget that JPEG compression has artifacts! And they're not all really obvious. The PHP JPEG compression is pretty decent, but it seems to generally:

-Lighten the image overall, by a reasonable amount (never seen this before, but it will drive graphic designers crazy, you might want to darken the image before compressing it)-Reduce saturation, especially with images with lots of points of different color within a few pixels of each other (this is a documented feature of JPEG)-Seriously mess with blue colors, which is common to all JPEG but really annoying in some situations with blue and black or other detailed blue parts

You might want to consider using imagepng() and outputting a PNG image instead of a JPEG if any of the above affect you, or your image is not very photo-like. Sometimes I have an algorithm compare JPEG to PNG for an image and send the smaller version to the user.

Also, when using imagepng(), you should use imageinterlace() before it 95% of the time. Interlaced JPEGs load progressively, improving in quality as the image loads, so users on slower connections see the whole image at low quality. All this happens without affecting the file size (actually, sometimes the file size is smaller!) or final quality.

Hope this helps a few people out. It's not all that obvious without lots of playing around.

In regards to adding images (or any other binary file) to a database, unless you absolutely *have* to, a MUCH better solution is to simply save the file you create to a directory and update your database with a URL to this file.

When I first started DB development I was hung up with BLOBs and how to make them effectively work with PHP but realized that they can severely impact performance and you also limit what you can do with those files once they're inside the DB.

If you can avoid using BLOBs, and most people can, then by all means just create a look-up table for your file urls and save them to a directory to store the files. File access and scalability will be greatly increased in most cases.

Looks like any specified resolution settings in a JPEG file get lost when using imageJPEG() function in a script.
I had a high resolution JPEG which i added text to with imagestringup() so my customer can print the emailed JPEG as a filled form, but printing both Graphics from Photoshop revealed that any JPEG created is downsampled to 72 dpi, while width and height is kept.
(72 dpi is the standard web resolution)
Nothing to wonder about, but maybe if you read this you dont need to scratch your head :)

I've just read all this AFTER solving the problem in my own little way. (this is re dumping the image into a string)

Im not actually saving the file to a database, but I'm passing it over XML:RPC so I have the constraint that I cant just dump it to browser, and also its not binary safe.. my solution does not involve ob_start(); which might arguably be the more elgant solution. I didnt see my solution listed, so I thought I aught to post it to add to the wealth of knowledge:

[apologies if this is incorrect, im snipping from a large bit of irrelevent XML:RPC catching stuff]

$tmpfname = tempnam ("/tmp", "FOO"); // Generate the temp file

Imagejpeg($im,$tmpfname); // save me image to the file

$temp = fopen($tmpfname,"rb"); // <- Open the file for reading binary

$buffer = fread($temp,filesize($tmpfname)); // get that data into the bufferfclose($temp); // close the fileunlink($tmpfname); // finished with the file, discard

$out = base64_encode($buffer); // encode it (not nessicary if you are using some kind of binary safe function with the info)

ImageJpeg ($img, "", $qlty) or any other Image*() command, with direct output to browser, BE ABSOLUTELY CERTAIN that your php file does not contain any \r, \n, or white spaces before the <? and after the ?> signs.

This should always kept in mind, not only for the file you are executing BUT ALSO FOR ALL THE INCLUDES called during the file execution!

I got totally crazy about this, for a whole weekend :(My php editor did not correctly display a \n sign, as I was locally using a different charset/OS.

If any of the included files, for any reason, prints an error message (or simply a warning) or has any white spaces/return/new line chars before "<?" or after the ">?" signs, the result will be a broken image!

Even looking inside the defective image, it will be quite difficult to notice the unwanted characters, especially if you are using something like the windows' notepad... X(

If nothing is found, with the file/php editors, and you are not sure about your charset compatibility, I suggest to try to edit directly the files on the server, if possible, and search for all unwanted chars. ;)