PNG23D logo by kyllikki



Although the tool was primarily developed for 3D printing applications, the STL output is two maifold and most CAD applications will import the output correctly.

Usage is based around the command line in a similar manner to the ImageMagick two dimensional image manipulation tool.

The full set of available command line switches may be found in the man page accompanying the program source.

As outlined in the main overview conversion is a five stage process each is detaild in their own secions below. The operations used to perform the conversion are:

Source Image
Read, decode and process the source image into a greyscale bitmap.
Mesh Generation
Generate a triangle mesh creating a manifold polygon.
Mesh Indexing
Index the vetices of the generated mesh.
Mesh Simplification
Simplify the generated mesh.
Write the generated mesh to output file in selected format.

The -v switch can be used to increase the verbostiy of the tool and get some basic statistics and values about each stage of operation.

3D printing

If you are using the output from this tool for 3D printing some specific properties have been discovered (from printing lots of faliures!)

Source Image

The input file must be a PNG image that the libpng library can read and a filename must always be provided as a parameter. The image is converted into a 256 level grey scale image using libpng.

The source filename may be given as a single - which indicates input will be taken from the standard input. This allows for an image conversion program to be chained with the png23d program.

The example here uses the imagemagick convert tool to convert a gif image to png output, with colour manipulation and cropping, and immediatly passes the generated image to png23d without an intermediate temporary file.

convert JohnvonNeumann.gif -quantize GRAY -dither none -colors 256 -negate \
-crop 350x510+90+60 +repage png:- | ./png23d -t x -f surface -o stl -l 25 \
-d 9.6 -w 100 - JohnvonNeumann.stl

Mesh Generation

This part of the process has a large impact on the output and should be tailored to the final use of the model.

The x and y components of the generated mesh are, in all cases, derived from the source images dimensions. For 3D printing these should be arranged to give around a 0.5mm spacial resolution in final scaled output (see the 3D printing section).

The z component is synthesised form the source greyscale image levels. The number of levels is controlled by the -l parameter. To illustrate, if four layers are selected colours from 0-63 will generate mesh output on layer 1, 64-127 on layer 2 and so on.

In adition to the number of layers a single colour may be selected, with the -t switch, as "transparent" which will result in no mesh being present at that x-y location. One oddity here is that if a single layer is specified and the transparancy is turned off (with -t x) the output will be a solid block.

currently there are four generation methods implemented, two general purpose and two which operate on a single layer. These methods are selected with the -f parameter.

This finish can only be used on single layer output. The bitmap is considered one pixel at a time and runs of non transparent pixes are converted into retangular cuboids. This finish is only useful with the rscad output type, specifying it with any other output type will generate an error.
This finish can only be used on single layer output. The non transparent areas of the bitmap are passed through the marching squares algorithm which produces a reasonable contour on the filled areas. This finish is the default and is especially good for converting 2D logos and text into a smooth contoured three dimensional extrusion suitable for use in OpenSCAD models.
This finish may be used with any number of valid levels. The bitmap is scanned and the transparency of each unit voxel considerd (as defined by its x and y position in the bitmap and its colour value as the z component). The faces of an opaque voxel whose neighbours are transparent get that face added to the mesh (as two right angled triangles). This finish produces a manifold mesh with (potentially) many levels. Caution should be employed using this finish for non-synthetic image sources as the result may become extremly complex and challenging to simplify.
This finish may be used with any number of valid levels. This finish is more suitable for complex heightfields like photographic images (used for lithophane generation). It simply creates triangle strips between each set of four pixels within the image (the edges being combined with virtual zero height pixels to ensure the mesh is manifold). This produces results which can never have vertical sides but are not subject to the "blocking" effect the cube finish produces.

Mesh Indexing

The indexing of the mesh is largely opaque to the user. This process costructs a face-vertex index for the triangular faces (facets) generated in the previous step. The process is greatly accelerated by the use of a bloom filter.

The only tunable parameter to the indexing process is the -b switch, this switch controls the size and number of functions for the bloom filter (and hence its efectiveness). The default value of 2 generally gives satisfactory results. For very complex meshes this value may need to be increased to reduce the mesh indexing time at the cost of increased memory usage.

Mesh Simplification

This is controlled with the -O switch similar to the optimisation level of a compiler. As of version 1.1 only the values 0 and 1 are usable. The value 0 simply turns off any optimisation and skips simplification altogether.

An optimisation level of 1 performs a half edge removal. Each vertex is visited and every neighbour vertex in the mesh used to create an edge. Each of these edges is considered for removal. If it is possible to remove the edge without damaging the topology of the mesh it is removed and the process repeated untill there are no more edges to consider.

The simplification process by its nature increases the number of faces which are joind to a single vertex. The complexity of a single vertex is limited by the -c parameter which may be set to a value between 8 and 128. The default of 16 is is a reasonable compromise on mesh complexity and memory usage. Increasing this parameter may result in output meshes with fewer vertices but will consume large quantities of memory (on a 64bit system changing from 16 to 32 adds 128bytes per vertex or 24 megabytes for a simple 200,000 vertex model)

The edge removals can be visualised for debugging purposes by specifying a filename with the -m switch. Caution should be exercised as the resulting html files can be huge. To illistrate here is an example of the output for the o.png test image.


The output file may have any arbitrary filename which must be specified. The output filename may be given as a single - which indicates output will be sent from the standard output.

The output file format is controlled by the -o switch. The file formats available as of version 1.1 are:

3D systems Stereolithography in binary (The default)
3D systems Stereolithography in ASCII
OpenSCAD module describing a polyhedron in ASCII
OpenSCAD module describing union of cubes in ASCII
Netpbm (PGM type) in ASCII

The output scaling for width, depth and height are controlled with the w,d,h switches respectively. It should be noted that these only control scaling applied to the output and not the size or complexity of the mesh. The values are dimensionless although convention in most of the supported output formats is one unit is one millimetre.