« Create your own drawing · Highest rated · Vote drawings · How this works »

How to generate images from html using PHP, htmldoc & convert

All images on this site are generated by people who visited and took the time to play with the grid. If you click on the 'Create your own drawing' link, you get a table with a lot of tiny cells which you can color with the selector on the right. At the moment, you have to click cell by cell. If I find some time, I'll upgrade the system so you can hold your mouse button to color the grid - although, looking at the submitted pictures, I think the system works well for now.

If a user submits his drawing to the database, a table is generated with a lot of cells holding each color as the background-color. For a while, I just displayed this html onto the screen, but the browsers and my bandwith didn't really like this option. So I looked for a fast and simple solution to convert the html to an image on the fly when I approve an image for display on this site.

Since I'm a linux boy, my site is hosted on a linux server (gentoo if you'd like to know), so there had to be a open source solution for this right ? After some searching, I came up with the following solution:

The conversion is split in 4 simple steps:
  1. I write the html to a temporary file on the server.

    <?PHP
    // $grid comes from the database
    $fp = fopen("blah.html","w");
    fwrite($fp,str_replace('border="1"','border="0"',$grid)); // replace the table border value to 0
    fclose($fp);
    ?>

  2. After that, I convert the html to postscript with htmldoc

    <?PHP
    $command = "htmldoc --continuous --left 0 --top -23 blah.html -f blah.ps";
    system($command,$retval);
    ?>


    The left margin is set to 0 and top margin to a negative value, so the html is positioned in the upper-left corner of the document. For some reason '0' for the top doesn't work. There is still a white line of 23 pixels height at the top. With the negative value, this is corrected.

  3. Now we'll convert the postscript to an image using 'convert' which is part of the ImageMagick package. Convert has a lot of options. In my case the crop function is what I needed.

    <?PHP
    $command = "convert -crop 202x201 blah.ps blah.jpg";
    system($command,$retval);
    ?>


  4. The crop function generates a lot of garbage images, but the one I need is blah-0.jpg which will be displayed on this site. So this file is moved and renamed with it's ID in the database to the picture directory. The geometry was determined after some trial & error.

    <?PHP
    // $id comes from the database
    $picture_directory = "somewhere/on/your/server";
    $command = "mv blah-0.jpg $picture_directory/{$id}.jpg";
    system($command,$retval);
    // cleanup the rest of the garbage files
    system("rm -f blah-*",$retval);
    ?>
The result isn't ideal yet, although I find the images very cool. I'm going to test some more options in the future, but for now I'm very satisfied as I'm able to load the top/voting pages much faster than I used to.

References:

htmldoc: convert html to html/ps/pdf (new window)
ImageMagick: create or modify images. (new window)

Note: both packages work on all major distributions.


copyleft 2006 - realize.be - swentel at realize dot be