Vector halftone: how to make dots that scale and cut
A vector halftone stores every dot as a shape. How to make one in Inkscape or CorelDRAW or with a few lines of code, and what to check before cutting it.
Published
A vector halftone is a halftone in which every dot is a shape, a circle or a closed path, and not a patch of pixels. It looks the same as any other halftone on screen. The difference shows when you use it: vector dots stay sharp at any size, take a new colour in one click, and can be followed by a cutter, a pen plotter or a laser.
This page covers three ways to get one: a tiled-clone trace in Inkscape, the Pointillizer effect in CorelDRAW, and a short script that writes the circles directly, each with the version of the program its documentation covers. If the word halftone itself is new, start with What is a halftone?
What is in the file
Open a vector halftone in a text editor and it is a list of dots:
<svg xmlns="http://www.w3.org/2000/svg" width="40mm" height="10mm" viewBox="0 0 40 10">
<circle cx="5" cy="5" r="4.2"/>
<circle cx="15" cy="5" r="3.3"/>
<circle cx="25" cy="5" r="2.1"/>
<circle cx="35" cy="5" r="0.9"/>
</svg>
Four dots on a line, 10 mm apart, shrinking from left to right. A real one has hundreds or thousands of them, and some programs write them as paths or as one compound path, but the idea is the same: a position and a size for each dot.
The number of dots grows quickly. On a grid, it is the area divided by the square of the spacing. A 200 mm square with dots 2 mm apart holds 10,000.
What does not count
Two things look like vector halftones and are not.
- A raster halftone inside a vector file. An SVG, PDF or AI file can hold an embedded picture. If the dots go soft when you zoom in, they are pixels.
- A pattern fill. A shape filled with a repeating dot pattern is one shape with paint on it. As our pattern generator page puts it, “A pattern fill is paint, not shapes. A cutting machine or a pen plotter follows outlines and takes no notice of how a shape is filled”. It also cannot change dot size across the shape, so it can only be a flat tint.
Inkscape: tiled clones that trace
Inkscape can lay a grid of copies of a dot over a picture and size each copy from the picture underneath. The steps follow Tavmjong Bah’s guide to Inkscape, which documents versions 0.92 and 1.0 (Tiling: Trace).
- Put the photo or gradient on the page.
- Draw a small circle at its top-left corner. This is the tile.
- With the circle selected, open Edit > Clone > Create Tiled Clones.
- At the bottom of the dialog, set the size of the tiling, by rows and columns or by the width and height to cover.
- On the Trace tab, tick Trace the drawing under the tiles.
- In the top section, pick what to read from the picture: the colour, one of the red, green and blue components, or one of hue, saturation and lightness.
- In the bottom section, tick Size, so that the value sets the size of each clone. If the big dots land on the light areas, use the invert option in the middle section.
- Click Create.
The dots are clones, linked to the first circle. To turn them into ordinary objects, select them and use Edit > Clone > Unlink Clone. Then delete the picture underneath.
With the default settings the tiles sit edge to edge in straight rows and columns. The Shift tab of the same dialog changes the spacing, and has a shift for each row with an Alternate option, which is the place to experiment if you want every other row staggered as in a 45° screen.
CorelDRAW: Pointillizer
CorelDRAW has an effect made for this. Its help says the Pointillizer “lets you create high-quality vector mosaics from any number of selected vector or bitmap objects. Whether you are looking to create precise halftone patterns or artistic effects that resemble pointillistic art”. The steps are from the CorelDRAW 2019 help (Vector mosaics).
- Select a vector object or a bitmap.
- Click Effects > Pointillizer.
- In the Pointillizer docker, set Method to Size modulation 2 (luminosity). The help describes it: “Brighter areas in the source are rendered as smaller tiles; darker areas are rendered as bigger tiles.” That is a halftone. The Uniform method makes every tile the same size.
- Set Density, the number of tiles per square inch, and Scale, which grows or shrinks all the tiles.
- Set Screen angle to turn the rows. Positive values turn them counterclockwise.
- Choose the Shape: a circle, a square or a closed curve of your own.
- To hold down the number of colours in the dots, tick Limit colors and type the maximum in the Number box.
- Click Apply.
Do not confuse it with Effects > Color transform > Halftone in the same program. That one, by the help’s description, “gives an image the appearance of a color halftone”. It is listed among the colour effects for an image, and the help says nothing of vector tiles.
Tracing a halftone you already have
Any black and white halftone image can be traced into shapes: with Trace Bitmap in Inkscape, or with the PNG to SVG converter in the browser. Start from a large, sharp image. A dot that is only a few pixels wide has little edge to follow and comes out lumpy, and the smallest dots can be dropped as specks: the converter has an “Ignore specks under” setting for that. The dots are traced from pixels, so they are close to circles and not exact.
Writing the dots with code
A halftone is simple enough to generate. This JavaScript writes an SVG of true circles on a 45° grid, sized by any tone function you give it. (Halftone gradient has a shorter version for a plain fade.) Run as printed, it produces 464 circles with radii from 0.32 to 1.82 mm, and none of them touch.
function halftone(width, height, pitch, tone) {
const step = pitch / Math.SQRT2; // spacing of a grid turned 45 degrees
const rMax = pitch * 0.46; // the largest dot stops short of its neighbours
let dots = '';
for (let j = 0; j * step <= height; j++) {
for (let i = 0; i * step <= width; i++) {
if ((i + j) % 2) continue; // every other point, to make the diagonal grid
const x = i * step, y = j * step;
const t = Math.min(1, Math.max(0, tone(x, y)));
const r = rMax * Math.sqrt(t); // area follows tone
if (r >= 0.3) dots += `<circle cx="${x.toFixed(2)}" cy="${y.toFixed(2)}" r="${r.toFixed(2)}"/>`;
}
}
return `<svg xmlns="http://www.w3.org/2000/svg" width="${width}mm" height="${height}mm" viewBox="0 0 ${width} ${height}">${dots}</svg>`;
}
// A fade from a dark centre to nothing at the edge, 100 mm square, dots 4 mm apart
const svg = halftone(100, 100, 4, (x, y) => 1 - Math.hypot(x - 50, y - 50) / 50);
Three details make it a proper halftone:
- The square root. Tone is about area, and the area of a circle goes with the square of its radius. To make a dot half as dark, its radius is multiplied by 0.71, not by 0.5.
- The largest dot. At 0.46 of the spacing the dots never touch, so each stays a separate shape. That caps the darkest tone at 66% ink, which is π × 0.46².
- The smallest dot. Anything under 0.3 mm in radius is left out, because a dot that small is lost in cutting and printing.
The width and height are in millimetres and the viewBox uses the same numbers, so one unit is one millimetre and the file opens at true size. SVG viewBox explained covers why.
Ready-made, and from a photo
The free halftone patterns on this site are sized by the same rule as the script, with the area of each dot following the tone: dot gradients, flat tints, radial fades, squares, diamonds and line screens, each as an SVG and a transparent PNG. In the SVG every dot is its own closed outline, a smooth curve drawn from a circle, and all the outlines of a pattern are joined in one compound path. Each pattern’s page lists its smallest dot at seven sizes.
For a photo, Plotcaster’s Dither style is a relative of the halftone: its dots are all one size, and tone comes from how many there are. Set Mark to Dots or Squares and Cell pitch to the spacing you want, from 0.3 to 4 mm, and the SVG holds one small outline per dot. The outlines are made for a pen: each is a stroked loop or square with no fill.
Before you send it to a machine
| Check | Why |
|---|---|
| Zoom far in: are the edges still sharp? | Soft edges mean an embedded image, not shapes |
| Select one dot: does only that dot highlight? | If the whole area highlights, it is a pattern fill, one image, or all the dots joined in one compound path. The last is still real outlines: the free patterns here are built that way |
| Do any dots touch or overlap? | Touching dots are cut as one shape, and the pattern loses its tone there |
| How small is the smallest dot? | Dots under about half a millimetre will not hold on a screen or survive a blade |
| How many dots are there? | Thousands of tiny dots are slow to cut and hard to weed: see SVG for Cricut and vinyl cutters |
| Is the size in millimetres? | Unitless files can open at the wrong scale |
Questions
Can I change the colour of a vector halftone? Yes. Select the dots and set the fill, or use the change SVG colour tool. That is one of the main reasons to want vector dots.
SVG, EPS or DXF? They can all hold the same shapes. SVG is read by most design and cutting software. SVG vs DXF and SVG vs EPS compare them.
Why is my vector halftone file so large? Every dot is stored, and traced dots take many more points than true circles. Fewer, larger dots, or circles in place of traced paths, bring the size down.