Page 1 of 1

Problem generating image on the fly

Posted: Tue Jul 29, 2008 10:29 pm
by recci
Ok I'm trying to develop a small object orientated program to generate graphs on the fly and then display them as part of web page. But I don't want the graph images to be saved anywhere. The problem is not generating the graphs I can do this no problem its displaying them.

the normal way to do this would be like so :

Code: Select all

'<IMG SRC="components/com_c/plugin/user/plug_1/graph.php" />
and this would show the graph on the fly but how do I do this using class?

You see I want to have one file that will extract the information from the database store them in variables and pass these to the graph.php file to use as the graphs info. I then want to pass the image of the graph back to the original file to be displayed as part of its output.

But I can see no way to do this.

Assuming this is me creating an instance of a new graph.

Code: Select all

$img1 = new graph();
          $img1->set_title(100, 200, 300);
and this is the class of graph, Im using the source code of an open source graph script i found just as an example and trying to add into the class.

Code: Select all

class graph {
 
    var $title1;
    var $title2;
    var $title3;
    var $pic;
 
function set_title( $new_title1, $new_title2, $new_title3) {
 
         $this->title1 = $new_title1;
         $this->title2 = $new_title2;
         $this->title3 = $new_title3;
 
// user defined vars:
// all measurements are in pixels
 
    // any less than 12 will cut off the text
    $bar_height = 15;
 
    // how many pixels to leave between bars (vertically)
    $bar_spacing = 5;
 
    // set grid spacing, any less than 25 will fudge the text. min 50 is preferable.
    $grid_space = 50;
 
    // amount of space to give for bar titles (horizontally)
    $bar_title_space = 70;
 
    // (optional) title of graph (could also come from session)
    $graph_title = "Graph of random stuff. Refresh for more.";
 
    // vertical space to leave for title
    $graph_title_space = 20;
 
    // (optional) graph footer (could also come from session)
    $graph_footer = "Coded By Howard Yeend. puremango.co.uk";
 
    // vertical space to leave for footer
    $graph_footer_space = 20;
 
    // colour of bars
    // 0=red, 1=green, 2=blue, 3=random
    $bar_colour = 0;
 
// end setup
 
// do not modify below this line (I know you will anyway :)
 
// tell browser we're an image
 
 
// get amounts and titles from session.
$amounts = Array($this->title1, $this->title3, $this->title3);
 
// sort amounts (lowest>highest)
asort($amounts);
 
// calculate required width and height of image
$pic_width = $bar_title_space+max($amounts)+($grid_space*1.5);
$pic_height = ($bar_height+$bar_spacing+2)*sizeof($amounts)+20+$graph_title_space+$graph_footer_space;
 
// create image
$pic = ImageCreate($pic_width+1,$pic_height+1);
 
// allocate colours
$white = ImageColorAllocate($pic,255,255,255);
$grey  = ImageColorAllocate($pic,200,200,200);
$lt_grey  = ImageColorAllocate($pic,210,210,210);
$black = ImageColorAllocate($pic,0,0,0);
 
// fill background of image with white
ImageFilledRectangle($pic,0,0,$pic_width,$pic_height,$white);
 
// draw graph title
ImageString($pic,5,($pic_width/2)-(strlen($graph_title)*5),0,$graph_title,$black);
 
// draw graph footer
ImageString($pic, 2,($pic_width/2)-(strlen($graph_footer)*3),$pic_height-$graph_footer_space, $graph_footer, $grey);
 
// draw grid markers
for($x_axis=$bar_title_space ; ($x_axis-$bar_title_space)<max($amounts)+$grid_space ; $x_axis+=$grid_space)
{
    // draw vertical grid marker
    ImageLine($pic,$x_axis,$graph_title_space,$x_axis,$pic_height-$graph_footer_space,$grey);
 
    // draw horizontal line above grid numbers
    ImageLine($pic,$x_axis,($pic_height-$graph_footer_space-25),$x_axis-($bar_title_space+$grid_space),($pic_height-$graph_footer_space-25),$grey);
 
    // draw grid numbers
    ImageString($pic, 3, $x_axis+5, ($pic_height-$graph_footer_space-20), $x_axis-($bar_title_space), $black);
}
 
// draw bars
$y_axis=$graph_title_space;
 
if($bar_colour!=3)
{
    // for a nice smooth fade of colour.
    $col = 180;
    $decrement = intval($col/count($amounts));
}
 
foreach($amounts as $key=>$amount)
{
    // write the bar title
    ImageString($pic, 2, ($bar_title_space-(strlen($key)*6)), $y_axis, $key, $black);
 
    // allocate a colour for this bar
    if($bar_colour==3)
    {
        // random colour
        $tempCol = ImageColorAllocate($pic,rand(50,200),rand(50,200),rand(50,200));
    } else {
 
        $col -= $decrement;
        if($bar_colour==0)
        {
            // faded red
            $tempCol = ImageColorAllocate($pic,255,$col,$col);
        } else if($bar_colour==1)
        {
            // faded green
            // 200 because green just looks too bright otherwise
            $tempCol = ImageColorAllocate($pic,$col,200,$col);
        } else if($bar_colour==2)
        {
            // faded blue
            $tempCol = ImageColorAllocate($pic,$col,$col,255);
        }
    }
 
    // draw the bar
    ImageFilledRectangle($pic,($bar_title_space+1),$y_axis,$amount+$bar_title_space,($y_axis+$bar_height),$tempCol);
 
    if(($amount)<15)
    {
        // if it's a tiny amount, write the amount outside the bar in black
        ImageString($pic, 2, ($amount+3)+$bar_title_space, $y_axis, $amount, $black);
    } else {
        // or if over 15, write the amount inside the bar in white
        // the strlen stuff is to ensure number is aligned with the end of the bar. works quite well, too.
        ImageString($pic, 2, ($amount-(strlen($amount)*6))+$bar_title_space, $y_axis, $amount, $white);
    }
 
    // move down
    $y_axis+=($bar_spacing+1)+$bar_height;
}
}
 
function displayImage(){
header("Content-type: image/png");
   
// output image
imagepng($this->pic);
 
 
 
 
 
// remove image from memory
imagedestroy($this->pic);
 
 
}
 
}
 
 

I would then display the image in the original file like this correct?:

Code: Select all

$img1->displayImage():
But I cant get this to work it just shows gibberish or says the image cant be displayed due to errors.

I know I need to somehow get the $img1->displayImage() into an <IMG SRC = but how do you do this?

cheers

Re: Problem generating image on the fly

Posted: Wed Jul 30, 2008 2:37 am
by onion2k
I know I need to somehow get the $img1->displayImage() into an <IMG SRC = but how do you do this?
You need to rethink your approach. An image is a completely separate world... like a separate page in your site except instead of HTML it's binary data. In order to display an image on a page the user must request the HTML page, and then that page requests the image when it's loaded. You cannot do it with a single call. Your img HTML tag must be a URL that points to the graph script.

Re: Problem generating image on the fly

Posted: Wed Jul 30, 2008 8:22 am
by recci
Ok so what would be the best way to pass the variables to the graph script? I would like to do it the object orientated way but is it possible to use POST or GET method or are these only usable with forms?

Re: Problem generating image on the fly

Posted: Wed Jul 30, 2008 8:32 am
by onion2k
There are several ways:

1. GET. It'll work if you don't have a huge amount of data to pass.

2. Session. Pop all the info into the session in the page that generates the HTML, then load it from there in the image script.

3. Generate the data in the image script. Pass in the minimum amount of information you need to pull the data out of a database or something using GET (eg a ID, date range, etc) and then actually build the graph data in the image script. This is the usual approach.

Re: Problem generating image on the fly

Posted: Wed Jul 30, 2008 8:48 am
by recci
Can you point me in the direction of an example of using Get when its not being used with Html forms etc. I'm still a relative beginner and I still don't fully understand sessions.