Pic2HTML

BeeThis is simply a copy of my old pic2html article (2005). I’ve done some minor content editing, mostly spelling but there still might be a few lines that doesn’t make any sense.

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, especially the movies are well made.
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 size heavy.
Before we get going, remember to enable the GD library[1], for PHP. If you don’t know how, consult the PHP manual. I wont be going into details about the different GD lib functions, so you’ll need to read up on the GD functions you’re not familiar with in the manual as well.

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 a lot of helper 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:

1
2
3
4
5
6
7
8
9
10
11
12
<?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 an array). 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.

1
2
3
4
<?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 function, 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:

1
2
font-size: 1px;
line-height: 1px;

For the less fortunate (this including myself. It took me several tries to find this obvious css syntax), this sheet will give it so that every character fills up 1 single pixel.
Anyway here you have it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?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>"; // You don't need to . concatenate the string, but my WP-plugin brakes if I don't.
    return imagedestroy($img);
}
?>

It shouldn’t be that hard to understand, but I’ll run through the code in briefs below:
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 . This will in pictures with few colors make the size of the file dramatically 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:

1
2
3
<?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”> [……….]

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. Another problem with a large picture is that it doesn’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 my system that lags the resources. But if you notice the beautiful picture below (captured by yours truly, during a massive hangover), you’ll see the script stops:

4.1 Useful?

So far I haven’t found any useful purpose for this. But if anyone can come up with something please do throw a comment and let me know.

– Added –

While converting the article to my new blog, I’ve read through it quickly, changing a few obvious spelling mistakes and altered a couple of lines (and removed a few sentences). But what strike me now is, that we can actually decrease the size of the end HTML, if we used <span> with a class. The class names would be c[ITERATED_NUMBER] and define a color, this way we could reuse a small class name many times instead of replicating a full color=”#000000″ (15 chars) class=”c1″ (10 chars, allowing up to class=”c999999″ different colors, that could be reused.
Anyway I still really can’t seem to figure out where this could be used, if you got an idea please do tell…

a. sources

[1] http://www.php.net/manual/en/ref.image.php
[2] http://en.wikipedia.org/wiki/Numeral_system

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>