Commit Graph
9 Commits
Author SHA1 Message Date
bflatastic 638d55983f Image Trace: stroked lines get square caps where their ink is cut square
Create: Strokes drew every line with round caps: a square-ended line 10 px wide
had its corners 2.94 px outside the stroke.

- A line's ends are square when its ink reaches as far a third of the width to
  either side of its middle as along it (a round end stops short there by a
  seventh of the width); told from lines 3 px wide and more, all the ends of a
  line together. The stroke then has square caps (`TracedPath::square_caps`).
- The last points of a wide line's skeleton can turn towards a corner of its
  end. An end that has left the line the skeleton followed a width back (by a
  quarter of the width, 1 px at least) is put back on it; and an end may be
  pulled back as well as pushed out to where the ink ends.

Outline on the thin-line inputs: largest distance from the art 2.94 -> 0.88 px
(clean 2.94 -> 0.41; aliased 0.88 -> 0.81), mean 0.055 -> 0.050 px, anchors
14 -> 10.
2026-10-14 06:43:57 +07:00
bflatastic 62036eac6c Image Trace: Flat Logo takes the tones of an unevenly lit colour for one colour
A scan's paper is a tenth darker in one corner than in another. Flat Logo found
each tone of it as a colour of its own and traced the bands and the specks
between them: on the scanned inputs 470 paths, 21 px from the art on average.

Two palette colours are now one when the pixels between them are no fewer than
a third of those at the lesser of the two: flat colours leave only their shared
edge between them, tones of one colour fill the gap. Whether the image is flat
art at all is still asked of the tones as found.

Flat Logo on its inputs, all sizes and variants: 3.106 -> 0.090 px off on
average, 88.5 -> 0.82 px at most, 69.9 -> 3.9 paths; clean, aliased, blurred
and noisy art as before.
2026-10-13 13:01:01 +07:00
bflatastic 250da4226e Image Trace: Gradients
Gradients (params `gradients`, a checkbox in the panel for Grayscale and Color;
off unless asked for): an area whose colour changes evenly along one direction
is traced as one path filled with a linear gradient, not as bands of flat colour.

Gradients are found before the palette is made, so no colour is spent on their
bands: a connected run of smoothly changing pixels is a gradient when a plane
fits each colour channel with all three sloping the same way, the colours along
that way are at most six stops with ramps between them, and painting them back
gives the area's own pixels. Flat colour, soft edges between flat colours and
shading that goes two ways are left as they were.

The harness gains two linear-gradient inputs with known lines and stops, and
measures whether each is found, the angle of its line and the colours of its ramp.
2026-10-13 12:16:03 +07:00
bflatastic 9ca74ac011 Image Trace: Shapes, and corners whose pixel is mostly outside the shape
Shapes (params `shapes`, a checkbox in the panel; off unless asked for): a filled
outline that is a circle, an ellipse, a rectangle or a regular polygon comes out
as that live shape. A shape is only made when every point of the traced outline
lies within 0.5 px (0.2% of the shape's size, if more) of it; an ellipse whose
radii differ by less than twice that is a circle of its area.

The outline before fitting: a corner's own pixel no longer pulls the two edges
that meet there, and a one-pixel step between two long edges is the corner where
they meet. Sharp corners kept: Default 69% -> 76%, the colour presets 86% -> 91%.

The harness gains plain-shape inputs and "shapes %".
2026-10-13 10:25:05 +07:00
bflatastic 612082e26e Image Trace: Snap Curves To Lines levels lines a degree or two askew
The documented option "replaces slightly curved lines with straight lines and snaps lines near 0 or 90 degrees
to absolute 0 or 90 degrees" (helpx, Image Trace panel options); ours did the first half only.

- With Snap Curves To Lines, a straight piece at least 2 px long and within 2.5 degrees of level or upright is
  made exactly so, by moving its ends across it to their mean (the page gives no angle: 2.5 degrees is our
  choice). The pieces next to a moved end follow it.
- A junction other regions share stays where it is, so abutting regions still have one curve along their edge;
  a line between a junction and a free end is levelled to the junction.
- The harness gains askew inputs (a rectangle, a plus sign and two lines, 1 to 2 degrees off level and upright)
  and an "upright %" column: the share of the outline length that is exactly level or upright.

On the clean askew inputs (docs/image-trace-quality.md): Black and White Logo and Technical Drawing, the presets
with the option on, go from 0% to 91% and 95% of their outline exactly level or upright. Their outlines are then
0.49 and 0.59 px from the art as drawn where they were 0.05 (4.2 px at the far end of a 300 px side turned 1.5
degrees): that distance is what the option is for. Presets without the option are unchanged.
2026-10-13 09:07:13 +07:00
bflatastic 761cc2371a Image Trace: Ignore Color, and the Auto Color and Outline presets
Against the documented panel (https://helpx.adobe.com/illustrator/desktop/manage-objects/traces-mockups-symbols/image-trace-panel-options.html):

- Ignore Color: "Ignores a specific color while tracing. Use the color picker to selectively ignore a color."
  The panel's Ignore White is now Ignore Color with a colour button beside it (white until another colour is
  picked); `imageTrace.make` takes `ignoreColor: "#rrggbb"` beside `ignoreWhite`, and leaves out the palette
  colours within about 30 levels of it. Documents saved before have no such setting and ignore white as they
  did. Flat Logo mode leaves out white only.
- Auto Color ("Creates a posterized image from a photo or artwork"): Color mode with the Automatic palette.
- Outline ("Simplifies the image to black outlines"): Black and White with Create: Strokes and no fills.
- The Outline preset's name is translated as a preset's name, not as the Outline view's.

Measured (docs/image-trace-quality.md): Auto Color on flat art is 0.140 px off on average with 4.0 paths (16
Colors: 0.141, 4.2). Outline on the line inputs, the first measure of Create: Strokes: 0.310 px off on average,
1.84 at worst, 81 anchors for 5 lines (Line Art's filled outlines: 0.055, 0.96, 46).
2026-10-13 08:04:32 +07:00
bflatastic 20ec49b2e7 Image Trace: abutting regions share one curve along their edge
Each region's outline was fitted on its own, so the edge between two regions was fitted twice, a little
differently, and left hairline gaps and overlaps.

- An outline is cut at its junctions: the pixel corners where three or more regions meet, where two parts of a
  region touch by a corner only, and where an edge reaches the image's border (each side of the image is a
  neighbour of its own, so the image's corners stay exact). A junction lies where the edges around it say, the
  same for every region around it.
- Each piece between two junctions is the whole edge between two regions. Both get exactly the same points for
  it (shifts are rounded to 1/1024 px so that the two sides agree to the last bit; whether a piece is hard is
  decided by the piece alone) and it is fitted the same way from either side (from its end further left), so it
  is one and the same curve in both paths. A loop without junctions is fitted clockwise from its leftmost point:
  a shape's outline and the hole it leaves in the shape around it are one curve too.
- Stacked layers (Overlapping) share no edges and are cut at the image's border only.

On each preset's own inputs, all sizes and variants (docs/image-trace-quality.md), before -> after:
- Default: gaps 22.2 -> 0.8 px, overlaps 22.4 -> 0.5 px
- 3 Colors: gaps 48.6 -> 0.0, overlaps 29.4 -> 0.0; outlines 0.087 -> 0.104 px off on average
- 6 Colors: gaps 39.0 -> 0.2, overlaps 35.7 -> 0.3; 0.137 -> 0.140 px off, largest 1.09 -> 1.34
- 16 Colors: gaps 34.5 -> 0.2, overlaps 26.4 -> 0.2; 0.133 -> 0.141 px off, largest 1.09 -> 1.31
2026-10-13 06:00:40 +07:00
bflatastic fcd7e3b42d Image Trace: edges to a fraction of a pixel in Black and White, Grayscale and Color
Each crack between an inside and an outside pixel is moved to where the pixels across it say the edge is (the
blend of the two tones in the column of pixels across the crack; a thin line by the centroid and sum of its
tone; hard-edged images are read as staircases), and the outline is fitted as Flat Logo mode fits its own:
corners put back, straight runs as lines, a round outline as a circle, the rest as few curves as Paths allows.
Snap Curves To Lines straightens slightly curved runs and makes arcs. A fit that strays from its outline
gives way to a plainer one, and at last to the outline's own points.

On each preset's own inputs, all sizes and variants (docs/image-trace-quality.md):
- Default: outlines 0.313 -> 0.091 px off on average, largest 1.51 -> 1.02; edge error 17.2 -> 10.1;
  gaps between abutting paths 63.5 -> 22.2 px, overlaps 67.0 -> 22.4 px
- Black and White Logo: 0.270 -> 0.064 px off, kinks 15.3 -> 0.3, anchors 3.78 -> 2.73 times the art's
- Technical Drawing: 0.201 -> 0.086 px off; Line Art: 0.158 -> 0.093
- Worse: anchors on blurred and scanned thin lines (Line Art 25 -> 77 on average), High Fidelity Photo
  (colour error 2.30 -> 2.50, anchors 46,866 -> 81,597, 1 megapixel photo-like image 0.37 -> 1.98 s)
2026-10-13 01:55:17 +07:00
Jax SpenserandClaude Sonnet 5.5 29310175af Image Trace: Flat Logo mode (sub-pixel edges, restored corners, true lines and circles)
A fourth Image Trace mode for flat-colour logos. The existing tracer follows hard pixel
edges, so an outline can only be as good as the pixel grid; here each pixel is read as a
blend of the logo's flat colours, the blend is interpolated smoothly (cubic B-spline), and
every outline is placed where two colours are equally present, to a fraction of a pixel.

Outlines are then cleaned the way a person would:
- corners the blur rounded are put back (line fits either side of a bend, intersected);
- near-straight runs and near-circular arcs become exact lines and arcs (Snap Curves To Lines);
- the rest is fitted with as few cubic Beziers as the tolerance allows (Schneider);
- touching colours overlap by 0.06 px so no hairline gap opens between independent fits;
- shapes are painted biggest first; transparent areas fully enclosed by artwork (letters
  knocked out of a badge, the counters of an "o") are painted white so the logo reads the
  same on any background, or become real holes with Ignore White (each hole belongs to the
  smallest outline containing it);
- an outline whose fit strays more than 1.4 px from the raw contour is fitted plainly.

Colours are found automatically (and completed from pixels no blend of the known colours
explains, so a small accent is not lost) or named with `logoColors: ["#rrggbb", ...]` (white is
always its own class; colours closer than 12 count as one; at most ten). Gradients and photos
are refused with advice to use Color (a flat-colour score of the solid areas, 0.93). A
hard-edged source with no anti-aliasing is softened by under a pixel and fitted with looser
snap tolerances. Images over 1024 px on the long side are averaged down first (further, if
they are busy enough to make the unmixing expensive) and the result is mapped back exactly.
More real outlines than we will fit are refused, not silently truncated.

Also: a "Flat Logo" preset, the mode in the Image Trace panel (Method hidden: it always
stacks), the command docs and MCP prompt, es/fr/it/ru translations for the two new messages
and the mode name, and the ROADMAP.

Never-crash: no unwrap/expect/panic, every size and float is bounded and checked, with
tests for degenerate and extreme input (NaN/infinite parameters, 0x0 and 1x1 images, sparse
outlines, an anchor budget, a 200,000-entry palette) and a 250-run randomised no-panic
property test. The B-spline interpolation follows Unser et al. and Thevenaz et al., and the
curve fitter follows Schneider (Graphics Gems); both are written from the papers.

Measured (local experiment, not in CI): a flat-colour logo's vector original rendered down
to a soft 199x100 px PNG and traced. Mean edge error vs the original at 1600 px wide:
built-in colour presets 2.5 to 3.4 px, Flat Logo 0.78 px (0.48 px from a crisp source);
region overlap 0.88-0.91 vs 0.966. About 0.1 s for a 200 px logo.

Tests: 60 new in the trace crate (unmix, field, contours, geometry, Beziers, corners,
outline fitting, palette, end-to-end on synthetic shapes made in code) and 3 in the engine.
cargo xtask ci passes (fmt, clippy, test, assets, brands, layers, wasm): 4,290 tests.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-09 17:57:04 +11:00