PHP provides an amazing library called Graphics Draw ( GD ) to generate images. You can create and output the images directly to the browser or you can store it as a image file. For example Google Charts API generates QR Code images and outputs it directly to the browser. You can do the same with PHP GD functions that can generate jpg, gif or png and send them as output, but the default content type of PHP is text or html. So when you output an image to the browser you need to tell the browser, hey look! now I am sending an image, you should not treat it as text or html.
For example when the browser requests a PHP or HTML page, browsers sends some information to the server, the server then looks for the file requested, if it is available it sends back the content along with some information of how to treat the content. That “some information” is called header.
Header information is sent using header() in PHP by passing the header string as parameter. There are lots of header strings for various operations and writing a complete list will be beyond the scope of this article. But let us look into setting up headers for image output. You can clearly see the headers received by the browser when a page is loaded. You can see this in real-time by installing Firebug.
For example take a look at the following 2 screenshots.
You could see Content-Type changes for html and images sent to the browser, but these headers must be sent to the browser before you send any other output.
Headers already sent – What? I dint send any..
This is the usual panic attack faced by PHP programmers, but let me tell you don’t panic. The problem might have occurred for the following reasons.
- You might have used echo, print or other functions like var_dump() that produces output before sending the header.
- <html> tags before <?php – placing an <html> tag before sending header will send the output to the browser.
Yeah, I can hear you saying – “I am not that stupid”. Well, you are not, but the error might have occurred for the following reasons.
- Blank white-spaces before <?php – a single white space is enough to give you a mild heart attack.
- UTF-8 Byte Order Mark( BOM ) – I would like to call it BOM(B) ready to explode as soon as you execute your PHP script. The byte order mark (BOM) is a Unicode character used to signal the byte order of a text file or stream.
- error messages, warnings or notices that occurred somewhere before sending the header.
Consider this example below – a simple php script that generates an image.
<?php $im = imagecreatetruecolor( 200, 200 ); $color = imagecolorallocate( $im, 255, 0, 0 ); imageellipse( $im, 100, 100, 150, 150, $color ); header( "Content-type: image/png" ); imagepng( $im );
The above code generates an image, and in the final line imagepng() function sends the image directly to the browser, so we need to tell the browser that we are sending an image and so the header() function specifying the content type is set. In the above code we don’t have any output functions before the header is sent, no blank space before PHP tag, but still you will get the error “Headers already sent”. Most of the time this error occurs because of the BOM character that is embedded within the document while saving them. You could remove them easily. Follow these simple steps.
- Install Notepad++
- From the – Encoding menu at the top, select “Convert to UTF-8 without BOM”, then save it.
You will get rid of that BOM character and your PHP will run fine. Now the sample code will show an image in the browser, there arises another problem – You try to save that image, and you will see that while saving images generated by PHP your image filename will be the same as the PHP script that sent the image to the browser.
You can see .php is the extension instead of png, jpg or gif. Now if you want to give a proper name and type for the image output that is sent to the browser you have to send another header like the one below.
header("Content-Disposition: inline; filename=myimage.png");
The above line says the content sent to the browser is to be opened inline and to be called as myimage.png. But there is also another type of Content-Disposition, that is attachment. The difference between inline and attachment is
- inline – tells the browser to display it inline, the browser will attempt to display the content, for example png, jpg, gif, pdf files etc. But if the browser could not to display the content it will show the download dialog to save it in some other location.
- attachment – will force the browser to open the download dialog, so the browser will not attempt to display the content even if it can, but shows the download dialog.