Image sampling using NodeBox, rendering image data with jQuery and CSS

An experiment using NodeBox, jQuery and CSS. Using NodeBox generate a pixel sampling of an image, create a css file with the data, then use jQuery to render out the colour blocks to recreate the image using divs only.

Just an interesting experiment, would love to see what others can extend this to, please have a play around, code listed in the how to section. Any feedback welcome.

This is an experiment I realise rendering this many divs, large css etc is not something you'd be using every day :)

how to instructions

Examples

The below have a sampling every 10x10 pixel area of the source image. This creates a sampling that runs to over 2,500 distinct RGB blocks.

  1. Chewbacca
  2. Obama
  3. Marilyn
  4. Mother Teresa
  5. Jack Nicholson
  6. Boba Fett

The below have a sampling every 20x20 pixel area of the source image. Reducing the sampling to 20x20 pixel area results in 639 distinct RGB blocks.

  1. Chewbacca
  2. Obama
  3. Marilyn
  4. Mother Teresa
  5. Jack Nicholson
  6. Boba Fett

Decreasing the blocksize to 5x5 pixels has a dramatic effect on the quality rendered but generates 10,473 distinct RGB blocks. Looks great and you should try it out but I'm not putting it live as its a bit of an animal on filesize etc

1. The NodeBox code

Few requirements to follow along, the main one is installing NodeBox.
Nodebox is a Mac OS X application for visual generation using python.
You can download NodeBox here.

Create a new file with NodeBox and paste in the below code. The code is expecting an images folder at the same level as your NodeBox file. You should have your target image in that folder. "targetfile" references the image you want to pull in and the code is set to expect ajpg, all of this can be changed to your suiting.

	
#a lot of the below relating to canvas and pixels is taken from the NodeBox Coreimage lib page 
#learn about coreimage here http://nodebox.net/code/index.php/Core_Image
size(440,595)
fill(0.2)
rect(0,0,WIDTH,HEIGHT)
coreimage = ximport("coreimage")
canvas=coreimage.canvas(WIDTH,HEIGHT)
# target image filename 
targetfile="boba-fett"
#string for filename of outputted css and js files
#good to use a different var here as you can leave the image source the same but change the blocksize and render different css files for different versions
outputfile="boba-fett"

#set size of grid division,
#this also defines then the width, height of the divs that render the blocks of colors
#the smaller this int is the more color blocks will be recorded and reverse is true
blocksize=10

l=canvas.layer("images/"+targetfile+".jpg")
p=l.pixels()

p.colormode=(RGB,255)
w,h=l.size()
count=1

#define the start of the css string we will create
css=".block{float:left;-moz-border-radius:1px;-webkit-border-radius:1px;border-radius:1px;margin:0px;width:"+str(blocksize)+"px;height:"+str(blocksize)+"px}"

#loop through the grid thats based on blocksize
for x,y  in grid(w/blocksize, h/blocksize, blocksize, blocksize):
    clr=p.get_pixel(x,y)
    #get r value from Color object, multiply by 100 to get it iinto correct value for css
    r=str(clr.r*100)
    #split r at '.' to get proper value for css
    r=r.split('.')[0]
    #do same for g and b values from Color object
    g=str(clr.g*100)
    g=g.split('.')[0]
    b=str(clr.b*100)
    b=b.split('.')[0]
    #add a class def for every color value to the css string we are building
    css+=".b"+str(count)+"{background: rgb("+r+","+g+","+b+");}\n"
    fill(clr)
    #draw rect at given x,y with fill set above
    rect(x,y, blocksize, blocksize)
    count+=1

#good idea to watch what the total count is here
#the lower blocksize val you use the higher this count
#obviously the css etc can start to become unwieldly
print ('count is',count)

#writing the string for the js file we will include on the page.
#setting the int for the point in the js loop we want the div to clear:left
#also setting the total number of blocks
js="var countbreak="+ str(WIDTH/blocksize)+"; var blockcount="+str(count)+";"

#write the css file
cssfilestr=outputfile+".css"
cssf=open(cssfilestr,'w')
cssf.write(css)
cssf.close()

#write the js file
jsfilestr=outputfile+".js"
jsf=open(jsfilestr,'w')
jsf.write(js)
jsf.close()




2. Include the generated css and js files in your page (+jQuery).

Minify your css they can be large...

<link href="boba-fett.css" type="text/css" rel="stylesheet" >
<script src="boba-fett.js" ></script>

3. Function in page for rendering color blocks

Remember you'll need to have jQuery included in your page before you can call this

$(document).ready(function() {
		var count=1;
		var tclass="";
    for (i=1;i<=blockcount;i++){
		if(count==countbreak){
                    tclass="clear"
                    count=0;
		}else{
                    tclass=""
		}
		
        $(".portrait").append('<div class="b'+i+' '+ tclass + ' block"></div>');
	count++;
    }
 });