in reply to Image::Magick in Mason and STDOUT

You are right with your guess that instead of writing to the "STDOUT" of the Mason component, your $image->Write('png:-') call writes the image somewhere else.

I suppose that this is a mod_perl limitation. Are you running Mason under mod_perl?
In a terminal program or with CGI both commands "print $header_templ" and "system('cat /my/templates/header.html')" will write to the same "STDOUT", but under mod_perl this is not so.

You have two options

  1. Use Mason handler as CGI Script, in this case the following code works
    <%flags> inherit => undef </%flags> <%init> use Image::Magick; my $image = Image::Magick->new; $image->Set(size => '500 x 750'); $image->Read('xc:black'); STDOUT->autoflush(1); $r->content_type('image/png'); $r->send_http_header; $image->Write("png:-"); </%init>
  2. Unfortunately Image::Magick can't write to scalar or filehandle. So let Image::Magick to write the image to some tempfile, then open this tempfile again, read it into a scalar and print to STDOUT, or use the "$r->sendfile" method from mod_perl like this.
    <%flags> inherit => undef </%flags> <%init> use Image::Magick; use File::Temp; my $image = Image::Magick->new; $image->Set(size => '500 x 750'); $image->Read('xc:green'); my $temp = File::Temp->new( DIR => '/tmp', UNLINK => 1); my $temp_file_name = $temp->filename; $image->Write("png:$temp_file_name"); $r->content_type('image/png'); $r->sendfile($temp_file_name); # File::Slurp and print could be used instead of $r->sendfile # #use File::Slurp; #print read_file($temp_file_name); </%init>

Replies are listed 'Best First'.
Re^2: Image::Magick in Mason and STDOUT
by eugeneman42 (Initiate) on Feb 03, 2011 at 00:53 UTC

    Thanks very much for all the replies! Yes, I am using mod_perl and so it looks like in my case using a temporary file is the best approach. I just needed confirmation that I wasn't missing something.

    Thanks also for pointing me to "sendfile()". Somehow I had not seen that before. On a previous web site I read the file chunk by chunk and wrote it out manually in a loop. sendfile() or Slurp looks much easier. These files are only small images so no need to do anything else. On the other site I did, they were downloading files that could be over 100MB!

    Thanks again...