tags:

views:

57

answers:

2

I'm using this block of code (mostly copied from a PHP.net comment here - http://www.php.net/manual/en/function.imagecolorat.php) in order to read in a picture, scan it pixel by pixel and output the picture as a block of div tags in a table-like fashion. Here's what I came up with...

<?php 
$img = imagecreatefrompng("image1.png"); 

$w = imagesx($img); 
$h = imagesy($img); 

for($y=0;$y<$h;$y++) { 
   for($x=0;$x<$w;$x++) { 
      $rgb = imagecolorat($img, $x, $y); 
      $r = ($rgb >> 16) & 0xFF; 
      $g = ($rgb >> 8) & 0xFF; 
      $b = $rgb & 0xFF;
      $hex = "#".str_repeat("0",2-strlen(dechex($r))).dechex($r). 
              str_repeat("0",2-strlen(dechex($g))).dechex($g). 
              str_repeat("0",2-strlen(dechex($b))).dechex($b);
     echo "<div style='background: {$hex}; height: 5px; width: 5px; display: inline;'></div>\r\n";
     /*
        echo "#".str_repeat("0",2-strlen(dechex($r))).dechex($r). 
              str_repeat("0",2-strlen(dechex($g))).dechex($g). 
              str_repeat("0",2-strlen(dechex($b))).dechex($b).","; 
     */ 
  } 
  echo "<br />\r\n"; 
} 
?>

I've tried using 'block', 'inline', 'inline-block' and 'inline-table' for the display property of the divs, but they each seem to make their own problems. I either get nothing at all, columns of pixels going straight down in a vertical line or the divs line up correctly in a square, but with spacing between them (which shouldn't happen since I'm using a reset.css to eliminate all padding, spacing, etc).

Also, this particular function doesn't seem to account for transparency. The picture I'm using has transparent pixels in it and it seems to be outputing them as a light blue.

Link - http://schnell.dreamhosters.com/folio/pixelread.php

+1  A: 

Well, this is an interesting one. I can't vouch for that function accounting for transparency, but the HTML positioning problem should be easy enough to solve.

I think the best solution would be to create a container as wide as the image, then float all of the divs left. Something like

echo "<div style='width: ".($imagesx * 5)."px;' class='outer'>";

Which will give the width you need (if I understand the code correctly). Then you simply use this CSS:

.outer div {
  width: 5px;
  height: 5px;
  float: left;
}

Doing this will effectively reduce the number of redundant inline styles you have to generate. Oh, and remove the br generated after each row.

As for the alpha transparency problem, I believe this comment should help you: http://www.php.net/manual/en/function.imagecolorat.php#79116


Edit

You forgot the px on width: 65px! This is being generated.

<div style='width: 65; background: #eeeeee; margin: 0px auto;'>

Also, nice Mario. ;)

Yi Jiang
Ok, I pretty much did exactly this, but without a line break it's creating a long straight line of pixels.
Mathias Schnell
Oh! Derp! And thanks. :D Now to take care of that transparency problem...
Mathias Schnell
A: 
 echo "<div style='background: {$hex}; height: 5px; width: 5px; position: absolute; top: {$y * 5}; left: {$x * 5};'></div>\r\n";

You'll want to place them all within a position: relative; containing element. And probably remove the <br>s too.

kevingessner
Yeah I know that's one solution and I've done it before with some other similar problems, but I was looking for one a little more fluid and less calculation involved.
Mathias Schnell