Machining an Image Into a Slab of Paint




About: Michael Koehle is the CNC shop assistant at Autodesk Pier 9. His background is in engineering and in art. He combines these to make work using drawing, painting, CNC, 3D printing, and laser cutting.

This Instructable describes how to machine an image into a slab of paint. The relief to be machined is developed from a photograph, where the brightness of each pixel determines the height of the relief. The slab of paint is made up of hundreds of coats of paint, forming a gradient from black to white. By machining the paint slab to different depths, different shades of gray are revealed, forming an image.

This project isn’t for the faint hearted, and requires a lot of time and resources.

Things you’ll need:

· A 3-axis CNC machine

· CAM software and know how (I use Visual Mill)

· Black and white acrylic house paint.

· Some light programming skill. I'm including an Octave script that can be used to generate the STL surface model.

Step 1: Making the Relief - the Concept

Before we can physically make anything, we first need to develop the relief model from the photograph. This is easiest if we start with a black and white image. A black and white image can be represented by a 2D matrix, where the indices are the pixel position. Each pixel has a brightness value, from 0 to 1, where 0 is black and 1 is white. The image below shows a simple matrix and corresponding image. The brightness value of the pixel at indices [2,2] is 0.5.

Now imagine that the brightness values are instead a height, where 1 is the tallest and 0 is the shortest. The matrix could be thought of as a set of xyz coordinates. For example, the coordinate for the pixel at [2,2] would be 2,2,0.5. Fitting a surface to these coordinates would result in following:

If you add a gradient to the surface, then when seen from above, this surface will appear to be equivalent to the source image.

Step 2: Making the Relief - the Method

I'm attaching an Octave script ( - a free language similar to matlab) that will convert an image into a surface. To run this, you will also need a function surf2stl ( Along with the file name, you will need to specify the desired size of the finished model. It is set so 0 is black and pure white will be the +z limit of your model.

This code interprets the black and white image matrix as a surface, which it then converts to an STL.

Step 3: Making the Substrate

This is a time intensive process. It involves painting multiple layers of different shades of acrylic house paint until the desired height is achieved.

Paint Mixing

By mixing black and white paint into several shades, a slab can be made that transitions smoothly from black to white. I found that 30 was a good starting point, mixed in ratios of black to white of 0:30, 1:29, 2:28, etc. However, at both ends of the grayscale, mostly white or mostly black, the difference in shades was more pronounced. Here, I made more mixes, but painted fewer coats with each mix. My total shades, with these half-steps was probably closer to 36.

Paint Application

For apply paint, I found a roller gave the most even, consistent coats of paint. I tried other methods, applying the paint in thicker layers, but found as the layers built up, it was hard to keep the surface level. Thick layers of paint could also crack. I let the paint dry at least a half hour between coats (when it felt dry to the touch), but this may change depending on the type of paint you are using, and the temperature/humidity. I applied the paint to plywood panel, which I also used for fixation.

Paint Volume

How much paint do you need? This takes some planning and some trial and error to figure out. On the acrylic paint can, the labeling will tell you the coverage, per gallon. From this you can calculate the thickness of each coat of paint (volume/coverage However, this will not give you the dry thickness, as a lot of volume (40-70%) will disappear as the paint dries. How much depends on the brand and type of paint. I found that Behr Premium (interior eggshell) had pretty small volume loss (about 50%), is fairly inexpensive, and machines well (for paint). If using Behr Premium, you would need a volume of paint equal to twice the volume of the slab you want to create. For example, a paint slab 12” x 12” x 0.5” has a volume of 72 in^3 or 0.0417 ft^3. You would need twice this amount of paint for this slab, .0833 ft^3 or about 0.63 gallons.

Knowing the coverage will also give you a sense of how many coats of paint you will need to paint. For example, Behr has a coverage of 400 sq ft, per gallon. This means each coat has a thickness of .004 inches (1 gallon or .1334 ft^3/400 ft&2). Half that thickness will be lost in drying, so each coat’s dry thickness is .002. To achieve a half inch height for your slab, you will need 250 (.5”/.002”) coats of paint.

I would suggest that you paint up a few substrates at the same time, as this can take several days, if not weeks, to paint.

Step 4: Programming the Machining Operations

Now that you have your substrate and your model, you are ready to program the machining operations. A relief at a reasonable resolution has a high polygon count, which eliminates some software packages, like CAMWorks and MasterCam, because the files are too big to handle. My image was 629x800 pixels, and resulted in an STL with just over 1 million polygons. I used Visual Mill for my CAM software.

I machined this as I would a soft plastic. The end mills to use depend on your image size and resolution. My CNC machine is a Roland 540. For roughing I used a ¼” ball mill at 12000 RPM, cutting at 30 in/minute. For my 11x14” image, the smallest ball mill I used overall was 1/8”. However, I used a 1/16" ball in areas of high detail. My machining time was around 12 hours.

If your CAM software can provide a color comparison between the simulated part and the model, this is helpful to check if your model will be machined with the desired level of accuracy. You can apply a black-to-gray color map, and see how closely the simulation matches the source image.

Best of luck! If you try this, I’d love to hear about it.



    • Growing Beyond Earth Maker Contest

      Growing Beyond Earth Maker Contest
    • Backyard Contest

      Backyard Contest
    • Sensors Contest

      Sensors Contest

    10 Discussions


    3 years ago

    Hi !

    Your project is amazing ! I love it.
    I'm currently doing it but I have a problem. Iwritten a smaal program with Processing and I got my .txt file with all the points. The problem is that i can't find the right parameter to remesh my cloud of point. Maybe could you help me or describe a little more the steps to do this ? I tried the Poisson method but it didn't work.

    I'm planning to glue like 50 page that i'm going to print to make a bloc with a gradient of grey instead off painting layer by layer to save some time. I'll post the result.

    Thanks for your help and sorry for my english, I come from Belgium.

    2 replies

    Reply 3 years ago

    I've uploaded an Octave script that will do the image-to-STL conversion. Let me know if you have any problems.


    Reply 3 years ago

    Thanks for your answer. I finally did it with matlab and a function (stlwrite). It works great ! Now, I have to program it for my cnc.

    el greeno

    3 years ago

    wow. this is pretty cool.


    3 years ago on Introduction

    Wow you blew my mind! Cool to see a subtractive process create a positive image! It really jumps right out...


    3 years ago on Introduction

    Over my head technically but WOW! I agree with CATP12 - as an artist I would be a buyer.


    3 years ago

    Make this process automated and you have a possibly multi million dollar product.