This is probably done a thousand times before, so this is the 1001st

Use this as a CGI, upload an image and get it back displayed as an HTML table. (not sure why you wanna do such a thing though ;)

View a live version here

Update: I fixed the code which now uses snippets from merlyn's column.
#!/usr/bin/perl -Tw use strict; $|++; use CGI qw/:standard *table/; $CGI::POST_MAX = 200000; # it's already too heavy print header, start_html('Image2HTML'); print h1 ('Image2HTML'); if (param('do')) { eval "use Image::Magick"; die "We need Image::Magick: $@\n" if $@; my $image; my $file = upload('file'); $image = Image::Magick->new or die "Cannot create Image::Magick Object: $image\n"; my $error = $image->Read(file=>$file); if ($error) { print strong('Bad File: '. $error ); } else { $image->Set(magick => 'rgb') && die "Cannot set to RGB, $_"; $image->Scale(geometry => '50x50'); my $width = $image->Get('columns'); my $height = $image->Get('rows'); print start_table({-border=>0, -cellpadding=>0, -cellspacing=>0}); my @blobs = unpack "C*", $image->ImageToBlob(); for (1..$height) { print q|<tr>|; for (1..$width) { print q|<td bgcolor="#|; my ($r,$g,$b) = splice @blobs, 0, 3; print sprintf("%02x%02x%02x", $r, $g, $b); print q|"><img src="/data/trans.gif" width="5" + height="5" /></td>|; } print qq|</tr>\n|; } print end_table; } } print hr; print p(q|This is Image2HTML, just another way to waste computer resources. Use the file field to upload an image (maximum size 200,000 bytes) and get it back as colored HTML &lt;table&gt;. Any kind of image will mostly work.|); print p(q|Note: The image is scaled down/up(?) for your own interest ; +)|); print p(q|This works best with images that have smooth color changes and gradients, brisk turns in colors can come out ugly.|); print start_form('POST', CGI::url(), 'multipart/form-data'); print filefield('file'), submit('do', 'Upload'), br; print end_form, end_html;

He who asks will be a fool for five minutes, but he who doesn't ask will remain a fool for life.

Chady | http://chady.net/

Replies are listed 'Best First'.
•Re: Image2HTML
by merlyn (Sage) on Mar 22, 2003 at 20:16 UTC
    You're doing far too much work for most of this. See how I did the task in my column. ImageToBlob means you don't have to fetch each pixel. A single sprintf to get the colors to hex. And your scaling can be drastically reduced... by default, if you say "resize to 50x50", you get a proportionate scaledown that makes the largest dimension 50 but the smaller dimension appropriate! No math required.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      The fact that I did it that way was that I was trying to do it with GD first, then realised that it's not installed on the test server, and I needed to put a live version, so I switched to Image::Magick, which is the first time I use. So $image->GetPixel($x, $y) became $image->Get("pixel[$x,$y]").

      And besides, the documentation of Image::Magick is still a bit greek to me.

      Thanks for the advice.
      He who asks will be a fool for five minutes, but he who doesn't ask will remain a fool for life.

      Chady | http://chady.net/
Re: Image2HTML
by grantm (Parson) on Mar 22, 2003 at 19:58 UTC
    eval { use Image::Magick };

    I'm guessing the purpose of this line is to defer the overhead of loading Image::Magick until you actually need it. I don't think this line of code successfully achieves that though.

    One of the differences between 'use' and 'require' is that use happens at compile-time while require happens at run-time. So Image::Magick will be loaded as soon as that line is compiled - regardless of the fact that it's in an eval block. You could change it to:

    eval "use Image::Magick";

    Which would work because the compiler wouldn't even see it. Or you could simply say:

    require Image::Magick

    The fact that you're using eval but not checking $@ was a bit of a red flag.

Re: Image2HTML
by bart (Canon) on Mar 23, 2003 at 11:46 UTC
    As been discussed in the ChatterBox, this fails in MSIE 5.5 on Windows. The reason, as derived from the error message, is that MSIE apparently specifies the full local file path as the filename. My bet is that Image::Magick on the server side cannot properly process a file with such a name.

    A possible solution, but untested at this time because I can't get Image::Magick to install even though the ImageMagick command line tools work, would be to use the tmpFileName method from CGI.pm, to get at the name of the temporary file for the upload. See the docs on CGI.pm, search for the text "tmpFileName". It doesn't appear to have a separate entry.

    If all this still fails, you can always try and copy the tempfile from the handle to your own temporary file, using functions available in File::Copy, so you get a filename that Image::Magick can work wirh.