This article has moved to http://birk-jensen.dk/2010/09/pic2html/

You can still view the original article below:
pic2html
Index
1) Introduction
2) rgb2html
3) pic2html
4) Conclusion
4.1) Useful?
a. Sources b. Understanding this article
1. Introduction
A long long time ago, I was a little trip by http://romanm.ch (no longer the same site), and well I must admit pretty impressing, try to take a look your self, specially the movies are freaken sweet.
Anyway, this gave me the idea of making an image to pure html code. My theory was that it would be simple to make a picture look good even with nothing but html (and as you'll see later this was the truth, it's possible to make 100% replicas), even though it'll be heavy.
Before we get goign, remember to enable the GD library[1], for PHP. If you don't know how, you'll have to go find comfort somewhere else, I'm not helping you there. And later in the article you'll notice that I don't comment much on the GD functions, so if you don't know anything about the GD lib, then pis off :) naah, stay!
2. rgb2html
First off we need a function to change the RGB color code to HTML color code (or simple from decimal to hexadecimal[2]). Lucky for us PHP is filled with useles functions, that sometimes turns out to be, well useful. This time it's the great comeback for the dechex function, which convert a decimal number to hexadecimal. I've packed this down in a little function:
rgb2html code
<?php
function rgb2html($clrR, $clrG, $clrB, $intReturn = 2) {
    $clrR = substr("0" . dechex($clrR), -2);
    $clrG = substr("0" . dechex($clrG), -2);
    $clrB = substr("0" . dechex($clrB), -2);
    
    if ($intReturn == 1)
        return array('red' => $clrR, 'green' => $clrG, 'blue' => $clrB);
    elseif ($intReturn == 2)
        return $clrR . $clrG . $clrB;
}
?>
In our code, all we need is the function which spits out the color code as a string, but I got carried away and made a little extra (return as a variable). And you can like any other of my functions in any of my articles, (ab)use them like a mad man, if that's you desire, just as long as you don't say you've written then your self. And just for the fun of it, lets try the code.
rgb2html example
<?php
// #ff9600
echo '#'. rgb2html(255, 150, 0);
?>
Output: #ff9600
And well it seems fine.
3. pic2html
And now this is where all the magic happens. In this cool (cool because of the number 2 instead of to in the function name, this is very popular so I thought I'd give it a try), we'll be reading a picture pixel by pixel, and printing it out as HTML. I've made a couple of considerations about the HTML before I started:
I've used the <pre>, this way we save some valuable space, byt not having to use the evil <br /> code. And i've chosen to use the <font color="#[COLOR]">char</font> instead of the (now a days) "correct" <span>, again to save some Kb. The stylesheet i've chosen is the following:
font-size: 1px; line-height: 1px;
For the less fortunate (read: stupid - including myself. It took me severel tries to find this obvious stylesheet), this sheet will give it so that every character fills up 1 single pixel.
Anyway here you have it:
The pic2html function
<?php
function pic2html($img, $char = "#") {
    $imgX = imagesx($img) - 1;
    $imgY = imagesy($img) - 1;
    $lastIndx = imagecolorat($img, 0, 0);
    $clrRGB = imagecolorsforindex($img, $lastIndx);
    
    echo '<pre style="font-size: 1px; line-height: 1px;">';
    echo '<font color="#' . rgb2html($clrRGB['red'], $clrRGB['green'], $clrRGB['blue']) . '">';

    for ($y = 0; $y <= $imgY; $y++) {
        for ($x = 0; $x <= $imgX; $x++) {
            $clrIndx = imagecolorat($img, $x, $y);
            if ($lastIndx != $clrIndx) {
                echo '</font>';
                $clrRGB = imagecolorsforindex($img, $clrIndx);
                
                echo '<font color="#' . rgb2html($clrRGB['red'],
                $clrRGB['green'], $clrRGB['blue']) . '">';
                $lastIndx = $clrIndx;
            }
            echo $char;
        }
        echo "\n";
    }
    echo "</pre>";
    return imagedestroy($img);
}
?>
It shouldn't be that hard to understand, but let me take it quick:
First of we find the size of the image, so we know how many times to run our loops.
Next we find the very first color. This is done outside our loops, this way we can optimize our code, so if the same color appears 2 times after each other, we will keep the same <font>. This will in pictures with few colors make the size of the file dramaticly less.
Now we print the selected character with the right color. Running from the top left corner till the lower right when it's done.

When you call the pic2html function, remember to do it with an image handle, and not just with a path:
rgb2html example
<?php
pic2html(imagecreatefromjpeg('images/bigbee.jpg'));
?>
Output: <pre style="font-size: 1px; line-height: 1px;"><font color="#0c0b09">#</font><fo nt color="#0f0e0c">#</font><font color="#100f0d">##</font><font color="#0f0e0c"> [..........]
notice, that we use our rgb2html function, so remember to include that somewhere.
4. Conclusion
Actually I must conclude that - for once - everything was as I've expected. It's possible to make a replica of an image, but it's heavy and bigger pictures need some heavy connections. Another problem with a large picture is that it dosn't go all the way through the image, it makes it till one point, and then it just stops. i don't know if it's my PHP script timeout, or if it's that my system lags the ressources. But if you notice the beautifull picture below (captued by yours truly, duringn a massive hangover), you'll see the script stops:
AAAHHHH look at the size of that thing!
AAAHHHH look at the size of that thing!

Anyway, I've found a couple of old picture, and I've compared them with an HTML version of them self, and well it's impossible to see the difference:
Guess which one is the HTML.
Guess which one is the HTML.
4.1 Useful?
Well, you might be saying to your self: Well that was a pretty good article, and I've learned a lot, that Philip is a true genius. But what can I use this function for?, and I've had exactly the same thought a couple of times my self - well when you don't get a lot of compliments you have ot make your own :).
I can't realy seem to figure out anything useful to do with this function. Maybe some evil advertising company can use it to send their evil banners out as HTML to avoid the blockers but then again, with the size of the image this would have no positive effect. But well it was nice to work with the GD-lib, on something other that just a line or two.
Download this article, with original bee image, and an example code ready to run.
a. Sources
[1] http://www.php.net/manual/en/ref.image.php
[2] http://en.wikipedia.org/wiki/Numeral_system

[-] http://romanm.ch
b. Understanding this article
Well the only purpose of this section, is to clearify a little something about this article. And it will just be done in no particular order:

- I've colored the codes my self, so if there are some color errors, please just leave some feedback, and I'll fix it. If yuo have any complaints about the colors I've used for the different syntax, then I don't want to hear about it, copy the code into your own favorit PHP editor.
- If you find anything offending please report, but then again don't say a word or I'll get you, and I'll get you good :p
- Well that was about it, understanding this article. Now remember please leave some feadback, nothing says "sweeeeet" like good feedback.
- Philip Birk-Jensen, January 2005 -