使用 PHP 将图像分割为像素 div

发布于 2024-12-14 03:44:55 字数 202 浏览 1 评论 0原文

这很难解释,但出于好奇,我想用 PHP 抓取一个图像,将其分成 1 个像素部分,然后执行 foreach 并将每个像素分配给一个 div 作为图像/背景图像。因此,当图片显示在屏幕上时,它看起来是完整的,但实际上它是很多 1px div。

使用GD或类似的库,这可能吗?

(另外,如果使用 Javascript 和 Canvas 更容易,那么我有兴趣知道)

This is tricky to explain, but for curiosities sake, I'd like to grab an image with PHP, split it into 1 pixel parts and do a foreach and assign each pixel to a div as an image/background image. So when the picture is displayed on the screen it looks whole, but its actually lots of 1px divs.

Using GD or a similar library, is this possible?

(Also, if this is easier with Javascript and Canvas then i'd be interested to know)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

寄居者 2024-12-21 03:44:55

正如其他人所说,您需要使用 imagecolorat 函数来选择每个像素的图像,然后根据需要循环并渲染元素。

只是因为我发现这比实用更有趣,所以我尝试了一下。

下面是一些快速组合在一起的代码,演示了其中的几个输出。 image.jpg 是一张 50x39px 的猴子图像,相当于 1950 个 1x1px 图像。下图显示了输出 - 第一个图像是原始图像,第二个图像是以 1x1px 图像矩阵作为 div 背景的图像,第三个图像是从原始图像中选取的十六进制颜色,然后 background:#xxxxxx; 在那个 1x1px div 上。请注意,如果您对此进行测试,请使用小图像!因为显然它会为原始图像中的每个像素生成一个图像。

对于未来的读者来说,这更多的是一个概念证明,不应该在生产环境中使用!

编辑:屏幕截图中的第三张图像显然未正确渲染 - 但由于 minitech 的建议,现在可以正常显示。下面的代码已被修改以反映此更改。

Original, 1pxendered, 1px hex colorendered

<?php

$im = imagecreatefromjpeg("image.jpg");
$w = imagesx($im);
$h = imagesy($im);

?>

<div style="background:url(image.jpg);float:left;width:50px;height:39px;"></div>
<div style="clear:both;"></div>
-------<br />
<div style="clear:both;"></div>

<?php

/*
 * Do it with image creation, image per pixel
 */

for( $i = 0; $i < $w; $i++ ) {
    for( $j = 0; $j < $h; $j++ ) {      
        if( !file_exists( "dots/{$i}_{$j}.jpg" ) ) {
            $dot = imagecreatetruecolor(1, 1);
            imagefill($dot, 0, 0, imagecolorat($im, $i, $j));
            imagejpeg($dot, "dots/{$i}_{$j}.jpg", 100); 
            imagedestroy($dot);
        }

        $dots[$j][$i] = "dots/{$i}_{$j}.jpg";
    }
}

foreach( $dots as $column ) {
    foreach( $column as $row ) {
        echo '<div style="background:url('.$row.');float:left;width:1px;height:1px;"></div>';
    }
    echo '<div style="clear:both;"></div>';
}

/*
 * Do it with picking the hex colour
 */

?>

<div style="clear:both;"></div>
-------<br />
<div style="clear:both;"></div>

<?php

for( $i = 0; $i < $w; $i++ ) {
    for( $j = 0; $j < $h; $j++ ) {
        $array[$j][$i] = get_hex(imagecolorat($im, $i, $j));
    }
}

foreach( $array as $column ) {
    foreach( $column as $row ) {
        echo '<div style="background:'.$row.';float:left;width:1px;height:1px;"></div>';
    }
    echo '<div style="clear:both;"></div>';
}

function get_hex( $dec ) {
    $r = ($dec >> 16) & 0xFF;
    $g = ($dec >> 8) & 0xFF;
    $b = $dec & 0xFF;

    return '#' . pad_hex( dechex( $r ) ) . pad_hex( dechex( $g ) ) . pad_hex( dechex( $b ) ) ;
}

function pad_hex( $val ) {  
    return strlen( $val ) == 1 ? str_pad(dechex( $val ), 2, '0', STR_PAD_LEFT) : $val;
}

?>

只是稍微玩了一下,这里也实现了相同的效果画布和 jQuery。不过,没有 jQuery 也可以轻松完成。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Test</title>
    <script src="http://code.jquery.com/jquery-1.7.min.js"></script>
    <script type="text/javascript">
    $(document).ready(function() {  
        var canvas = document.getElementById("myCanvas");  
        var ctx = canvas.getContext("2d");  

        var image = new Image();  
        image.src = "image.jpg";  
        $(image).load(function() {  
            ctx.drawImage(image, 0, 0);

            var imageData = ctx.getImageData(0, 0, 50, 39);  
            var pixels = imageData.data;

            ctx.clearRect(0, 0, canvas.width, canvas.height);
            $('canvas').remove();

            for (var i = 0, n = pixels.length; i < n; i += 4) {
                var r = pixels[i  ] // red
                var g = pixels[i+1] // green
                var b = pixels[i+2] // blue

                // i+3 is alpha (the fourth element)
                $('body').append('<div style="width:1px;background:rgb('+pixels[i  ]+','+g+','+b+');height:1px;float:left;"></div>');
                if( i % ( 4 * imageData.width ) == 0) {
                    //alert(i);
                    $('body').append('<div style="clear:both;"></div>');
                }
            }
        });
    });  
    </script>
  </head>
  <body>
    <p><canvas style="display:none;" id="myCanvas" width="350" height="250"></canvas></p>
  </body>
</html>

As others have said, you'd need to use the imagecolorat function to select the image at each pixel, then loop through and render the elements as necessary.

Just because I found this interesting more so than practical I had a play around with it.

Below is some quickly thrown together code which demonstrates a couple of outputs from this. image.jpg is a 50x39px image of a monkey which amounts to 1950 1x1px images. The image below shows the output- the first image is the original, the second is the one with a matrix of 1x1px images as div backgrounds, the third is the hex colour picked from the original then background:#xxxxxx; on that 1x1px div. Be warned, if you test this use a small image! as obviously it generates an image for each pixel in the original image.

For future readers, this is more a proof of concept and should not be used in a production environment!

Edit: The third image in the screenshot obviously isn't rendered correctly- however this now works thanks to a suggestion by minitech. The code below has been amended to reflect this change.

Original, 1px rendered, 1px hex colour rendered

<?php

$im = imagecreatefromjpeg("image.jpg");
$w = imagesx($im);
$h = imagesy($im);

?>

<div style="background:url(image.jpg);float:left;width:50px;height:39px;"></div>
<div style="clear:both;"></div>
-------<br />
<div style="clear:both;"></div>

<?php

/*
 * Do it with image creation, image per pixel
 */

for( $i = 0; $i < $w; $i++ ) {
    for( $j = 0; $j < $h; $j++ ) {      
        if( !file_exists( "dots/{$i}_{$j}.jpg" ) ) {
            $dot = imagecreatetruecolor(1, 1);
            imagefill($dot, 0, 0, imagecolorat($im, $i, $j));
            imagejpeg($dot, "dots/{$i}_{$j}.jpg", 100); 
            imagedestroy($dot);
        }

        $dots[$j][$i] = "dots/{$i}_{$j}.jpg";
    }
}

foreach( $dots as $column ) {
    foreach( $column as $row ) {
        echo '<div style="background:url('.$row.');float:left;width:1px;height:1px;"></div>';
    }
    echo '<div style="clear:both;"></div>';
}

/*
 * Do it with picking the hex colour
 */

?>

<div style="clear:both;"></div>
-------<br />
<div style="clear:both;"></div>

<?php

for( $i = 0; $i < $w; $i++ ) {
    for( $j = 0; $j < $h; $j++ ) {
        $array[$j][$i] = get_hex(imagecolorat($im, $i, $j));
    }
}

foreach( $array as $column ) {
    foreach( $column as $row ) {
        echo '<div style="background:'.$row.';float:left;width:1px;height:1px;"></div>';
    }
    echo '<div style="clear:both;"></div>';
}

function get_hex( $dec ) {
    $r = ($dec >> 16) & 0xFF;
    $g = ($dec >> 8) & 0xFF;
    $b = $dec & 0xFF;

    return '#' . pad_hex( dechex( $r ) ) . pad_hex( dechex( $g ) ) . pad_hex( dechex( $b ) ) ;
}

function pad_hex( $val ) {  
    return strlen( $val ) == 1 ? str_pad(dechex( $val ), 2, '0', STR_PAD_LEFT) : $val;
}

?>

Just had a bit more of a play around with it and here's the same achieved with canvas and jQuery. It could easily be done without jQuery though.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Test</title>
    <script src="http://code.jquery.com/jquery-1.7.min.js"></script>
    <script type="text/javascript">
    $(document).ready(function() {  
        var canvas = document.getElementById("myCanvas");  
        var ctx = canvas.getContext("2d");  

        var image = new Image();  
        image.src = "image.jpg";  
        $(image).load(function() {  
            ctx.drawImage(image, 0, 0);

            var imageData = ctx.getImageData(0, 0, 50, 39);  
            var pixels = imageData.data;

            ctx.clearRect(0, 0, canvas.width, canvas.height);
            $('canvas').remove();

            for (var i = 0, n = pixels.length; i < n; i += 4) {
                var r = pixels[i  ] // red
                var g = pixels[i+1] // green
                var b = pixels[i+2] // blue

                // i+3 is alpha (the fourth element)
                $('body').append('<div style="width:1px;background:rgb('+pixels[i  ]+','+g+','+b+');height:1px;float:left;"></div>');
                if( i % ( 4 * imageData.width ) == 0) {
                    //alert(i);
                    $('body').append('<div style="clear:both;"></div>');
                }
            }
        });
    });  
    </script>
  </head>
  <body>
    <p><canvas style="display:none;" id="myCanvas" width="350" height="250"></canvas></p>
  </body>
</html>
愛上了 2024-12-21 03:44:55

当然。您所需要的只是 GD 的 imagecolorat() 。结果将是一个非常非常大的文件,使得除了实验之外的几乎所有事情都变得不切实际。

Sure. All you need is GD's imagecolorat(). The result is just going to be a really, really big file, making this impractical for almost everything beyond an experiment.

东风软 2024-12-21 03:44:55

我对你的问题很感兴趣,所以我尝试制作一些东西来创建带有 html 标签的图像,但尺寸太大了,无法使用。我花了一天剩下的时间,通过创建一个动态样式表将任何网络安全的十六进制颜色压缩为 3 个字符版本,调整多个连续像素的宽度以跨越该数量的列,并删除图像的边框,从而使其尽可能小用 CSS 填充替换它。

<?

echo number_format(create_cssi('myimage.png')/1024) .' kb';

function create_cssi($file,$link=false){
    set_time_limit(60);
    $a = get_array($file);
    arsort($a['p']);//sort the color counter high to low
    foreach($a['p'] as $col => $count){//create css pallete .cRGB or .cRRGGBB
        $css[] = '.c'.substr($col,1).'{background:'.$col.'}';
    }

    foreach($a['xy'] as $x => $xy){//create image pixels with css
        foreach($xy as $y => $color){
            if($color==$a['cb']['c']){//if the pixel is the same as the border color (top left pixel) then don't use a class
                $cssi[] = '<i></i>';
            }else{//otherwise apply the color class
                $cssi[] = '<i class=c'.substr($color,1).'></i>';
            }
        }
        $cssi[] = '<div class="cb"></div>';//new line: .cb{clear:both;}
    }

    //now it gets a bit more messy, I did this part after to further compress the html
    //this finds all of the consecutive empty tags (<i></i><i></i><i></i>) and replaced them with single tags of the same width:
    //<i></i><i></i><i></i>
    //<i class="s3"></i>

    $cssi = implode('',$cssi);
    $counters = array();
    preg_match_all('%(<i></i>)+%', $cssi, $result, PREG_SET_ORDER);
    for ($matchi = 0; $matchi < count($result); $matchi++) {
        for ($backrefi = 0; $backrefi < count($result[$matchi]); $backrefi++) {
            $count = substr_count($result[$matchi][0], '/');
            if($count>2){//3 or more consecutive tags
                $counters[$result[$matchi][0]] = substr_count($result[$matchi][0], '/');
            }
        }
    }
    $counters = array_unique($counters);
    $keys = array_map('strlen', array_keys($counters));//sort counters by key length ensuring the longest is first
    array_multisort($keys, SORT_DESC, $counters);
    $find = array();
    $replace = array();
    foreach($counters as $i => $c){
        $css[] = '.s'.$c.'{width:'.$c.'px}';//create a css class for the width
        $find[] = $i;                           //e.g. <i></i><i></i><i></i><i></i><i></i><i></i>
        $replace[] = '<i class="s'.$c.'"></i>'; //e.g. <i class="s6"></i>
    }
    $cssi = str_replace($find,$replace,$cssi);//do the highly inefficient find and replace!


    //still with me?
    //OK, now for all of the other colors - essentially the same thing but we're also saving the color in the counter array

    foreach($a['p'] as $span_color => $ct){
        $counters = array();
        if($ct>10){
            preg_match_all('%(<i class=c'.substr($span_color,1).'></i>)+%', $cssi, $result, PREG_SET_ORDER);
            for ($matchi = 0; $matchi < count($result); $matchi++) {
                for ($backrefi = 0; $backrefi < count($result[$matchi]); $backrefi++) {
                    $count = substr_count($result[$matchi][0], '/');
                    if($count>2){
                        $counters[$result[$matchi][0]] = array(substr_count($result[$matchi][0], '/'),'c'.substr($span_color,1));
                    }
                }
            }

            $keys = array_map('strlen', array_keys($counters));
            array_multisort($keys, SORT_DESC, $counters);

            $find = array();
            $replace = array();
            foreach($counters as $i => $c){
                $css[] = '.s'.$c[0].'{width:'.$c[0].'px}';
                $find[] = $i;
                $replace[] = '<i class="s'.$c[0].' '.$c[1].'"></i>';//$c[0] is the span width and $c[1] is the color class
            }

            $cssi = str_replace($find,$replace,$cssi);
        }
    }
    $css = array_unique($css);//strip out any diplicated css
    $style = '<style>.cb{clear:both;}i{width:1px;height:1px;float:left;}'.implode('',$css).'</style>';//build the style tag

    if($link!==false){//do we want this image linked?
        $pic = '<a href="'.$link.'">'.$cssi.'</a>';
    }else{
        $pic = $cssi;
    }

    //combine css pallete, image divs and wrapper and use the border removal valued as padding
    $tofile = $style.'<div style="width:'.$a['w'].'px;height:'.$a['h'].'px; padding:'.$a['cb']['t'].'px '.$a['cb']['r'].'px '.$a['cb']['b'].'px '.$a['cb']['l'].'px;background:'.$a['cb']['c'].';">'.$pic.'</div>';

    echo $tofile;//output to screen
    file_put_contents('logo.htm',$tofile);//store in a file
    return(strlen($tofile));//return the file size

}

function get_array($path){
    $img = imagecreatefromfile($path);//create the image from the path or remote uri
    $cb['t'] = 0;
    $cb['b'] = 0;
    $cb['l'] = 0;
    $cb['r'] = 0;
    $cb['c'] = imagecolorat($img, 0, 0);//get the top left pixel color (used for removing borders

    for(; $cb['t'] < imagesy($img); ++$cb['t']) {
        for($x = 0; $x < imagesx($img); ++$x) {
            if(imagecolorat($img, $x, $cb['t']) != $cb['c']) {
                break 2;
            }
        }
    }

    //find a pizel that is not the top left corner color on the bottom
    for(; $cb['b'] < imagesy($img); ++$cb['b']) {
        for($x = 0; $x < imagesx($img); ++$x) {
            if(imagecolorat($img, $x, imagesy($img) - $cb['b']-1) != $cb['c']) {
                break 2;
            }
        }
    }

    //find a pizel that is not the top left corner color on the left
    for(; $cb['l'] < imagesx($img); ++$cb['l']) {
        for($y = 0; $y < imagesy($img); ++$y) {
            if(imagecolorat($img, $cb['l'], $y) != $cb['c']) {
                break 2;
            }
        }
    }

    //find a pizel that is not the top left corner color on the right
    for(; $cb['r'] < imagesx($img); ++$cb['r']) {
        for($y = 0; $y < imagesy($img); ++$y) {
            if(imagecolorat($img, imagesx($img) - $cb['r']-1, $y) != $cb['c']) {
                break 2;
            }
        }
    }
    $r = ($cb['c'] >> 16) & 0xFF;
    $g = ($cb['c'] >> 8) & 0xFF;
    $b = $cb['c'] & 0xFF;
    $cb['c'] = rgb2hex($r,$g,$b);//convert the top left pixel color to hex

    $newimg = imagecreatetruecolor(//create a new image the size of the none bordered image
        imagesx($img)-($cb['l']+$cb['r']),
        imagesy($img)-($cb['t']+$cb['b'])
    );

    imagecopy($newimg, $img, 0, 0, $cb['l'], $cb['t'], imagesx($newimg), imagesy($newimg));//copt the section of the image without the border to the new image

    $newimg = imagerotate($newimg, 270, 0);//don't ask, something drove me nots with my pixerl array so I just hacked it with a rotate and flip
    $newimg = ImageFlip($newimg);
    $imagew = imagesx($newimg);
    $imageh = imagesy($newimg);
    $xy = array();
    $p = array();

    for ($x = 0; $x <= $imagew-1; $x++) {//cycle through every pixel of the image to build and array $xy
        for ($y = 0;$y <= $imageh-1; $y++){
            $rgb = imagecolorat($newimg, $x, $y);
            $r = ($rgb >> 16) & 0xFF;
            $g = ($rgb >> 8) & 0xFF;
            $b = $rgb & 0xFF;
            $h = rgb2hex($r,$g,$b);
            $xy[$x][$y] = $h;
            @$p[$h]++;//count the occurences of each color
        }
    }
    return(array('xy'=>$xy,'p'=>$p,'w'=>$imageh,'h'=>$imagew,'cb'=>$cb));//return the pizel array ($xy), the color count ($p), the original height ($h), the original width ($w) and the crop box with color at the top left corner ($cb)
}

function rgb2hex($r,$g,$b) {
    $r = dechex($r);
    $g = dechex($g);
    $b = dechex($b);
    $rp = str_pad($r, 2, "0", STR_PAD_LEFT);
    $gp = str_pad($g, 2, "0", STR_PAD_LEFT);
    $bp = str_pad($b, 2, "0", STR_PAD_LEFT);
    $rr = str_split($rp);
    $gg = str_split($gp);
    $bb = str_split($bp);
    if($rr[0]==$rr[1]&&$gg[0]==$gg[1]&&$bb[0]==$bb[1]){//compress web safe colors to 3 character equivalent
        return('#'.$rr[0].$gg[0].$bb[0]);
    }else{
        return('#'.$rp.$gp.$bp);
    }
}

function imagecreatefromfile($path){//my fave imagecreate function
    $info = @getimagesize($path);
    if(!$info){
        return false;
    }
    $functions = array(
        IMAGETYPE_GIF => 'imagecreatefromgif',
        IMAGETYPE_JPEG => 'imagecreatefromjpeg',
        IMAGETYPE_PNG => 'imagecreatefrompng',
        IMAGETYPE_WBMP => 'imagecreatefromwbmp',
        IMAGETYPE_XBM => 'imagecreatefromwxbm',
    );
    return $functions[$info[2]]($path);
}

function ImageFlip($img){//image flip because I'm not great at arrays.
    $width = imagesx($img);
    $height = imagesy($img);
    $src_x = 0;
    $src_y = 0;
    $src_width = $width;
    $src_height = $height;
    $src_x = $width -1;
    $src_width = -$width;
    $imgdest =  imagecreatetruecolor($width, $height );
    if(imagecopyresampled($imgdest, $img, 0, 0, $src_x, $src_y , $width, $height, $src_width, $src_height)){
        return $imgdest;
    }
    return $img;
}

function pre($a){//just useful for outputting arrays in a <pre> tag, not used
    echo '<pre>';
    print_r($a);
    echo '</pre>';
}
?>

png input

从 300x300 像素 png 86kb 创建一个 1.1mb 等效的 html

html output

使用仅包含几种颜色的图像可以获得更好的结果,例如 Twitter 徽标,“仅”以 78kb 输出

twitter 徽标 300x300 像素

这是 40x40 像素 twitter 徽标的输出

<style>.cb{clear:both;}i{width:1px;height:1px;float:left;}.c00aced{background:#00aced}.cfff{background:#fff}.c00a7ec{background:#00a7ec}.c00abed{background:#00abed}.c00a8ec{background:#00a8ec}.c00a9ed{background:#00a9ed}.c00a6ec{background:#00a6ec}.c00aaed{background:#00aaed}.c00a8ed{background:#00a8ed}.cf8fdfe{background:#f8fdfe}.c00a9ec{background:#00a9ec}.cfeffff{background:#feffff}.cfdfeff{background:#fdfeff}.cf4fbfe{background:#f4fbfe}.c02aced{background:#02aced}.c5cc9f2{background:#5cc9f2}.c09aeed{background:#09aeed}.cf6fcfe{background:#f6fcfe}.c6fcff4{background:#6fcff4}.c00aaec{background:#00aaec}.cebf8fd{background:#ebf8fd}.c04abed{background:#04abed}.c4ec5f2{background:#4ec5f2}.c07aeed{background:#07aeed}.c2bb8ef{background:#2bb8ef}.c63cbf3{background:#63cbf3}.c03aced{background:#03aced}.c11b1ee{background:#11b1ee}.c33bcf0{background:#33bcf0}.cc1ebfb{background:#c1ebfb}.cb1e5f9{background:#b1e5f9}.c04abec{background:#04abec}.cd8f2fc{background:#d8f2fc}.cd0effb{background:#d0effb}.ce1f5fc{background:#e1f5fc}.cf5fcfe{background:#f5fcfe}.ce2f5fc{background:#e2f5fc}.ccfeffb{background:#cfeffb}.c18b1ed{background:#18b1ed}.c3ebfef{background:#3ebfef}.ce3f5fc{background:#e3f5fc}.c20b4ee{background:#20b4ee}.c03abec{background:#03abec}.c42c0f1{background:#42c0f1}.c0bafed{background:#0bafed}.cb0e5f9{background:#b0e5f9}.ce8f7fd{background:#e8f7fd}.cfafdfe{background:#fafdfe}.c05adec{background:#05adec}.c30baf0{background:#30baf0}.c04aced{background:#04aced}.c45c2f0{background:#45c2f0}.cade4f9{background:#ade4f9}.cd4f0fb{background:#d4f0fb}.c85d6f4{background:#85d6f4}.c7fd4f5{background:#7fd4f5}.c6ecff4{background:#6ecff4}.ca7e2f8{background:#a7e2f8}.c46c1f1{background:#46c1f1}.ccdeefa{background:#cdeefa}.c54c6f1{background:#54c6f1}.c7cd3f4{background:#7cd3f4}.c8cd8f5{background:#8cd8f5}.c42c1f0{background:#42c1f0}.cb9e7f8{background:#b9e7f8}.cd1effb{background:#d1effb}.c62cbf3{background:#62cbf3}.cdff4fc{background:#dff4fc}.c5dc9f3{background:#5dc9f3}.cc3ebfa{background:#c3ebfa}.cd2f0fc{background:#d2f0fc}.c8dd9f6{background:#8dd9f6}.c13b1ee{background:#13b1ee}.c3dbef1{background:#3dbef1}.c4ec4f2{background:#4ec4f2}.ccceefb{background:#cceefb}.c9ddef7{background:#9ddef7}.c4dc4f2{background:#4dc4f2}.c22b6ef{background:#22b6ef}.ce0f4fc{background:#e0f4fc}.cc3ebfb{background:#c3ebfb}.cc8edfb{background:#c8edfb}.cd7f2fc{background:#d7f2fc}.cf7fcfe{background:#f7fcfe}.ce6f7fd{background:#e6f7fd}.c03aded{background:#03aded}.c13b2ee{background:#13b2ee}.ca8e2f8{background:#a8e2f8}.c00a4eb{background:#00a4eb}.c00a2eb{background:#00a2eb}.c0dafee{background:#0dafee}.c3dbef0{background:#3dbef0}.cdef4fc{background:#def4fc}.ccaecf9{background:#caecf9}.c64cbf3{background:#64cbf3}.cbee9fa{background:#bee9fa}.c6bcef4{background:#6bcef4}.c0baeed{background:#0baeed}.c1fb4ee{background:#1fb4ee}.c98ddf7{background:#98ddf7}.ca2e1f8{background:#a2e1f8}.cf9fdfe{background:#f9fdfe}.cecf9fd{background:#ecf9fd}.c8fdaf6{background:#8fdaf6}.c1ab2ee{background:#1ab2ee}.c7ad3f5{background:#7ad3f5}.c07aced{background:#07aced}.c96ddf7{background:#96ddf7}.c7dd4f5{background:#7dd4f5}.c20b6ef{background:#20b6ef}.cdcf3fc{background:#dcf3fc}.c77d1f3{background:#77d1f3}.ce8f7fc{background:#e8f7fc}.c1db4ee{background:#1db4ee}.c0fafed{background:#0fafed}.cd9f2fb{background:#d9f2fb}.c00a4ec{background:#00a4ec}.c35bdf0{background:#35bdf0}.c77d3f5{background:#77d3f5}.c2fbbf0{background:#2fbbf0}.c23b6ee{background:#23b6ee}.ce7f7fd{background:#e7f7fd}.c0db0ee{background:#0db0ee}.c5fcaf2{background:#5fcaf2}.cb5e5f7{background:#b5e5f7}.cd1f0fb{background:#d1f0fb}.cbce9fa{background:#bce9fa}.ca5e1f8{background:#a5e1f8}.c47c2f1{background:#47c2f1}.c66ccf2{background:#66ccf2}.c1cb3ee{background:#1cb3ee}.c8ddaf6{background:#8ddaf6}.c16b1ee{background:#16b1ee}.cb0e4f9{background:#b0e4f9}.cfbfeff{background:#fbfeff}.ce9f7fd{background:#e9f7fd}.c3fc0f1{background:#3fc0f1}.c37bef1{background:#37bef1}.cbce8fa{background:#bce8fa}.c6acdf4{background:#6acdf4}.c41c0f1{background:#41c0f1}.cf3fbfd{background:#f3fbfd}.c47c1f1{background:#47c1f1}.c87d7f5{background:#87d7f5}.c3fbeef{background:#3fbeef}.cc8edfa{background:#c8edfa}.ca2dff6{background:#a2dff6}.c4ac2f1{background:#4ac2f1}.c37bcf0{background:#37bcf0}.cc6ecfa{background:#c6ecfa}.cc1eafa{background:#c1eafa}.c01aced{background:#01aced}.cc7ecfa{background:#c7ecfa}.c7ed4f5{background:#7ed4f5}.c46c2f1{background:#46c2f1}.c4cc5f2{background:#4cc5f2}.ce9f8fd{background:#e9f8fd}.cd1f0fc{background:#d1f0fc}.c3bbef1{background:#3bbef1}.c78d2f5{background:#78d2f5}.cace4f9{background:#ace4f9}.cb1e4f9{background:#b1e4f9}.cf2fbfe{background:#f2fbfe}.c85d6f6{background:#85d6f6}.cf3fbfe{background:#f3fbfe}.c18b4ee{background:#18b4ee}.c0fb0ee{background:#0fb0ee}.c51c6f2{background:#51c6f2}.c5dcaf3{background:#5dcaf3}.c63ccf3{background:#63ccf3}.c26b7ef{background:#26b7ef}.c02aaec{background:#02aaec}.ccaedfa{background:#caedfa}.cdaf3fc{background:#daf3fc}.c05aded{background:#05aded}.c08aced{background:#08aced}.c62caf2{background:#62caf2}.c00a3eb{background:#00a3eb}.c0aaeed{background:#0aaeed}.c16b3ee{background:#16b3ee}.c19b4ef{background:#19b4ef}.c82d5f5{background:#82d5f5}.ca0dff8{background:#a0dff8}.c71d0f4{background:#71d0f4}.c88d7f6{background:#88d7f6}.c40c0f1{background:#40c0f1}.c76d2f4{background:#76d2f4}.ca3e0f8{background:#a3e0f8}.c00a5ec{background:#00a5ec}.c1db5ef{background:#1db5ef}.c2cb8ef{background:#2cb8ef}.c5fcaf3{background:#5fcaf3}.s24{width:24px}.s23{width:23px}.s19{width:19px}.s18{width:18px}.s17{width:17px}.s16{width:16px}.s15{width:15px}.s14{width:14px}.s13{width:13px}.s12{width:12px}.s11{width:11px}.s10{width:10px}.s9{width:9px}.s8{width:8px}.s7{width:7px}.s6{width:6px}.s5{width:5px}.s4{width:4px}.s3{width:3px}.s29{width:29px}.s28{width:28px}.s27{width:27px}.s26{width:26px}.s22{width:22px}</style><div style="width:40px;height:33px; padding:3px 0px 4px 0px;background:#fff;"><i class="s24"></i><i class=cbce8fa></i><i class=c6acdf4></i><i class=c41c0f1></i><i class=c37bef1></i><i class=c3fc0f1></i><i class=c63cbf3></i><i class=cb0e4f9></i><i class=cfbfeff></i><i class="s6"></i><i class=ce9f7fd></i><i></i><div class="cb"></div><i></i><i></i><i class=cf4fbfe></i><i class=cf3fbfd></i><i class="s18"></i><i class=cd8f2fc></i><i class=c47c1f1></i><i class=c00a9ec></i><i class=c00a7ec></i><i class=c00a8ec></i><i class=c00a9ed></i><i class=c00a9ec></i><i class=c00a7ec></i><i class=c00a8ec></i><i class=c37bcf0></i><i class=cc6ecfa></i><i></i><i></i><i class=cfdfeff></i><i class=cc1eafa></i><i class=c4ac2f1></i><i class=ca2dff6></i><i></i><div class="cb"></div><i></i><i></i><i class=c87d7f5></i><i class=c3fbeef></i><i class=cf8fdfe></i><i class="s16"></i><i class=cc8edfa></i><i class=c16b1ee></i><i class=c00a7ec></i><i class="s7 c00aced"></i><i class=c00a8ec></i><i class=c09aeed></i><i class=c8ddaf6></i><i class=c77d3f5></i><i class=c2fbbf0></i><i class=c00a6ec></i><i class=c23b6ee></i><i class=cf6fcfe></i><i></i><div class="cb"></div><i></i><i class=cfeffff></i><i class=c35bdf0></i><i class=c00a4ec></i><i class=c4ec5f2></i><i class=cf8fdfe></i><i class="s14"></i><i class=ce8f7fc></i><i class=c1db4ee></i><i class=c00a8ed></i><i class="s9 c00aced"></i><i class=c00abed></i><i class=c00a8ec></i><i class=c00a7ec></i><i class=c00a7ec></i><i class=c0fafed></i><i class=cd9f2fb></i><i></i><i class=cf4fbfe></i><div class="cb"></div><i></i><i class=ce7f7fd></i><i class=c0db0ee></i><i class=c00abed></i><i class=c00a7ec></i><i class=c47c2f1></i><i class=cebf8fd></i><i class="s13"></i><i class=c66ccf2></i><i class=c00a6ec></i><i class="s12 c00aced"></i><i class=c00abed></i><i class=c1cb3ee></i><i class=ca5e1f8></i><i class=cbce9fa></i><i class=c5fcaf2></i><i class=cb5e5f7></i><div class="cb"></div><i></i><i class=cd1f0fb></i><i class=c01aced></i><i class=c00aced></i><i class=c00aced></i><i class=c00a7ec></i><i class=c2bb8ef></i><i class=cc7ecfa></i><i class="s11"></i><i class=ce2f5fc></i><i class=c0aaeed></i><i class=c00abed></i><i class="s12 c00aced"></i><i class=c00abed></i><i class=c16b3ee></i><i class=c19b4ef></i><i class=c00a3eb></i><i class=c62caf2></i><i class=cfdfeff></i><div class="cb"></div><i></i><i class=cdaf3fc></i><i class=c05aded></i><i class=c00abed></i><i class=c00aced></i><i class=c00aced></i><i class=c00a9ed></i><i class=c08aced></i><i class=c82d5f5></i><i class=cf5fcfe></i><i class="s9"></i><i class=ca0dff8></i><i class=c00a7ec></i><i class="s14 c00aced"></i><i class=c00abed></i><i class=c00a5ec></i><i class=c5cc9f2></i><i class=cfeffff></i><i></i><div class="cb"></div><i></i><i class=cf6fcfe></i><i class=c1db5ef></i><i class=c00aaed></i><i class="s3 c00aced"></i><i class=c00abed></i><i class=c00a7ec></i><i class=c2cb8ef></i><i class=ca3e0f8></i><i class=cf8fdfe></i><i class="s7"></i><i class=c76d2f4></i><i class=c00a7ec></i><i class="s14 c00aced"></i><i class=c04abed></i><i class=c71d0f4></i><i class=cfeffff></i><i></i><i></i><div class="cb"></div><i></i><i></i><i class=c5cc9f2></i><i class=c00a7ec></i><i class="s5 c00aced"></i><i class=c00a9ed></i><i class=c00a8ec></i><i class=c2bb8ef></i><i class=c88d7f6></i><i class=cd8f2fc></i><i class="s5"></i><i class=c6fcff4></i><i class=c00a7ec></i><i class="s13 c00aced"></i><i class=c00a9ec></i><i class=c40c0f1></i><i class="s4"></i><div class="cb"></div><i></i><i></i><i class=ccaedfa></i><i class=c02aaec></i><i class=c00abed></i><i class="s6 c00aced"></i><i class=c00a9ed></i><i class=c00a7ec></i><i class=c07aeed></i><i class=c3bbef1></i><i class=c78d2f5></i><i class=cace4f9></i><i class=cd1f0fc></i><i class=ce9f8fd></i><i class=c7ed4f5></i><i class=c00a8ec></i><i class="s13 c00aced"></i><i class=c00a8ec></i><i class=c46c2f1></i><i class="s4"></i><div class="cb"></div><i class="s3"></i><i class=c77d1f3></i><i class=c00a6ec></i><i class="s8 c00aced"></i><i class=c00abed></i><i class=c00a9ed></i><i class=c00a7ec></i><i class=c00a8ec></i><i class=c00aced></i><i class=c11b1ee></i><i class=c11b1ee></i><i class="s14 c00aced"></i><i class=c00a8ec></i><i class=c4cc5f2></i><i class="s4"></i><div class="cb"></div><i></i><i class=ce1f5fc></i><i class=cb1e4f9></i><i class=cf2fbfe></i><i class=c5dcaf3></i><i class=c04abed></i><i class="s12 c00aced"></i><i class=c00abed></i><i class=c00abed></i><i class="s14 c00aced"></i><i class=c00a8ec></i><i class=c63ccf3></i><i class="s4"></i><div class="cb"></div><i></i><i class=cd0effb></i><i class=c00a9ec></i><i class=c26b7ef></i><i class=c51c6f2></i><i class=c0fb0ee></i><i class=c00abed></i><i class="s27 c00aced"></i><i class=c00a7ec></i><i class=c85d6f6></i><i class="s4"></i><div class="cb"></div><i></i><i class=cf3fbfe></i><i class=c18b4ee></i><i class=c00a8ed></i><i class=c00a9ed></i><i class="s29 c00aced"></i><i class=c00a8ec></i><i class=cb1e5f9></i><i class="s4"></i><div class="cb"></div><i></i><i></i><i class=c5fcaf3></i><i class=c00a7ec></i><i class="s29 c00aced"></i><i class=c00abed></i><i class=c07aeed></i><i class=cdef4fc></i><i class="s4"></i><div class="cb"></div><i></i><i></i><i class=cd0effb></i><i class=c04abec></i><i class=c00abed></i><i class="s28 c00aced"></i><i class=c00a9ed></i><i class=c33bcf0></i><i class=cfeffff></i><i class="s4"></i><div class="cb"></div><i class="s3"></i><i class=c85d6f4></i><i class=c00a6ec></i><i class="s28 c00aced"></i><i class=c00a7ec></i><i class=c7fd4f5></i><i class="s5"></i><div class="cb"></div><i class="s4"></i><i class=c6ecff4></i><i class=c00a7ec></i><i class=c00a9ed></i><i class="s26 c00aced"></i><i class=c03aced></i><i class=cd4f0fb></i><i class="s5"></i><div class="cb"></div><i class="s5"></i><i class=cade4f9></i><i class=c30baf0></i><i class=c04aced></i><i class="s24 c00aced"></i><i class=c00a8ed></i><i class=c45c2f0></i><i class="s6"></i><div class="cb"></div><i class="s4"></i><i class=ce1f5fc></i><i class=cb1e5f9></i><i class=ca7e2f8></i><i class=c46c1f1></i><i class=c02aced></i><i class="s23 c00aced"></i><i class=c00a8ec></i><i class=cb9e7f8></i><i class="s6"></i><div class="cb"></div><i class="s4"></i><i class=ce2f5fc></i><i class=c05adec></i><i class=c00a8ed></i><i class="s24 c00aced"></i><i class=c00a8ed></i><i class=c42c1f0></i><i class="s7"></i><div class="cb"></div><i class="s5"></i><i class=c8cd8f5></i><i class=c00a6ec></i><i class="s23 c00aced"></i><i class=c00abed></i><i class=c04abec></i><i class=ccdeefa></i><i class="s7"></i><div class="cb"></div><i class="s5"></i><i class=cfdfeff></i><i class=c54c6f1></i><i class=c00a6ec></i><i class="s22 c00aced"></i><i class=c00a6ec></i><i class=c7cd3f4></i><i class="s8"></i><div class="cb"></div><i class="s6"></i><i class=cf8fdfe></i><i class=c62cbf3></i><i class=c00a8ec></i><i class=c00a8ec></i><i class=c00abed></i><i class="s18 c00aced"></i><i class=c00a8ed></i><i class=c3ebfef></i><i class=cfafdfe></i><i class="s8"></i><div class="cb"></div><i class="s8"></i><i class=cb0e5f9></i><i class=c42c0f1></i><i class=c0bafed></i><i class=c02aced></i><i class="s16 c00aced"></i><i class=c00a9ed></i><i class=c20b4ee></i><i class=ce3f5fc></i><i class="s9"></i><div class="cb"></div><i class="s10"></i><i class=ce8f7fd></i><i class=c6fcff4></i><i class=c03abec></i><i class="s14 c00aced"></i><i class=c00a9ed></i><i class=c18b1ed></i><i class=cd1effb></i><i class="s10"></i><div class="cb"></div><i class="s9"></i><i class=cdcf3fc></i><i class=c6bcef4></i><i class=c0baeed></i><i class=c00abed></i><i class="s13 c00aced"></i><i class=c00a7ec></i><i class=c1fb4ee></i><i class=ccfeffb></i><i class="s11"></i><div class="cb"></div><i class="s6"></i><i class=cf5fcfe></i><i class=cbee9fa></i><i class=c64cbf3></i><i class=c0dafee></i><i class=c00a7ec></i><i class="s13 c00aced"></i><i class=c00abed></i><i class=c00a7ec></i><i class=c3dbef0></i><i class=cdff4fc></i><i class="s12"></i><div class="cb"></div><i class=ccaecf9></i><i class=c98ddf7></i><i class=ca2e1f8></i><i class=c96ddf7></i><i class=c7dd4f5></i><i class=c4ec5f2></i><i class=c20b6ef></i><i class=c00aaec></i><i class=c00a7ec></i><i class=c00abed></i><i class="s13 c00aced"></i><i class=c00a8ec></i><i class=c07aced></i><i class=c7ad3f5></i><i class=cf9fdfe></i><i class="s13"></i><div class="cb"></div><i class=cecf9fd></i><i class=c8fdaf6></i><i class=c1ab2ee></i><i class=c00a2eb></i><i class=c00a4eb></i><i class=c00a7ec></i><i class=c00aaed></i><i class="s13 c00aced"></i><i class=c00abed></i><i class=c00a7ec></i><i class=c00aaec></i><i class=c4ec4f2></i><i class=ccceefb></i><i class="s15"></i><div class="cb"></div><i></i><i></i><i class=cf4fbfe></i><i class=c9ddef7></i><i class=c3dbef1></i><i class=c03aced></i><i class=c00a7ec></i><i class=c00a8ec></i><i class=c00aaed></i><i class=c00abed></i><i class="s5 c00aced"></i><i class=c00abed></i><i class=c00abed></i><i class=c00a9ed></i><i class=c00a7ec></i><i class=c00a8ec></i><i class=c13b1ee></i><i class=c5dc9f3></i><i class=cc3ebfa></i><i class="s17"></i><div class="cb"></div><i class="s5"></i><i class=cd2f0fc></i><i class=c8dd9f6></i><i class=c4dc4f2></i><i class=c22b6ef></i><i class=c09aeed></i><i class=c00aced></i><i class=c00aaed></i><i class=c00aaed></i><i class=c00aaed></i><i class=c00abed></i><i class=c03aded></i><i class=c13b2ee></i><i class=c33bcf0></i><i class=c63cbf3></i><i class=ca8e2f8></i><i class=ce6f7fd></i><i class="s19"></i><div class="cb"></div><i class="s8"></i><i class=cf7fcfe></i><i class=ce0f4fc></i><i class=ccfeffb></i><i class=cc3ebfb></i><i class=cc1ebfb></i><i class=cc1ebfb></i><i class=cc8edfb></i><i class=cd7f2fc></i><i class=cebf8fd></i><i class="s23"></i><div class="cb"></div></div>

I was intrigued with your question so I had a go at making something that would create an image with html tags but the size was so huge it was unusable. I spent the rest of the day making it as small as possible by creating a dynamic stylesheet compressing any web safe hex colors into 3 character versions, adjusting the width of multiple consecutive pixels to span that number of columns and removing the border of an image and replacing it with css padding.

<?

echo number_format(create_cssi('myimage.png')/1024) .' kb';

function create_cssi($file,$link=false){
    set_time_limit(60);
    $a = get_array($file);
    arsort($a['p']);//sort the color counter high to low
    foreach($a['p'] as $col => $count){//create css pallete .cRGB or .cRRGGBB
        $css[] = '.c'.substr($col,1).'{background:'.$col.'}';
    }

    foreach($a['xy'] as $x => $xy){//create image pixels with css
        foreach($xy as $y => $color){
            if($color==$a['cb']['c']){//if the pixel is the same as the border color (top left pixel) then don't use a class
                $cssi[] = '<i></i>';
            }else{//otherwise apply the color class
                $cssi[] = '<i class=c'.substr($color,1).'></i>';
            }
        }
        $cssi[] = '<div class="cb"></div>';//new line: .cb{clear:both;}
    }

    //now it gets a bit more messy, I did this part after to further compress the html
    //this finds all of the consecutive empty tags (<i></i><i></i><i></i>) and replaced them with single tags of the same width:
    //<i></i><i></i><i></i>
    //<i class="s3"></i>

    $cssi = implode('',$cssi);
    $counters = array();
    preg_match_all('%(<i></i>)+%', $cssi, $result, PREG_SET_ORDER);
    for ($matchi = 0; $matchi < count($result); $matchi++) {
        for ($backrefi = 0; $backrefi < count($result[$matchi]); $backrefi++) {
            $count = substr_count($result[$matchi][0], '/');
            if($count>2){//3 or more consecutive tags
                $counters[$result[$matchi][0]] = substr_count($result[$matchi][0], '/');
            }
        }
    }
    $counters = array_unique($counters);
    $keys = array_map('strlen', array_keys($counters));//sort counters by key length ensuring the longest is first
    array_multisort($keys, SORT_DESC, $counters);
    $find = array();
    $replace = array();
    foreach($counters as $i => $c){
        $css[] = '.s'.$c.'{width:'.$c.'px}';//create a css class for the width
        $find[] = $i;                           //e.g. <i></i><i></i><i></i><i></i><i></i><i></i>
        $replace[] = '<i class="s'.$c.'"></i>'; //e.g. <i class="s6"></i>
    }
    $cssi = str_replace($find,$replace,$cssi);//do the highly inefficient find and replace!


    //still with me?
    //OK, now for all of the other colors - essentially the same thing but we're also saving the color in the counter array

    foreach($a['p'] as $span_color => $ct){
        $counters = array();
        if($ct>10){
            preg_match_all('%(<i class=c'.substr($span_color,1).'></i>)+%', $cssi, $result, PREG_SET_ORDER);
            for ($matchi = 0; $matchi < count($result); $matchi++) {
                for ($backrefi = 0; $backrefi < count($result[$matchi]); $backrefi++) {
                    $count = substr_count($result[$matchi][0], '/');
                    if($count>2){
                        $counters[$result[$matchi][0]] = array(substr_count($result[$matchi][0], '/'),'c'.substr($span_color,1));
                    }
                }
            }

            $keys = array_map('strlen', array_keys($counters));
            array_multisort($keys, SORT_DESC, $counters);

            $find = array();
            $replace = array();
            foreach($counters as $i => $c){
                $css[] = '.s'.$c[0].'{width:'.$c[0].'px}';
                $find[] = $i;
                $replace[] = '<i class="s'.$c[0].' '.$c[1].'"></i>';//$c[0] is the span width and $c[1] is the color class
            }

            $cssi = str_replace($find,$replace,$cssi);
        }
    }
    $css = array_unique($css);//strip out any diplicated css
    $style = '<style>.cb{clear:both;}i{width:1px;height:1px;float:left;}'.implode('',$css).'</style>';//build the style tag

    if($link!==false){//do we want this image linked?
        $pic = '<a href="'.$link.'">'.$cssi.'</a>';
    }else{
        $pic = $cssi;
    }

    //combine css pallete, image divs and wrapper and use the border removal valued as padding
    $tofile = $style.'<div style="width:'.$a['w'].'px;height:'.$a['h'].'px; padding:'.$a['cb']['t'].'px '.$a['cb']['r'].'px '.$a['cb']['b'].'px '.$a['cb']['l'].'px;background:'.$a['cb']['c'].';">'.$pic.'</div>';

    echo $tofile;//output to screen
    file_put_contents('logo.htm',$tofile);//store in a file
    return(strlen($tofile));//return the file size

}

function get_array($path){
    $img = imagecreatefromfile($path);//create the image from the path or remote uri
    $cb['t'] = 0;
    $cb['b'] = 0;
    $cb['l'] = 0;
    $cb['r'] = 0;
    $cb['c'] = imagecolorat($img, 0, 0);//get the top left pixel color (used for removing borders

    for(; $cb['t'] < imagesy($img); ++$cb['t']) {
        for($x = 0; $x < imagesx($img); ++$x) {
            if(imagecolorat($img, $x, $cb['t']) != $cb['c']) {
                break 2;
            }
        }
    }

    //find a pizel that is not the top left corner color on the bottom
    for(; $cb['b'] < imagesy($img); ++$cb['b']) {
        for($x = 0; $x < imagesx($img); ++$x) {
            if(imagecolorat($img, $x, imagesy($img) - $cb['b']-1) != $cb['c']) {
                break 2;
            }
        }
    }

    //find a pizel that is not the top left corner color on the left
    for(; $cb['l'] < imagesx($img); ++$cb['l']) {
        for($y = 0; $y < imagesy($img); ++$y) {
            if(imagecolorat($img, $cb['l'], $y) != $cb['c']) {
                break 2;
            }
        }
    }

    //find a pizel that is not the top left corner color on the right
    for(; $cb['r'] < imagesx($img); ++$cb['r']) {
        for($y = 0; $y < imagesy($img); ++$y) {
            if(imagecolorat($img, imagesx($img) - $cb['r']-1, $y) != $cb['c']) {
                break 2;
            }
        }
    }
    $r = ($cb['c'] >> 16) & 0xFF;
    $g = ($cb['c'] >> 8) & 0xFF;
    $b = $cb['c'] & 0xFF;
    $cb['c'] = rgb2hex($r,$g,$b);//convert the top left pixel color to hex

    $newimg = imagecreatetruecolor(//create a new image the size of the none bordered image
        imagesx($img)-($cb['l']+$cb['r']),
        imagesy($img)-($cb['t']+$cb['b'])
    );

    imagecopy($newimg, $img, 0, 0, $cb['l'], $cb['t'], imagesx($newimg), imagesy($newimg));//copt the section of the image without the border to the new image

    $newimg = imagerotate($newimg, 270, 0);//don't ask, something drove me nots with my pixerl array so I just hacked it with a rotate and flip
    $newimg = ImageFlip($newimg);
    $imagew = imagesx($newimg);
    $imageh = imagesy($newimg);
    $xy = array();
    $p = array();

    for ($x = 0; $x <= $imagew-1; $x++) {//cycle through every pixel of the image to build and array $xy
        for ($y = 0;$y <= $imageh-1; $y++){
            $rgb = imagecolorat($newimg, $x, $y);
            $r = ($rgb >> 16) & 0xFF;
            $g = ($rgb >> 8) & 0xFF;
            $b = $rgb & 0xFF;
            $h = rgb2hex($r,$g,$b);
            $xy[$x][$y] = $h;
            @$p[$h]++;//count the occurences of each color
        }
    }
    return(array('xy'=>$xy,'p'=>$p,'w'=>$imageh,'h'=>$imagew,'cb'=>$cb));//return the pizel array ($xy), the color count ($p), the original height ($h), the original width ($w) and the crop box with color at the top left corner ($cb)
}

function rgb2hex($r,$g,$b) {
    $r = dechex($r);
    $g = dechex($g);
    $b = dechex($b);
    $rp = str_pad($r, 2, "0", STR_PAD_LEFT);
    $gp = str_pad($g, 2, "0", STR_PAD_LEFT);
    $bp = str_pad($b, 2, "0", STR_PAD_LEFT);
    $rr = str_split($rp);
    $gg = str_split($gp);
    $bb = str_split($bp);
    if($rr[0]==$rr[1]&&$gg[0]==$gg[1]&&$bb[0]==$bb[1]){//compress web safe colors to 3 character equivalent
        return('#'.$rr[0].$gg[0].$bb[0]);
    }else{
        return('#'.$rp.$gp.$bp);
    }
}

function imagecreatefromfile($path){//my fave imagecreate function
    $info = @getimagesize($path);
    if(!$info){
        return false;
    }
    $functions = array(
        IMAGETYPE_GIF => 'imagecreatefromgif',
        IMAGETYPE_JPEG => 'imagecreatefromjpeg',
        IMAGETYPE_PNG => 'imagecreatefrompng',
        IMAGETYPE_WBMP => 'imagecreatefromwbmp',
        IMAGETYPE_XBM => 'imagecreatefromwxbm',
    );
    return $functions[$info[2]]($path);
}

function ImageFlip($img){//image flip because I'm not great at arrays.
    $width = imagesx($img);
    $height = imagesy($img);
    $src_x = 0;
    $src_y = 0;
    $src_width = $width;
    $src_height = $height;
    $src_x = $width -1;
    $src_width = -$width;
    $imgdest =  imagecreatetruecolor($width, $height );
    if(imagecopyresampled($imgdest, $img, 0, 0, $src_x, $src_y , $width, $height, $src_width, $src_height)){
        return $imgdest;
    }
    return $img;
}

function pre($a){//just useful for outputting arrays in a <pre> tag, not used
    echo '<pre>';
    print_r($a);
    echo '</pre>';
}
?>

png input

From a 300x300 pixel png 86kb it creates a 1.1mb html equivalent

html output

Far better results can be made with images containing only a few colors like the twitter logo which "only" comes out at 78kb

twitter logo 300x300 pixels

Here's the output of a 40x40 pixel twitter logo

<style>.cb{clear:both;}i{width:1px;height:1px;float:left;}.c00aced{background:#00aced}.cfff{background:#fff}.c00a7ec{background:#00a7ec}.c00abed{background:#00abed}.c00a8ec{background:#00a8ec}.c00a9ed{background:#00a9ed}.c00a6ec{background:#00a6ec}.c00aaed{background:#00aaed}.c00a8ed{background:#00a8ed}.cf8fdfe{background:#f8fdfe}.c00a9ec{background:#00a9ec}.cfeffff{background:#feffff}.cfdfeff{background:#fdfeff}.cf4fbfe{background:#f4fbfe}.c02aced{background:#02aced}.c5cc9f2{background:#5cc9f2}.c09aeed{background:#09aeed}.cf6fcfe{background:#f6fcfe}.c6fcff4{background:#6fcff4}.c00aaec{background:#00aaec}.cebf8fd{background:#ebf8fd}.c04abed{background:#04abed}.c4ec5f2{background:#4ec5f2}.c07aeed{background:#07aeed}.c2bb8ef{background:#2bb8ef}.c63cbf3{background:#63cbf3}.c03aced{background:#03aced}.c11b1ee{background:#11b1ee}.c33bcf0{background:#33bcf0}.cc1ebfb{background:#c1ebfb}.cb1e5f9{background:#b1e5f9}.c04abec{background:#04abec}.cd8f2fc{background:#d8f2fc}.cd0effb{background:#d0effb}.ce1f5fc{background:#e1f5fc}.cf5fcfe{background:#f5fcfe}.ce2f5fc{background:#e2f5fc}.ccfeffb{background:#cfeffb}.c18b1ed{background:#18b1ed}.c3ebfef{background:#3ebfef}.ce3f5fc{background:#e3f5fc}.c20b4ee{background:#20b4ee}.c03abec{background:#03abec}.c42c0f1{background:#42c0f1}.c0bafed{background:#0bafed}.cb0e5f9{background:#b0e5f9}.ce8f7fd{background:#e8f7fd}.cfafdfe{background:#fafdfe}.c05adec{background:#05adec}.c30baf0{background:#30baf0}.c04aced{background:#04aced}.c45c2f0{background:#45c2f0}.cade4f9{background:#ade4f9}.cd4f0fb{background:#d4f0fb}.c85d6f4{background:#85d6f4}.c7fd4f5{background:#7fd4f5}.c6ecff4{background:#6ecff4}.ca7e2f8{background:#a7e2f8}.c46c1f1{background:#46c1f1}.ccdeefa{background:#cdeefa}.c54c6f1{background:#54c6f1}.c7cd3f4{background:#7cd3f4}.c8cd8f5{background:#8cd8f5}.c42c1f0{background:#42c1f0}.cb9e7f8{background:#b9e7f8}.cd1effb{background:#d1effb}.c62cbf3{background:#62cbf3}.cdff4fc{background:#dff4fc}.c5dc9f3{background:#5dc9f3}.cc3ebfa{background:#c3ebfa}.cd2f0fc{background:#d2f0fc}.c8dd9f6{background:#8dd9f6}.c13b1ee{background:#13b1ee}.c3dbef1{background:#3dbef1}.c4ec4f2{background:#4ec4f2}.ccceefb{background:#cceefb}.c9ddef7{background:#9ddef7}.c4dc4f2{background:#4dc4f2}.c22b6ef{background:#22b6ef}.ce0f4fc{background:#e0f4fc}.cc3ebfb{background:#c3ebfb}.cc8edfb{background:#c8edfb}.cd7f2fc{background:#d7f2fc}.cf7fcfe{background:#f7fcfe}.ce6f7fd{background:#e6f7fd}.c03aded{background:#03aded}.c13b2ee{background:#13b2ee}.ca8e2f8{background:#a8e2f8}.c00a4eb{background:#00a4eb}.c00a2eb{background:#00a2eb}.c0dafee{background:#0dafee}.c3dbef0{background:#3dbef0}.cdef4fc{background:#def4fc}.ccaecf9{background:#caecf9}.c64cbf3{background:#64cbf3}.cbee9fa{background:#bee9fa}.c6bcef4{background:#6bcef4}.c0baeed{background:#0baeed}.c1fb4ee{background:#1fb4ee}.c98ddf7{background:#98ddf7}.ca2e1f8{background:#a2e1f8}.cf9fdfe{background:#f9fdfe}.cecf9fd{background:#ecf9fd}.c8fdaf6{background:#8fdaf6}.c1ab2ee{background:#1ab2ee}.c7ad3f5{background:#7ad3f5}.c07aced{background:#07aced}.c96ddf7{background:#96ddf7}.c7dd4f5{background:#7dd4f5}.c20b6ef{background:#20b6ef}.cdcf3fc{background:#dcf3fc}.c77d1f3{background:#77d1f3}.ce8f7fc{background:#e8f7fc}.c1db4ee{background:#1db4ee}.c0fafed{background:#0fafed}.cd9f2fb{background:#d9f2fb}.c00a4ec{background:#00a4ec}.c35bdf0{background:#35bdf0}.c77d3f5{background:#77d3f5}.c2fbbf0{background:#2fbbf0}.c23b6ee{background:#23b6ee}.ce7f7fd{background:#e7f7fd}.c0db0ee{background:#0db0ee}.c5fcaf2{background:#5fcaf2}.cb5e5f7{background:#b5e5f7}.cd1f0fb{background:#d1f0fb}.cbce9fa{background:#bce9fa}.ca5e1f8{background:#a5e1f8}.c47c2f1{background:#47c2f1}.c66ccf2{background:#66ccf2}.c1cb3ee{background:#1cb3ee}.c8ddaf6{background:#8ddaf6}.c16b1ee{background:#16b1ee}.cb0e4f9{background:#b0e4f9}.cfbfeff{background:#fbfeff}.ce9f7fd{background:#e9f7fd}.c3fc0f1{background:#3fc0f1}.c37bef1{background:#37bef1}.cbce8fa{background:#bce8fa}.c6acdf4{background:#6acdf4}.c41c0f1{background:#41c0f1}.cf3fbfd{background:#f3fbfd}.c47c1f1{background:#47c1f1}.c87d7f5{background:#87d7f5}.c3fbeef{background:#3fbeef}.cc8edfa{background:#c8edfa}.ca2dff6{background:#a2dff6}.c4ac2f1{background:#4ac2f1}.c37bcf0{background:#37bcf0}.cc6ecfa{background:#c6ecfa}.cc1eafa{background:#c1eafa}.c01aced{background:#01aced}.cc7ecfa{background:#c7ecfa}.c7ed4f5{background:#7ed4f5}.c46c2f1{background:#46c2f1}.c4cc5f2{background:#4cc5f2}.ce9f8fd{background:#e9f8fd}.cd1f0fc{background:#d1f0fc}.c3bbef1{background:#3bbef1}.c78d2f5{background:#78d2f5}.cace4f9{background:#ace4f9}.cb1e4f9{background:#b1e4f9}.cf2fbfe{background:#f2fbfe}.c85d6f6{background:#85d6f6}.cf3fbfe{background:#f3fbfe}.c18b4ee{background:#18b4ee}.c0fb0ee{background:#0fb0ee}.c51c6f2{background:#51c6f2}.c5dcaf3{background:#5dcaf3}.c63ccf3{background:#63ccf3}.c26b7ef{background:#26b7ef}.c02aaec{background:#02aaec}.ccaedfa{background:#caedfa}.cdaf3fc{background:#daf3fc}.c05aded{background:#05aded}.c08aced{background:#08aced}.c62caf2{background:#62caf2}.c00a3eb{background:#00a3eb}.c0aaeed{background:#0aaeed}.c16b3ee{background:#16b3ee}.c19b4ef{background:#19b4ef}.c82d5f5{background:#82d5f5}.ca0dff8{background:#a0dff8}.c71d0f4{background:#71d0f4}.c88d7f6{background:#88d7f6}.c40c0f1{background:#40c0f1}.c76d2f4{background:#76d2f4}.ca3e0f8{background:#a3e0f8}.c00a5ec{background:#00a5ec}.c1db5ef{background:#1db5ef}.c2cb8ef{background:#2cb8ef}.c5fcaf3{background:#5fcaf3}.s24{width:24px}.s23{width:23px}.s19{width:19px}.s18{width:18px}.s17{width:17px}.s16{width:16px}.s15{width:15px}.s14{width:14px}.s13{width:13px}.s12{width:12px}.s11{width:11px}.s10{width:10px}.s9{width:9px}.s8{width:8px}.s7{width:7px}.s6{width:6px}.s5{width:5px}.s4{width:4px}.s3{width:3px}.s29{width:29px}.s28{width:28px}.s27{width:27px}.s26{width:26px}.s22{width:22px}</style><div style="width:40px;height:33px; padding:3px 0px 4px 0px;background:#fff;"><i class="s24"></i><i class=cbce8fa></i><i class=c6acdf4></i><i class=c41c0f1></i><i class=c37bef1></i><i class=c3fc0f1></i><i class=c63cbf3></i><i class=cb0e4f9></i><i class=cfbfeff></i><i class="s6"></i><i class=ce9f7fd></i><i></i><div class="cb"></div><i></i><i></i><i class=cf4fbfe></i><i class=cf3fbfd></i><i class="s18"></i><i class=cd8f2fc></i><i class=c47c1f1></i><i class=c00a9ec></i><i class=c00a7ec></i><i class=c00a8ec></i><i class=c00a9ed></i><i class=c00a9ec></i><i class=c00a7ec></i><i class=c00a8ec></i><i class=c37bcf0></i><i class=cc6ecfa></i><i></i><i></i><i class=cfdfeff></i><i class=cc1eafa></i><i class=c4ac2f1></i><i class=ca2dff6></i><i></i><div class="cb"></div><i></i><i></i><i class=c87d7f5></i><i class=c3fbeef></i><i class=cf8fdfe></i><i class="s16"></i><i class=cc8edfa></i><i class=c16b1ee></i><i class=c00a7ec></i><i class="s7 c00aced"></i><i class=c00a8ec></i><i class=c09aeed></i><i class=c8ddaf6></i><i class=c77d3f5></i><i class=c2fbbf0></i><i class=c00a6ec></i><i class=c23b6ee></i><i class=cf6fcfe></i><i></i><div class="cb"></div><i></i><i class=cfeffff></i><i class=c35bdf0></i><i class=c00a4ec></i><i class=c4ec5f2></i><i class=cf8fdfe></i><i class="s14"></i><i class=ce8f7fc></i><i class=c1db4ee></i><i class=c00a8ed></i><i class="s9 c00aced"></i><i class=c00abed></i><i class=c00a8ec></i><i class=c00a7ec></i><i class=c00a7ec></i><i class=c0fafed></i><i class=cd9f2fb></i><i></i><i class=cf4fbfe></i><div class="cb"></div><i></i><i class=ce7f7fd></i><i class=c0db0ee></i><i class=c00abed></i><i class=c00a7ec></i><i class=c47c2f1></i><i class=cebf8fd></i><i class="s13"></i><i class=c66ccf2></i><i class=c00a6ec></i><i class="s12 c00aced"></i><i class=c00abed></i><i class=c1cb3ee></i><i class=ca5e1f8></i><i class=cbce9fa></i><i class=c5fcaf2></i><i class=cb5e5f7></i><div class="cb"></div><i></i><i class=cd1f0fb></i><i class=c01aced></i><i class=c00aced></i><i class=c00aced></i><i class=c00a7ec></i><i class=c2bb8ef></i><i class=cc7ecfa></i><i class="s11"></i><i class=ce2f5fc></i><i class=c0aaeed></i><i class=c00abed></i><i class="s12 c00aced"></i><i class=c00abed></i><i class=c16b3ee></i><i class=c19b4ef></i><i class=c00a3eb></i><i class=c62caf2></i><i class=cfdfeff></i><div class="cb"></div><i></i><i class=cdaf3fc></i><i class=c05aded></i><i class=c00abed></i><i class=c00aced></i><i class=c00aced></i><i class=c00a9ed></i><i class=c08aced></i><i class=c82d5f5></i><i class=cf5fcfe></i><i class="s9"></i><i class=ca0dff8></i><i class=c00a7ec></i><i class="s14 c00aced"></i><i class=c00abed></i><i class=c00a5ec></i><i class=c5cc9f2></i><i class=cfeffff></i><i></i><div class="cb"></div><i></i><i class=cf6fcfe></i><i class=c1db5ef></i><i class=c00aaed></i><i class="s3 c00aced"></i><i class=c00abed></i><i class=c00a7ec></i><i class=c2cb8ef></i><i class=ca3e0f8></i><i class=cf8fdfe></i><i class="s7"></i><i class=c76d2f4></i><i class=c00a7ec></i><i class="s14 c00aced"></i><i class=c04abed></i><i class=c71d0f4></i><i class=cfeffff></i><i></i><i></i><div class="cb"></div><i></i><i></i><i class=c5cc9f2></i><i class=c00a7ec></i><i class="s5 c00aced"></i><i class=c00a9ed></i><i class=c00a8ec></i><i class=c2bb8ef></i><i class=c88d7f6></i><i class=cd8f2fc></i><i class="s5"></i><i class=c6fcff4></i><i class=c00a7ec></i><i class="s13 c00aced"></i><i class=c00a9ec></i><i class=c40c0f1></i><i class="s4"></i><div class="cb"></div><i></i><i></i><i class=ccaedfa></i><i class=c02aaec></i><i class=c00abed></i><i class="s6 c00aced"></i><i class=c00a9ed></i><i class=c00a7ec></i><i class=c07aeed></i><i class=c3bbef1></i><i class=c78d2f5></i><i class=cace4f9></i><i class=cd1f0fc></i><i class=ce9f8fd></i><i class=c7ed4f5></i><i class=c00a8ec></i><i class="s13 c00aced"></i><i class=c00a8ec></i><i class=c46c2f1></i><i class="s4"></i><div class="cb"></div><i class="s3"></i><i class=c77d1f3></i><i class=c00a6ec></i><i class="s8 c00aced"></i><i class=c00abed></i><i class=c00a9ed></i><i class=c00a7ec></i><i class=c00a8ec></i><i class=c00aced></i><i class=c11b1ee></i><i class=c11b1ee></i><i class="s14 c00aced"></i><i class=c00a8ec></i><i class=c4cc5f2></i><i class="s4"></i><div class="cb"></div><i></i><i class=ce1f5fc></i><i class=cb1e4f9></i><i class=cf2fbfe></i><i class=c5dcaf3></i><i class=c04abed></i><i class="s12 c00aced"></i><i class=c00abed></i><i class=c00abed></i><i class="s14 c00aced"></i><i class=c00a8ec></i><i class=c63ccf3></i><i class="s4"></i><div class="cb"></div><i></i><i class=cd0effb></i><i class=c00a9ec></i><i class=c26b7ef></i><i class=c51c6f2></i><i class=c0fb0ee></i><i class=c00abed></i><i class="s27 c00aced"></i><i class=c00a7ec></i><i class=c85d6f6></i><i class="s4"></i><div class="cb"></div><i></i><i class=cf3fbfe></i><i class=c18b4ee></i><i class=c00a8ed></i><i class=c00a9ed></i><i class="s29 c00aced"></i><i class=c00a8ec></i><i class=cb1e5f9></i><i class="s4"></i><div class="cb"></div><i></i><i></i><i class=c5fcaf3></i><i class=c00a7ec></i><i class="s29 c00aced"></i><i class=c00abed></i><i class=c07aeed></i><i class=cdef4fc></i><i class="s4"></i><div class="cb"></div><i></i><i></i><i class=cd0effb></i><i class=c04abec></i><i class=c00abed></i><i class="s28 c00aced"></i><i class=c00a9ed></i><i class=c33bcf0></i><i class=cfeffff></i><i class="s4"></i><div class="cb"></div><i class="s3"></i><i class=c85d6f4></i><i class=c00a6ec></i><i class="s28 c00aced"></i><i class=c00a7ec></i><i class=c7fd4f5></i><i class="s5"></i><div class="cb"></div><i class="s4"></i><i class=c6ecff4></i><i class=c00a7ec></i><i class=c00a9ed></i><i class="s26 c00aced"></i><i class=c03aced></i><i class=cd4f0fb></i><i class="s5"></i><div class="cb"></div><i class="s5"></i><i class=cade4f9></i><i class=c30baf0></i><i class=c04aced></i><i class="s24 c00aced"></i><i class=c00a8ed></i><i class=c45c2f0></i><i class="s6"></i><div class="cb"></div><i class="s4"></i><i class=ce1f5fc></i><i class=cb1e5f9></i><i class=ca7e2f8></i><i class=c46c1f1></i><i class=c02aced></i><i class="s23 c00aced"></i><i class=c00a8ec></i><i class=cb9e7f8></i><i class="s6"></i><div class="cb"></div><i class="s4"></i><i class=ce2f5fc></i><i class=c05adec></i><i class=c00a8ed></i><i class="s24 c00aced"></i><i class=c00a8ed></i><i class=c42c1f0></i><i class="s7"></i><div class="cb"></div><i class="s5"></i><i class=c8cd8f5></i><i class=c00a6ec></i><i class="s23 c00aced"></i><i class=c00abed></i><i class=c04abec></i><i class=ccdeefa></i><i class="s7"></i><div class="cb"></div><i class="s5"></i><i class=cfdfeff></i><i class=c54c6f1></i><i class=c00a6ec></i><i class="s22 c00aced"></i><i class=c00a6ec></i><i class=c7cd3f4></i><i class="s8"></i><div class="cb"></div><i class="s6"></i><i class=cf8fdfe></i><i class=c62cbf3></i><i class=c00a8ec></i><i class=c00a8ec></i><i class=c00abed></i><i class="s18 c00aced"></i><i class=c00a8ed></i><i class=c3ebfef></i><i class=cfafdfe></i><i class="s8"></i><div class="cb"></div><i class="s8"></i><i class=cb0e5f9></i><i class=c42c0f1></i><i class=c0bafed></i><i class=c02aced></i><i class="s16 c00aced"></i><i class=c00a9ed></i><i class=c20b4ee></i><i class=ce3f5fc></i><i class="s9"></i><div class="cb"></div><i class="s10"></i><i class=ce8f7fd></i><i class=c6fcff4></i><i class=c03abec></i><i class="s14 c00aced"></i><i class=c00a9ed></i><i class=c18b1ed></i><i class=cd1effb></i><i class="s10"></i><div class="cb"></div><i class="s9"></i><i class=cdcf3fc></i><i class=c6bcef4></i><i class=c0baeed></i><i class=c00abed></i><i class="s13 c00aced"></i><i class=c00a7ec></i><i class=c1fb4ee></i><i class=ccfeffb></i><i class="s11"></i><div class="cb"></div><i class="s6"></i><i class=cf5fcfe></i><i class=cbee9fa></i><i class=c64cbf3></i><i class=c0dafee></i><i class=c00a7ec></i><i class="s13 c00aced"></i><i class=c00abed></i><i class=c00a7ec></i><i class=c3dbef0></i><i class=cdff4fc></i><i class="s12"></i><div class="cb"></div><i class=ccaecf9></i><i class=c98ddf7></i><i class=ca2e1f8></i><i class=c96ddf7></i><i class=c7dd4f5></i><i class=c4ec5f2></i><i class=c20b6ef></i><i class=c00aaec></i><i class=c00a7ec></i><i class=c00abed></i><i class="s13 c00aced"></i><i class=c00a8ec></i><i class=c07aced></i><i class=c7ad3f5></i><i class=cf9fdfe></i><i class="s13"></i><div class="cb"></div><i class=cecf9fd></i><i class=c8fdaf6></i><i class=c1ab2ee></i><i class=c00a2eb></i><i class=c00a4eb></i><i class=c00a7ec></i><i class=c00aaed></i><i class="s13 c00aced"></i><i class=c00abed></i><i class=c00a7ec></i><i class=c00aaec></i><i class=c4ec4f2></i><i class=ccceefb></i><i class="s15"></i><div class="cb"></div><i></i><i></i><i class=cf4fbfe></i><i class=c9ddef7></i><i class=c3dbef1></i><i class=c03aced></i><i class=c00a7ec></i><i class=c00a8ec></i><i class=c00aaed></i><i class=c00abed></i><i class="s5 c00aced"></i><i class=c00abed></i><i class=c00abed></i><i class=c00a9ed></i><i class=c00a7ec></i><i class=c00a8ec></i><i class=c13b1ee></i><i class=c5dc9f3></i><i class=cc3ebfa></i><i class="s17"></i><div class="cb"></div><i class="s5"></i><i class=cd2f0fc></i><i class=c8dd9f6></i><i class=c4dc4f2></i><i class=c22b6ef></i><i class=c09aeed></i><i class=c00aced></i><i class=c00aaed></i><i class=c00aaed></i><i class=c00aaed></i><i class=c00abed></i><i class=c03aded></i><i class=c13b2ee></i><i class=c33bcf0></i><i class=c63cbf3></i><i class=ca8e2f8></i><i class=ce6f7fd></i><i class="s19"></i><div class="cb"></div><i class="s8"></i><i class=cf7fcfe></i><i class=ce0f4fc></i><i class=ccfeffb></i><i class=cc3ebfb></i><i class=cc1ebfb></i><i class=cc1ebfb></i><i class=cc8edfb></i><i class=cd7f2fc></i><i class=cebf8fd></i><i class="s23"></i><div class="cb"></div></div>
醉南桥 2024-12-21 03:44:55

哎呀,这是函数:
http://www.php.net/manual/en/function.imagecolorat.php

但这样做会非常非常非常低效,因为不是每个像素传输一个数字,而是使用 div 传输一个字符串,所以不要指望加载时间会更短。

Jep, here's the function:
http://www.php.net/manual/en/function.imagecolorat.php

But it would be very very VERY inefficent to do this, because instead of transfering one number per pixel you are transferring a string with the div, so don't expect a shorter loadingtime.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文