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

I'm writing a cgi script that I intend to call as an image:
<img src="dynamicImage.cgi">
The basic idea is that the image will be semi-random, composed of a collage of existing images. I havn't been able to find any good examples of reading / editing / returning valid image files. I know that the return statement is going to HTTP, so it has to start with "Content-type: image/gif\n\n", but what comes after that? I plan to work with GIF, but really almost any format would be ok. Does anyone have any suggestions? Places I could find examples? Examples? :)
Gracias

Replies are listed 'Best First'.
Re: Working with images
by larsen (Parson) on Mar 31, 2002 at 22:31 UTC
    A good place to get inspiration could be Graphic RSS. In the page, among other things, you'll find a reference to Image::Magick, a very powerful module to work with images. I'd like to mention also GD, simpler but useful.
      Image::Magick looks quite useful. I'll have to give that a try. By the way, after a cursory glance through the documentation, I didn't see how I could return the image directly to the caller, rather then saving it. Do you know how to do that?
      Gracias

        You'll want to print it to standard output. Per the docs, this would be:

        $image->Write("gif:-");

        perl -pe '"I lo*`+$^X$\"$]!$/"=~m%(.*)%s;$_=$1;y^`+*^e v^#$&V"+@( NO CARRIER'

Re: Working with images
by emilford (Friar) on Mar 31, 2002 at 23:11 UTC
Re: Working with images
by Ryszard (Priest) on Apr 01, 2002 at 21:57 UTC
    Co-incidently I've embarked on this mission also. I want to create some graphs dynamically, overlay an image map and pump it all out to the browser without hitting the disk.

    The code is extremely rough at this stage, and is an example of what not to put into production. There is much polishing to do.

    #!/usr/bin/perl -w use GD::Graph::bars; use GD::Graph::Map; use CGI qw/:standard/; use Date::Calc qw/Delta_Days Date_to_Text Add_Delta_Days/; my @data = ( ["node1"], ); my @dates = ("11-3-2002","12-4-2002", "15-5-2002","31-12-2002"); my $startdate = $dates[0]; for (my $i=0;$i<$#dates;$i+=1){ my @basedate = split(/-/, $dates[$i] ); my @nextdate = split(/-/, $dates[$i+1]); my $dd = Delta_Days($basedate[2],$basedate[1],$basedate[0], $nextdate[2],$nextdate[1],$nextdate[0]); push @data, [$dd]; } my $my_graph = new GD::Graph::bars(200,500); $my_graph->set( x_label => 'Node', y_label => 'Date', title => "Technology", y_max_value => 365, y_tick_number => 10, y_label_skip => 2, y_number_format => \&y_format, cumulate => 1, borderclrs => 'black', bar_spacing => 4, bar_width => 30, values_vertical => 1, accntclr => 'lgreen', transparent => 0, ); sub y_format { my $val = shift; my @ysd = split(/-/, $startdate); my @delta = Add_Delta_Days($ysd[2],$ysd[1],$ysd[0], int($val) ); return substr(Date_to_Text(@delta), 4); } $my_graph->set_legend( qw(COM21 euroDOCSIS DOCSIS)); my $format= $my_graph->export_format; if (length (my $info = path_info())) { print header("image/$format"), $my_graph->plot(\@data)->$format(); my $map = new GD::Graph::Map($my_graph, info => '%l: x=%x y=%y' +); } print header; my $session = "graph"; my $map = new GD::Graph::Map($my_graph, info => '%l: x=%x y=%y'); print "hey this is way cool dude"; print $map->imagemap(url()."/$session.png", \@data, noImgMarkup=>1);

    The generated image is a one stacked bar, with dates on the y.

    Merlyn has a column that sends a dynamically created image to the browser, from which I've learnt, and adapted.