www.webdeveloper.com
Results 1 to 4 of 4

Thread: Displaying Image from Function

  1. #1
    Join Date
    Dec 2008
    Posts
    17

    Question Displaying Image from Function

    Hi,

    I'm having some trouble getting the image created by the following function to display correctly.

    I'm pulling some data out of MySQL then plotting a barchart. However, I can only get the image stream to display, even if I wrap <img scr=" "> around it, and I don't really want to generate a file. How can I call the function, and display the image correctly?

    reports.php:

    Code:
    if (isset($_POST['submit'])) {
    	$output=show_barchart_reports();
    	echo '<img src="'.$output.'">';
    }
    function.php

    Code:
    function show_barchart_reports(){
    $year = 2008;
    $month= 12;
    $numdays = cal_days_in_month(CAL_GREGORIAN, $month, $year) ; 
    for ( $i = 1; $i <= $numdays; $i++) {
    	$sql = "SELECT COUNT(id) FROM `support_requests` WHERE `date` LIKE '$year-$month-$i &#37;'";
    	$result = mysql_query($sql) or die('Query failed: ' . mysql_error());
    	while($row=mysql_fetch_array($result)){
    	$data[$i] = $row['COUNT(id)'];
    	}
      }
    
    // create image 
    $width = 480; 
    $height = 350; 
    $image = imagecreate($width, $height); 
    
    // title 
    $titlefont = 3; 
    
    
    // colors 
    $white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF); 
    $navy = imagecolorallocate($image, 0x00, 0x00, 0x80); 
    $black = imagecolorallocate($image, 0x00, 0x00, 0x00); 
    $gray = imagecolorallocate($image, 0xC0, 0xC0, 0xC0); 
    
    // layout 
    $maxval = max($data); 
    $nval = sizeof($data); 
    
    $vmargin = 20; // top (bottom) vertical margin for title (x-labels) 
    $hmargin = 38; // left horizontal margin for y-labels 
    
    $base = floor(($width - $hmargin) / $nval); // distance between columns 
    
    $ysize = $height - 2 * $vmargin; // y-size of plot 
    $xsize = $nval * $base; // x-size of plot 
    
    
    $txtsz = imagefontwidth($titlefont) * strlen($title); // pixel-width of title 
    
    $xpos = (int)($hmargin + ($xsize - $txtsz)/2); // center the title 
    $xpos = max(1, $xpos); // force positive coordinates 
    $ypos = 3; // distance from top 
    
    imagestring($image, $titlefont, $xpos, $ypos, $title , $black); 
    
    // y labels and grid lines 
    $labelfont = 2; 
    $ngrid = 4; // number of grid lines 
    
    $dydat = $maxval / $ngrid; // data units between grid lines 
    $dypix = $ysize / ($ngrid + 1); // pixels between grid lines 
    
    for ($i = 0; $i <= ($ngrid + 1); $i++) { 
        // iterate over y ticks 
    
        // height of grid line in units of data 
        $ydat = (int)($i * $dydat); 
    
        // height of grid line in pixels
        $ypos = $vmargin + $ysize - (int)($i*$dypix); 
    
        $txtsz = imagefontwidth($labelfont) * strlen($ydat); // pixel-width of label 
        $txtht = imagefontheight($labelfont); // pixel-height of label 
    
        $xpos = (int)(($hmargin - $txtsz) / 2); 
        $xpos = max(1, $xpos); 
    
        imagestring($image, $labelfont, $xpos, 
            $ypos - (int)($txtht/2), $ydat, $black); 
    
        if (!($i == 0) && !($i > $ngrid)) {
            imageline($image, $hmargin - 3, 
                $ypos, $hmargin + $xsize, $ypos, $gray); 
            // don't draw at Y=0 and top 
        }
    } 
    
    // columns and x labels 
    $padding = 3; // half of spacing between columns 
    $yscale = $ysize / (($ngrid+1) * $dydat); // pixels per data unit 
    
    for ($i = 0; list($xval, $yval) = each($data); $i++) { 
    
        // vertical columns 
        $ymax = $vmargin + $ysize; 
        $ymin = $ymax - (int)($yval*$yscale); 
        $xmax = $hmargin + ($i+1)*$base - $padding; 
        $xmin = $hmargin + $i*$base + $padding; 
    
        imagefilledrectangle($image, $xmin, $ymin, $xmax, $ymax, $navy); 
    
        // x labels 
        $txtsz = imagefontwidth($labelfont) * strlen($xval); 
    
        $xpos = $xmin + (int)(($base - $txtsz) / 2); 
        $xpos = max($xmin, $xpos); 
        $ypos = $ymax + 3; // distance from x axis 
    
        imagestring($image, $labelfont, $xpos, $ypos, $xval, $black); 
    } 
    
    // plot frame 
    imagerectangle($image, $hmargin, $vmargin, 
        $hmargin + $xsize, $vmargin + $ysize, $black); 
    
    // flush image 
    header('Content-type: image/gif'); // or "Content-type: image/png" 
    imagegif($image); // or imagepng($image) 
    imagedestroy($image); 
    }
    Last edited by bjblackmore; 01-14-2009 at 10:26 AM.

  2. #2
    Join Date
    Dec 2005
    Posts
    2,984
    This is a rather quick answer, and the only thing I checked code-wise is that you sent out the proper header before using imagegif() or imagepng(), aside from that, you're going about it wrong.

    Seeing how you have your function in a file function.php anyway, remove the actual enclosed function and just have the code as a standalone .php file. Then, all you have to do is include this HTML code in your page:

    HTML Code:
    <img src="function.php" />
    If you need to create several different images using function.php, then pass different parameters to it and use $_GET in the function.php file to get them:

    HTML Code:
    <img src="function.php?param1=value1&param2=value2" />

    Quick answer: Remove the function declaration from function.php and use <img src="function.php" /> in your HTML.

    Remember, imagegif() or imagepng() will output binary image data - you want a ASCII file in your image tag (i.e. <img src="function.php" />) - things make a lot more sense when you think about what you're trying to do.
    Last edited by aj_nsc; 01-14-2009 at 11:04 AM.

  3. #3
    Join Date
    Dec 2008
    Posts
    17
    Hi aj,

    The trouble is, function.php has about 20 other functions, including a user_create function, login & logout function etc.

    Wouldn't this cause problems?

    I guess I could put the image creation function inside a barchart.php, then run my sql query, and call the barchart.php, but I was hoping to try and keep to as few files as possible. So there would be functions.php in a sub dir called \include then in the root just an index.php, which would display different page content depending on the ?action, i.e. index.php?action=login would show the login page, index.php?action=reports would show a page with a selection of reports, including this barchart, and piecharts etc.

    Ben
    Last edited by bjblackmore; 01-14-2009 at 11:31 AM.

  4. #4
    Join Date
    Dec 2005
    Posts
    2,984
    Just like you said - put it in a separate file called barchart.php

    There is a messy (in my opinion) alternative:

    leave it in the functions.php file but enclose it in a conditional statement like:

    PHP Code:
    if($_GET['barchart']) {
       
    //your image code

    and then do this:

    HTML Code:
    <img src="functions.php?barchart=true" />
    Last edited by aj_nsc; 01-14-2009 at 11:53 AM.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles