cosmicsoup has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

I have a perl script that creates a graph and it works, except when I try to embed it in HTML.
#!/usr/local/bin/perl use GD::Graph::pie; my @data = (['A','O','S','I'],[3,16,12,47]); my $mygraph = GD::Graph::pie->new(200, 200); my $myimage = $mygraph->plot(\@data)->png; print "Content-type: image/png\n\n"; print <<end_html; <html><head><title>Current Stats</title></head> <body> <p align="center"> end_html print $myimage; print <<end_html; </p> </body> </html> end_html
What happens is I get an output that looks partially like this:
PNG  IHDR(q;PLTEVttRNS@f IDATx[K8 N{| +P /^s{$ keJ")I‹]BHaR"(R~^֎@q<x쬰 +k xT>ѭ}Z_/o9‹ΦVZזGܹ\' -3N5riB +qgzH:pkB:t]YԬkǟ5N4ΓgSہZf`g̯mm/ +ZWiw6RS8mHqZ>+-:"GGq-r@YPy4߳V +b'nH\-8G>#_d"9ϧc @"DQb\HT4@Ԑ4 +UQ.Ŭ oŨ$xcK7UeRW3G*›7֬܈@ZnL }
If I remove the HTML content, it works. I've even tried calling it like this:
<img src=$myimage>
Unfortunately, I get the same response. Any suggestions?

Louis

Replies are listed 'Best First'.
Re: GD::Graph in HTML
by dragonchild (Archbishop) on Jun 22, 2004 at 20:53 UTC
    You're attempting to print a both ASCII and binary to a socket that's expecting binary (based on the content-type setting). Try not putting the HTML markup and seeing what happens.

    You also might want to look at Graph::Template. It provides a way of creating graphs using the same API that HTML::Template does.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

    I shouldn't have to say this, but any code, unless otherwise stated, is untested

Re: GD::Graph in HTML
by hardburn (Abbot) on Jun 22, 2004 at 20:56 UTC

    What you're actually doing is printing a PNG image into the HTML document, which is a bunch of binary data (thus the jiberish). The HTML source tag needs a file which sends back an image, but that file could be a CGI. So what you can do is make a regular HTML document which contains an image tag pointing to your CGI. That CGI will just print out the PNG image data (print $myimage;, no HTML needed in the output).

    ----
    send money to your kernel via the boot loader.. This and more wisdom available from Markov Hardburn.

Re: GD::Graph in HTML
by injunjoel (Priest) on Jun 22, 2004 at 23:19 UTC
    Greetings all,
    I would suggest splitting out your graph creation into its own script that prints its own header and displays your graph... then you can embed it in your html with an image tag.
    example
    Your script for creating the graph
    #!/usr/local/bin/perl -w use strict; #ALWAYS!!!! use GD::Graph::pie; my @data = (['A','O','S','I'],[3,16,12,47]); my $mygraph = GD::Graph::pie->new(200, 200); my $myimage = $mygraph->plot(\@data)->png; print "Content-type: image/png\n\n"; print $myimage; exit;

    The image tag to embed in your HTML output.
    <img src="your/script/here.cgi?key=value(if needed)">

    rather than
    <img src=$myimage>

    This is actually what I do when I am displaying binary data from a database Blob field.
    Hope that helps. Let me know if you have any questions.

    -injunjoel
    "I do not feel obliged to believe that the same God who endowed us with sense, reason and intellect has intended us to forego their use." -Galileo
Re: GD::Graph in HTML
by kryberg (Pilgrim) on Jun 22, 2004 at 21:13 UTC
    Here's a snippet of some code where I did something similar:
    #plot data to a png graph # I have a temporary image because I end up splicing # two images together open(GRAPH, "+>./supportfiles/temp.png") or die("Cannot open temp grap +h file: $!") ; my $gd = $graph->plot($data) or die $graph->error; binmode GRAPH; print GRAPH $gd->png; seek GRAPH, 0, 0; my $gdgraph = newFromPng GD::Image(\*GRAPH) or die ("Cannot read into +GD object: $ !" ); close GRAPH; # second, pre-existing image I supperimpose on the first open(LOGO, "<./supportfiles/logo.png") or die("Cannot open logo file: +$!" ); my $image = newFromPng GD::Image(\*LOGO) or die ("Cannot read logo int +o GD object: $!" ); $gdgraph->colorAllocate(255,255,255); $gdgraph->copy($image,460,368,0,0,80,22); # File name for final image my $filename = "$number" . "_" . "$huc" . ".png"; open(IMG, ">./charts/$filename") or die $!; binmode IMG; print IMG $gdgraph->png;
    You can actually do this dynamically with perl and HTML and not save an actual file. It all has to do with the binmode. If you want to do it dynamically, expermient with something like:
    print STDOUT $query->header(-type=>'image/png'); binmode STDOUT; print STDOUT $image->png();
Re: GD::Graph in HTML
by hossman (Prior) on Jun 23, 2004 at 16:47 UTC
Re: GD::Graph in HTML
by Anonymous Monk on Mar 03, 2016 at 18:41 UTC
    You need to use: print $myimage->png;