View Full Version : Piechart - no image only data stream?

12-15-2008, 03:17 PM

I'm using the PHP code from the following site to create a piechart: http://www.peters1.dk/webtools/php/lagkage.php

But, rather than placing the code in a page, then supplying the data in the url (i.e. piechart.php?data=10*20*30&label=red*blue*green), I've added it to a function, which pulls the data out of a mysql database. This function is run from a form/submit button, once users select whether to display data for the month or year.

However, when I submit the button, IE pops up with the file download box, asking if you want to open or save the page, when you view the page, its a html with the correct header & footer, but in between where the image should be, is what looks like a data stream, i.e.:
JFIF    <CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 100 C 

I'm not sure why IE isn't displaying the image correctly, the image function is set to content-type: image/jpg

function OutputImage($img)
header('Content-type: image/jpg');

Can anyone advise how to get the image displayed correctly?

Many thanks


12-15-2008, 03:23 PM
The original script output the image in an <img src="url_that_results_in_the_image_being_ouput" /> tag because that is the only way to place an image on a web page. You cannot output image data directly on a web page.

12-15-2008, 03:42 PM
What you see is simply ascii representation of an image. You cannot combine the image data with any textual output to a browser and send an image header. Though you can pack it into a function, it needs to stand alone (or accessed on its own) and used in the image source. This is why most image handling is done by a single script, ie: image.php?id=yourimageidhere for example. If you pass a second parameter to you're content type of true, you may be able to override the text/* output of the file into an image type. Seems like a waste though.

The original script output the image in an <img src="url_that_results_in_the_image_being_ouput" /> tag because that is the only way to place an image on a web page. You cannot output image data directly on a web page.

That is mainly true. Though I think more modern browsers are supporting it, you can actually shove a base64 encoded string into an image source o.O. I don't know what its length limitations are though; I think it will only work for smaller images.
I think it works in IE7 and FF2+, something like this:

<img src="data:image/{imagetypehere};base64,4dffkjtk55909af8434...==" alt="" />

This is such a ridiculous way of handling images though. I have yet to see anybody use it for anything more than sample code, so with that in mind, always point you're source at an actual filesystem image instead (or dynamically generated binary for the image).

12-15-2008, 03:43 PM
Ah yes, I also had to get the OutputImage function to give the image a name, as it was set to just NULL, so I set it to report.jpg, then in the original PHP/HTML page inserted the <img src=> tag:

if (isset($_POST['submit'])) {
echo "<img src=report.jpg>";

12-15-2008, 03:51 PM
You shouldn't need to actually create the image file.
If you have an image generation script that outputs just the image binary with the correct content-type, you should be able to use that as you're image source.
However, there are other considerations (which may better suit you're purposes). For example, if this is a highly accessed image and changes only rarely, you're better off writing it to an actual image file than to dynamically generate it on the fly. This is for simple resource saving; image generation takes a lot of memory to process.

If you're learning to do this, the best thing to do is to create a simple image and start by reading and outputting the image using PHP. After that, roll into GD to manipulate you're image, or if you're a really adventurous programmer (like me), roll out bit manipulations on it. Sweet. I've corrupted a many a images doing this ;). Its hard to mimic structs in PHP...

12-15-2008, 03:51 PM
Saving a dynamically generated image to a single file name and then putting that file name into an <img /> tag will result in concurrent visitors getting the wrong image.

If you expect more than one visitor at a time to your site and the data they request will result in different charts, then you need to dynamically output the image after it is created or you need to save it using unique file names (that you then need to clean up and delete after they are no longer needed.)

12-15-2008, 03:54 PM
Wow, that rocks. We just covered both potential (and opposing) perspectives on almost simultaneous posts o.O

12-15-2008, 04:11 PM
Thanks for the help guys.

I seem to have found a problem using the named file output, during my testing, selecting monthly & yearly reports was giving the same image, I assumed it was an IE caching problem, so I set the image name to be "reports".$time.".jpg" and set $time = time(); so each image was unique. However, after looking on the webserver at the site room, it was becoming full of report*.jpg images, for some reason they aren't getting deleted, even though I have ImageDestroy($img); in my function, right after OutputImage($img);

The site won't be heavily used for reports, just myself, and my manager. The data is stored in a mysql database, and is a database of helpdesk requests. We want to be able to generate a piechart showing requests/user. The piechart script found on that link in my original post gives a good image, and seems to work well when acessing directly, i.e.
<img src="piechart.php?data=50*20*10&label=Open*Close*Pending">

Although, thinking about it, I could still link to that piechart.php as an external page, rather than using a function, but generate the data & label information in the URL dymanically. This might be easier, and solve the caching & file deletion problem.


12-15-2008, 04:20 PM
Add ?t=time() at the end of the image instead. Simply tricks the browser into assuming its a brand new file and therefore caches a new copy of it.
Funny, I've always has this problem with Firefox. Course, thats with dynamic images, but its the same concept.

12-15-2008, 04:51 PM
Linking directly to the script, and just constructing the data in the function seems to have solved all the problems :-)

The mySQL query now creates the end URL data resulting in:

return "?data=". $count ."&label=". $users;

which is then added to the piechart.php script using:

$data = show_reports();
echo "<img src=\"piechart.php".$data."\">";

The image no longer gets cached, and as it isn't created in the first place, there isn't a mass of jpg files left in the site dir.

Thanks for the help guys, this is a much easier, and quicker way, don't know why I decided to go down the whole function route this morning, must have been a Monday morning madness/lack of coffee!

Thanks again