HTMLize an image

FW: This code performs the rather esoteric function of converting an image file to a raw HTML page, using a <table> tag with a cell for each pixel. The output is, of course, huge, and will crash some older browsers or systems. The only use I can think of this is if you had a hosting service which had tons of bandwidth but didn't support images, and really needed one.

Yes, I realize this isn't quite standard HTML with doctypes and all that, but for something this useless I don't think it's worth being precise ;)

  proc htmlize {image_file save_to} {
    set page [open $save_to w]

    set source [image create photo -file $image_file]
    puts -nonewline $page {<html><head></head><body><table border=0 cellspacing=0 cellpadding=0>}
    foreach row [$source data] {
      puts -nonewline $page {<tr>}
      foreach color $row {
        puts -nonewline $page "<td width=1 height=1 bgcolor=$color></td>"
      }
      puts -nonewline $page {</tr>}
    }
    puts -nonewline $page {</table></body></html>}

    close $page
  }

Feedback: meh: Found it quite useful in CGI scripts for human verification. Stops them just matching the image filename to a set of corresponding characters - with some modification, random parts of the image can be modified to further deter non-human usage. Good work :)

FW: Thanks. It happens that the more accepted way to achieve the first effect is by using a second script that sends through the appropriate image file (or generates one). To alter random parts or otherwise custom generate CAPTCHAs you can use the image tools directly.

meh: Oh, it was more a temporary solution until I figured out how to use TclMagick :p

Sarnold: You may gain bandwidth (I guess that would help) by generating all this HTML code with Javascript. It may be something like :

 function line(row) {
     var i;
     // increment by steps 6 because the color is stored in 6 characters
     for (i=0;i<row.length;i+=6) {
         document.writeln("<td width=1 height=1 bgcolor="+row.substring(i,i+5)+"></td>");
     }
 }
 function nextline() {document.write("</tr><tr>");}

then, in your HTML body, just append:

 <table><tr>
 <script language=javascript>
  line("FFFFFFF...."); // put some pixels, you can split 1 line into n calls
  ...
  nextline(); // go to the next line by writing </tr><tr>
  line("DDDDDDDDD...");
  ...
  line("FFFFFFFFF..."); // the last call should not be nextline(), because we do not want to start a new line
 </script>
 <!-- end here the line, and the table also -->
 </tr></table>