d3 is great for creating charts but also fun to play around with in other ways. Here we’ll use d3 in conjunction with canvas to create a pixelated version of an image. It’s hard to think of any useful applications for this but we’ll go ahead anyway.
Below is the original image, inside a canvas element, and a pixelated SVG version below created with d3. Click the “Change” button to change the source image. Use the slider to change the size of the pixels:
First set up the HTML. This could be included in the code but having it in one place in the HTML let’s you easily change the image source and size:
The image load handler closes with a call to a function pixelate, passing in the image and the size (width and height) for the squares to create. (NB: The opening example just calls pixelate with the current slider value for the square size on change events.) The pixelate function reads the colors from the canvas image to create the data for the pixelated rendering:
The pixelate function creates an array of objects, each representing a square in the final rendering with x and y positions and an average color value.
Lines 9-10 Loop through all the squares, left to right and top to bottom.
Line 12 The getImageData function returns an array of color channel values for the specified square in the image. The data are a flat array of rgba values: [r0, g0, b0, a0, … rN, gN, bN, aN].
Line 21 Sum the color channel values for the square.
Line 28 Add a data object for the square with the x-y position and the mean color value.
The pixelate function closes by calling drawSvg, passing along the image data. This function uses d3 to bind the data to rect elements:
The drawSvg function just uses the basic d3 enter-update-exit pattern to render the squares at the specified positions with the specified fill color. And now at long last you can use d3 to render pixelated images.