Introducing Joel Simons' imageToPaint

I’ve been on the look out for a way to draw stuff, paint stuff plot colour photos etc with gcode for some time now.

Finally I found this page:

Since this wasn’t on Joel’s Github page, I contacted him asking if he would share the code. He very kindly shared the prototype version he had, and also agreed to get it on Github and licensed so it can be shared and possibly developed.

Well, not only has he put it on Github after just a couple of days, it’s all tidied up and documented nicely.

Having worked with the software for a bit I’m excited and astounded at the possibilities, so take a look and see if you like it.

And thanks again Joel!


1 Like

From this photo:

[attachment file=47580]

To gcode that will produce this (with the right brushes/colours):

[attachment file=47581]


And if all you have is a pen, no problem:

[attachment file=47584]





1 Like

I will definitely be checking this out!! Thanks for the heads up!


I can’t wait to see how this comes out, pretty cool.

This looks great. It’s pretty clear code too, so I think we can edit it pretty well.

Big thanks to Joel for sharing and thanks to James for finding it and encouraging sharing.

I gave it a go last night…first image I sent through it was apparently too complex/muddled as the resulting gcode looks like spaghetti :smiley: I need to find a more appropriate image to test it with.

One little thing I ran into is that PIL is apparently no longer supported, but pillow seems to work as a replacement (then again maybe that’s why I got spaghetti…I should test it with the provided apple image…)

If you try with --f_grid 1 as a starting point, that will reduce the gaps between the lines to n multiples of the brush width

So if you run with --brushes 2 --f_grid 1, you should see a really close image to the input. Unfortunately the gcode will be huge, but it’s a starting point.


Actually…I guess with color it’s possible to kind of see how it relates to the original:

[attachment file=47648]


[attachment file=47649]

I tried varying the T “Threshold to create a new stroke” by dropping it from the default 10 down to 5 and then again to 2…but both only resulted in one additional stroke so no not much more detail. I also tried increasing it to 15 and didn’t see any real difference.

This one did a little better:

[attachment file=47650]


[attachment file=47652]

And one of me:

[attachment file=47651]


[attachment file=47653]

So…seems like having a high contrast well cropped image is key to getting something usable.

That’s pretty true of any method taking an image and creating a drawing. Unless you’re making a Monet.

Start simple with a logo or something, and see if you can at least get something that looks nice. I would also try with a darker image. It looks like it’s drawing fewer lines because it’s trying to not darken the image as much.

As for PIL vs. pillow, if it doesn’t throw exceptions, then it’s probably fine, but any future modifications will be harder. At any rate, converting to pillow shouldn’t be hard. There aren’t any advanced functions being used, just reading in the image, and treating it as an array.

Did you try --brushes 2 --f_grid 1?

If you want to see it produce recognisable images, you need to consider decreasing the gap (f_grid). It feels a bit like I’m stalking you, but I used your first example to demonstrate.

Note, the gcode size is a consideration for detailed images, but if we’re talking about just output quality, this is the output possible:

[attachment file=47662]

If you want a version that’s doable with less gcode and monochrome, a bit of pre-processing the image will help.

Threshold processed:

[attachment file=47663]

Edge detection:

[attachment file=47664]

1 Like

BTW, I did the processing in Gimp if you didn’t guess. And I thought it would be fun to upload the gcode for the line art version. It’s 1.3Mb, and 13k lines.

Gcode simulation says it would plot in 1h:39m, so not bad really.

strokes_2.txt (1.21 MB)

One of the first things I thought of when looking through this code is to port it to a gimp plugin instead of a standalone application. Gimp no doubt has some libraries already picked out and tuned for gaussian, sobel, etc. It would be nice if it was fast enough for a live preview, sort of like the inkscape trace bitmap menu. Plus, a lot of people can install gimp and paste in a plugin. Some folks have a hard time even running python, let alone python plus dependencies like PIL.

That’s an interesting idea because since you mention plugins, my first thought would be Inkscape.

But on reflection Gimp is a better fit. It’s handling images and has a good preview workflow.

Yeah, I have a background in photography and graphic design (even though I work day to day as a sysadmin/coder) and can think of a LOT of things I could do to improve the results.

But I didn’t have time to open an image editor and do any of them so I just picked a few things that looked like they may have decent enough subject matter that it could have a chance of doing something usable.

Adjusting the brushes makes sense if you’re looking for an image - but doesn’t really help with the gcode unless you’re using a large brush or marker :wink: So I left them small to get a feel for how the gcode would look.

Honestly I was surprised at how well it did for what I gave it to work with. Makes me wish my MPCNC was still portable. We’re opening our office as part of a local “art walk” next Friday and I’d love to have the MPCNC setup doing some drawings - but there’s no getting it out of my shop right now. Maybe next spring (we host them twice a year.)

Now if it would just generate the image all in one line for the ZenXY…

I should have made clearer it’s the --f_grid param that makes the most difference making images less spaghetti like rather than the brush width