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

I have a website that is generated via perl using CGI::Application along with HTML::Template.

I added a section of the site where the images are dynamically generated by GD. The way I was populating the images was making the src="nameofperlscript.pl?node=image&file=blah". However, since the script to create the images and the webpage is the same it seems silly to have to call the script again (especially since some pages have more than one dynamic image). I would like to load it all in one shot. Is there a way to actually passed the image data directly?

Thanks in advance!
  • Comment on Dymanically Generated Images in Website

Replies are listed 'Best First'.
Re: Dymanically Generated Images in Website
by adrianh (Chancellor) on May 12, 2006 at 10:00 UTC
    I added a section of the site where the images are dynamically generated by GD. The way I was populating the images was making the src="nameofperlscript.pl?node=image&file=blah". However, since the script to create the images and the webpage is the same it seems silly to have to call the script again (especially since some pages have more than one dynamic image). I would like to load it all in one shot. Is there a way to actually passed the image data directly?

    Have the script write the images out to files, and then put the generated image URLs in your HTML? Add a cron job to clean up old images every so often and all done.

Re: Dymanically Generated Images in Website
by dorward (Curate) on May 12, 2006 at 09:10 UTC
    The data: URL Scheme - but Internet Explorer doesn't support it, so in practise a seperate request for each image is the way to go.
      Hello,

      I know it is over a year later, but this post helped me solve my own problem - wanting to create various sizes of images, or even to scale images to a constant size.

      It sounds like since your script generates HTML and images both, you want a way to embed the binary images into the HTML. I am not sure I know of a way to do that. I have done scripts where you use a parameter to trigger an image or HTML based upon the value of the parameter, and then just call the script with the parameter indicating "image" from the page generated by the script in "HTML" mode.

      Or, you could split the script into two separate scripts. I know, not very clean.

      For those interested in my resizing-on-the-fly solution, it is here:
      #!/usr/local/bin/perl # Usage: http://www.yoururl.com/cgi-bin/image_resize.cgi?FILE=/path/to +/image.jpg&SIZE=300 use Image::Resize; use Image::Size; use CGI::Simple; my $q = new CGI::Simple; my $file = $q->param('FILE'); # Path to file on server file system my $size = $q->param('SIZE'); # Desired size of image my ($x, $y, $type) = imgsize($file); $size = ($x > $y) ? $x : $y if (($x < $size) || ($y < $size)); # Will not scale greater than 100% my $image = Image::Resize->new($file); my $gd = $image->resize($size, $size, 1); # 1 = maintain aspect ratio binmode STDOUT; if ((uc($type) eq 'JPG') || (uc($type) eq 'JPEG')) { print(qq|Content-Type: image/jpeg\n\n|); print $gd->jpeg(); } elsif (uc($type) eq 'PNG') { print(qq|Content-Type: image/png\n\n|); print $gd->png(); } elsif (uc($type) eq 'GIF') { print(qq|Content-Type: image/gif\n\n|); print $gd->gif(); }
      I hope this is useful to someone. Enjoy!

      Regards,

      Mark, Webberville, Michigan USA

      I seem to remember having seen people achieve something similar with JavaScript. I'm not really sure. Whatever, even if so then the same portability problems would arise...

        I have used preloading of images in javascript on some pretty big sites. It is worth a look. SOmething similar can be done with CSS.

        jdtoronto

      Hrm... I guess I will just leave it be for now. Thanks for the info!
Re: Dymanically Generated Images in Website
by pajout (Curate) on May 12, 2006 at 11:58 UTC
    I think that your requirement is not really what do you need. I guess that you really require quick loading of your web sites on the client browser. If I am false, you can stop your reading here :>)
    My idea is very simple - you should dynamically resize the images on the server and cache them for next requests. Of course, the first user can be annoyed, but it is acceptable... Additionally, if the images repeats on the web, browsers will cache them.
Re: Dymanically Generated Images in Website
by leocharre (Priest) on May 12, 2006 at 17:55 UTC

    Dude.. make one scripts like image.cgi which spits out the image and your html.cgi or any html will call it like  <img src="/cgi-bin/image.cgi?yup">

    do some testing with the image.cgi first via htp see if it does what you want

    here.. i made this script that spits out text to screen.. You just have to tweak where on your server the ttf file is .. etc. This script is not fully complete.. but.. it works!

    #!/usr/bin/perl -wT use strict; use Image::Magick; use CGI; my $conf = { font_size => 8, font_name=>'/srv/www/htdocs-devel/lib/kroe0555.ttf', img_type=>'png', }; my $t = new CGI(); my $string = $t->param('string'); $string ||='leocharre'; $$conf{string} = untaint( $string ); # attempt untaint $$conf{img_height} = int($$conf{font_size}*1.33) ; $$conf{img_width} = ( length($$conf{string}) * int($$conf{font_size}*0 +.8) ); my $bgcolor = $t->param('bgcolor'); my $fgcolor = $t->param('fgcolor'); $bgcolor ||='#fff'; $fgcolor ||='#000'; $$conf{bgcolor} = untaint_color($bgcolor); $$conf{fgcolor} = untaint_color($fgcolor); generate_img($conf); show_and_exit($conf); sub show_and_exit { my $conf = shift; # read in image and output to browser print(qq|Content-Type: image/$$conf{img_type}\n\n|); binmode STDOUT; $$conf{img}->Write($$conf{img_type}.':-'); exit; } sub generate_img{ my $conf = shift; $$conf{img} = Image::Magick->new; $$conf{img}->Set(size => $$conf{img_width}."x".$$conf{img_height}) +; $$conf{img}->ReadImage('xc:'.$$conf{bgcolor}); $$conf{img}->Annotate( font=> $$conf{font_name}, pointsize=> $$conf{font_size}, fill=> $$conf{fgcolor}, text=> $$conf{string}, gravity=> 'center' ); } sub untaint { my $string= shift; if ($string=~/^([a-zA-Z0-9 \.\:\[\]\{\}\+\-_]+)$/){ return $1; } die ("don't like some chars here = [$string]"); } sub untaint_color { my $color = shift; if ($color=~/^([\d\w#]{3,7})$/){ return $1; } die ("the heck kind of color is this? [$color]"); }