diff --git a/crates/trace/src/fit.rs b/crates/trace/src/fit.rs index c833930f..6abfb5bf 100644 --- a/crates/trace/src/fit.rs +++ b/crates/trace/src/fit.rs @@ -4,7 +4,7 @@ use vectorcraft_geom::{Anchor, AnchorKind, CubicBez, ParamCurve, PathData, Point use vectorcraft_pathops::{SimplifyOptions, simplify_with}; use crate::contour::Loop; -use crate::logo::{Cubic, Stats, Style, all_within, fit_outline, resample_closed, sample_cubics}; +use crate::logo::{Cubic, Stats, Style, all_within, fit_open, fit_outline, resample_closed, resample_open, sample_cubics}; use crate::subpixel::{self, Crack}; #[derive(Clone, Copy, Debug)] @@ -48,27 +48,98 @@ fn rdp(pts: &[Point], a: usize, b: usize, tol: f64, keep: &mut [bool]) { } } -/// Fit one loop of a `w × h` image into a closed Bézier subpath (pixel coordinates): its points -/// are placed to a fraction of a pixel ([`subpixel::outline`], which explains `shift`) and fitted as -/// Flat Logo mode fits its outlines (corners restored, straight runs as lines, the rest as few -/// curves as `style.tol` allows). -pub(crate) fn fit_loop(l: &Loop, w: usize, h: usize, shift: &dyn Fn(Crack) -> f64, style: &Style) -> Option { - let (pts, hard) = subpixel::outline(l, w, h, shift); - let mut style = *style; - if hard { - // No anti-aliasing: the edge is only known to about half a pixel (as in Flat Logo mode). - style.tol *= 2.5; - style.line_tol *= 1.8; - style.circle_tol *= 1.8; - style.sigma = 0.9; +fn reversed(mut segs: Vec) -> Vec { + segs.reverse(); + for c in &mut segs { + c.reverse(); } + segs +} + +fn before(a: Point, b: Point) -> std::cmp::Ordering { + a.x.total_cmp(&b.x).then(a.y.total_cmp(&b.y)) +} + +/// A whole loop fitted. The same loop gives the same curves whichever way it runs and wherever it +/// starts (it is fitted clockwise from its leftmost point): the outline of a shape and the hole it +/// leaves in the shape around it are one curve. +fn fit_closed(pts: &[Point], style: &Style) -> Option> { + let n = pts.len(); + let area2: f64 = (0..n).map(|i| pts[i].x * pts[(i + 1) % n].y - pts[(i + 1) % n].x * pts[i].y).sum(); + let flip = area2 < 0.0; + let mut pts = pts.to_vec(); + if flip { + pts.reverse(); + } + let start = (0..n).min_by(|&i, &j| before(pts[i], pts[j])).unwrap_or(0); + pts.rotate_left(start); let mut stats = Stats::default(); - let mut segs = fit_outline(&pts, &style, &mut stats)?; + let mut segs = fit_outline(&pts, style, &mut stats)?; // A fit that strayed was replaced by a plain one that nothing has checked: one that strays too // (a wild handle on a tiny or ragged loop) gives way to the outline's own points. if stats.reverted > 0 && !all_within(&sample_cubics(&segs, 0.25), &resample_closed(&pts, 0.5).map_or_else(|| pts.clone(), |(p, _)| p), 1.5) { segs = polygon(&pts, style.tol); } + Some(if flip { reversed(segs) } else { segs }) +} + +/// A piece of a loop between two junctions fitted, from its first point to its last. The same +/// piece gives the same curve whichever way it runs (it is fitted from its end further left): the +/// edge two regions share is one curve. +fn fit_piece(pts: &[Point], style: &Style) -> Vec { + let n = pts.len(); + let (Some(&first), Some(&last)) = (pts.first(), pts.last()) else { return vec![] }; + let flip = match before(first, last) { + std::cmp::Ordering::Equal => n > 3 && before(pts[1], pts[n - 2]).is_gt(), + order => order.is_gt(), + }; + let mut pts = pts.to_vec(); + if flip { + pts.reverse(); + } + let mut segs = fit_open(&pts, style, &mut Stats::default()); + // Nothing else checks this fit: one that strays gives way to the piece's own points. + if !all_within(&sample_cubics(&segs, 0.25), &resample_open(&pts, 0.5).map_or_else(|| pts.clone(), |(p, _)| p), 1.5) { + let mut keep = vec![false; n]; + rdp(&pts, 0, n - 1, style.tol, &mut keep); + keep[0] = true; + keep[n - 1] = true; + let kept: Vec = (0..n).filter(|&i| keep[i]).map(|i| pts[i]).collect(); + segs = kept.windows(2).filter(|p| p[0] != p[1]).map(|p| [p[0], p[0], p[1], p[1]]).collect(); + } + if flip { reversed(segs) } else { segs } +} + +/// Fit one loop of a `w × h` image into a closed Bézier subpath (pixel coordinates): its points +/// are placed to a fraction of a pixel ([`subpixel::outline`], which explains `across`) and fitted +/// as Flat Logo mode fits its outlines (corners restored, straight runs as lines, the rest as few +/// curves as `style.tol` allows), piece by piece between its junctions, so that the regions on +/// either side of an edge get the same curve for it. +pub(crate) fn fit_loop( + l: &Loop, + w: usize, + h: usize, + across: &dyn Fn(Crack) -> (f64, u32), + junction_at: &dyn Fn(i32, i32) -> Option, + style: &Style, +) -> Option { + let pieces = subpixel::outline(l, w, h, across, junction_at); + let mut segs: Vec = Vec::new(); + for piece in &pieces { + let mut style = *style; + if piece.hard { + // No anti-aliasing: the edge is only known to about half a pixel (as in Flat Logo mode). + style.tol *= 2.5; + style.line_tol *= 1.8; + style.circle_tol *= 1.8; + style.sigma = 0.9; + } + if piece.closed { + segs = fit_closed(&piece.pts, &style)?; + } else { + segs.extend(fit_piece(&piece.pts, &style)); + } + } let n = segs.len(); // A straight piece has no handles. let straight = |c: &Cubic| seg_dist(c[1], c[0], c[3]) < 1e-6 && seg_dist(c[2], c[0], c[3]) < 1e-6; diff --git a/crates/trace/src/lib.rs b/crates/trace/src/lib.rs index 923f9e2a..b7e82dab 100644 --- a/crates/trace/src/lib.rs +++ b/crates/trace/src/lib.rs @@ -25,6 +25,9 @@ //! is (an anti-aliased or blurred edge pixel is part one tone, part the other), so the outline //! is right to a fraction of a pixel before any fitting; hard-edged images are read as //! staircases instead (see `subpixel`). +//! Outlines are cut at their junctions (where three regions meet, and at the image's border) +//! and each piece between two is fitted on its own, the same way from either side, so that two +//! abutting regions have one and the same curve along the edge they share. //! 5. **Curves**: the outline is fitted as Flat Logo mode fits its own (`logo::fit_outline`): //! corners the pixels rounded are put back, straight runs become lines, a round outline a //! true circle, and the rest as few cubic Béziers as the Paths tolerance allows; Snap Curves To @@ -563,6 +566,46 @@ impl Layers<'_> { fn ignored(&self, label: u16) -> bool { self.params.ignore_white && self.q.palette.get(label as usize).is_some_and(|c| is_white(*c)) } + /// The region across a crack, for cutting outlines at their junctions: the outside pixel's + /// colour. Stacked layers end on many colours at once and share no edge: one neighbour. + fn neighbour(&self, c: Crack) -> u32 { + if self.params.method == Method::Overlapping { + return 0; + } + c.at(1).and_then(|i| self.q.labels.get(i)).map_or(u32::from(TRANSPARENT), |&l| u32::from(l)) + } + /// The junction at pixel corner `(x, y)`, if there is one: where three or four regions + /// meet, or two parts of a region touch by the corner only, or an edge reaches the image's + /// border. It lies at the corner, moved across by what the edges that run up and down from it + /// say, and up or down by what those to its left and right say (the mean, where there are + /// two). It depends on the corner alone, so every region around it gets the same point; on the + /// image's border it stays on the border. + fn junction(&self, x: i32, y: i32) -> Option { + let label = |px: i32, py: i32| Crack::new((px, py), (1, 0), self.w, self.h).at(0).and_then(|i| self.q.labels.get(i).copied()); + // The four pixels around the corner (`None` off the image), and the edges between them. + let around = [label(x - 1, y - 1), label(x, y - 1), label(x, y), label(x - 1, y)]; + let edges = (0..4).filter(|&i| around[i] != around[(i + 1) % 4]).count(); + let apart = |a: usize, b: usize, c: usize, d: usize| around[a] == around[c] && around[b] != around[a] && around[d] != around[a]; + let touching = apart(0, 1, 2, 3) || apart(1, 2, 3, 0); + // (Stacked layers share no edges: they are cut at the image's border only.) + if edges < 3 && !touching || self.params.method == Method::Overlapping { + return None; + } + // The shift of the crack between `a` and the pixel `step` from it, if both are in the + // image and of different regions. + let shift = |a: (i32, i32), step: (i32, i32)| { + let (la, lb) = (label(a.0, a.1)?, label(a.0 + step.0, a.1 + step.1)?); + (la != lb).then(|| self.shift(Crack::new(a, step, self.w, self.h)).clamp(-0.5, 0.5)) + }; + let mean = |a: Option, b: Option| match (a, b) { + (Some(a), Some(b)) => (a + b) / 2.0, + (Some(v), None) | (None, Some(v)) => v, + (None, None) => 0.0, + }; + let dx = mean(shift((x - 1, y - 1), (1, 0)), shift((x - 1, y), (1, 0))); + let dy = mean(shift((x - 1, y - 1), (0, 1)), shift((x, y - 1), (0, 1))); + Some(vectorcraft_geom::Point::new(f64::from(x) + dx, f64::from(y) + dy)) + } /// How far the edge lies from a crack between two pixels, towards the outside one (−0.5 to 0.5). /// /// Each pixel of the column across the crack is read as a blend of the tones on its two sides @@ -690,7 +733,7 @@ impl Layers<'_> { true }; for comp in trace_mask(&mask, w, h) { - let fit = |l: &Loop| fit::fit_loop(l, w, h, &|c| self.shift(c), &self.style); + let fit = |l: &Loop| fit::fit_loop(l, w, h, &|c| (self.shift(c), self.neighbour(c)), &|x, y| self.junction(x, y), &self.style); let Some(outer) = fit(&comp.outer) else { continue }; let mut subs = vec![outer]; for hole in &comp.holes { diff --git a/crates/trace/src/logo/geom.rs b/crates/trace/src/logo/geom.rs index 5b26160a..ca77f276 100644 --- a/crates/trace/src/logo/geom.rs +++ b/crates/trace/src/logo/geom.rs @@ -52,6 +52,41 @@ pub(crate) fn resample_closed(p: &[Point], step: f64) -> Option<(Vec, f64 Some((out, total / m as f64)) } +/// An open polyline resampled at (about) `step` spacing, both ends kept; also returns the exact +/// spacing used. +pub(crate) fn resample_open(p: &[Point], step: f64) -> Option<(Vec, f64)> { + let n = p.len(); + let (first, last) = (*p.first()?, *p.last()?); + if n < 2 || step.is_nan() || step <= 0.0 || !p.iter().all(|&q| finite(q)) { + return None; + } + let mut cum = Vec::with_capacity(n); + cum.push(0.0); + for pair in p.windows(2) { + cum.push(cum.last().copied().unwrap_or(0.0) + pair[0].distance(pair[1])); + } + let total = cum.last().copied().unwrap_or(0.0); + if total.is_nan() || total <= 0.0 { + return None; + } + let m = ((total / step).round() as usize).clamp(1, MAX_POINTS); + let mut out = Vec::with_capacity(m + 1); + out.push(first); + let mut j = 0usize; + for i in 1..m { + let s = total * i as f64 / m as f64; + while cum.get(j + 1).is_some_and(|&c| c < s) { + j += 1; + } + let (c0, c1) = (*cum.get(j)?, *cum.get(j + 1)?); + let t = if c1 > c0 { (s - c0) / (c1 - c0) } else { 0.0 }; + let (a, b) = (*p.get(j)?, *p.get(j + 1)?); + out.push(a + (b - a) * t); + } + out.push(last); + Some((out, total / m as f64)) +} + fn kernel(sigma: f64) -> Vec { let s = sigma.max(0.3); let r = ((3.0 * s).ceil() as i64).max(1); diff --git a/crates/trace/src/logo/mod.rs b/crates/trace/src/logo/mod.rs index d21098e5..336ba262 100644 --- a/crates/trace/src/logo/mod.rs +++ b/crates/trace/src/logo/mod.rs @@ -24,7 +24,7 @@ mod tests; mod testutil; mod unmix; -pub(crate) use geom::{Cubic, all_within, resample_closed, sample_cubics}; -pub(crate) use outline::{Stats, Style, fit_outline}; +pub(crate) use geom::{Cubic, all_within, resample_closed, resample_open, sample_cubics}; +pub(crate) use outline::{Stats, Style, fit_open, fit_outline}; pub(crate) use pipeline::trace_logo; pub(crate) use restore::RestoreParams; diff --git a/crates/trace/src/logo/outline.rs b/crates/trace/src/logo/outline.rs index 016cc807..b85f51bd 100644 --- a/crates/trace/src/logo/outline.rs +++ b/crates/trace/src/logo/outline.rs @@ -1,7 +1,9 @@ //! One outline: smooth, restore corners, snap to lines and arcs, fit Béziers, and verify. use super::bezier::{fit_cubics, tangent}; -use super::geom::{Cubic, all_within, arc_cubics, circle_fit, find_corners, finite, resample_closed, sample_cubics, smooth_closed, smooth_open}; +use super::geom::{ + Cubic, all_within, arc_cubics, circle_fit, find_corners, finite, resample_closed, resample_open, sample_cubics, smooth_closed, smooth_open, +}; use super::restore::{RestoreParams, restore_corners}; use vectorcraft_geom::Point; @@ -95,6 +97,105 @@ fn plain_fit(p: &[Point], tol: f64) -> Vec { fit_cubics(&closed, t, -t, tol) } +/// One run between two corners, added to `segs`: a line or an arc where it is one, else fitted +/// curves. `sg` is the smoothing, in samples. +fn fit_run(run: &[Point], sg: f64, st: &Style, stats: &mut Stats, segs: &mut Vec) { + let (Some(&first), Some(&last)) = (run.first(), run.last()) else { return }; + if run.len() < 4 { + if run.len() >= 2 && first.distance(last) > 1e-9 { + segs.push(line_cubic(first, last)); + } + return; + } + let sm = smooth_open(run, sg); + let (Some(&a), Some(&b)) = (sm.first(), sm.last()) else { return }; + let len = a.distance(b); + if st.snap && len > 1.5 { + let d = b - a; + let nrm = kurbo::Vec2::new(-d.y, d.x) / len; + if sm.iter().all(|q| (*q - a).dot(nrm).abs() < st.line_tol) { + stats.lines += 1; + segs.push(line_cubic(a, b)); + return; + } + } + if st.snap + && st.arcs + && sm.len() > 12 + && len > 1.0 + && let Some(c) = circle_fit(&sm) + && c.resid < st.circle_tol + && c.r > 2.5 + && c.r < 400.0 + && let Some((a0, a1)) = sweep(&sm, c.c) + && (a1 - a0).abs() > 0.35 + { + stats.arcs += 1; + let first = segs.len(); + segs.extend(arc_cubics(c.c, c.r, a0, a1)); + // The fitted circle may miss the corners by up to the snap tolerance: end exactly on them. + if let Some(s) = segs.get_mut(first) { + s[0] = a; + } + if let Some(s) = segs.last_mut() { + s[3] = b; + } + return; + } + segs.extend(fit_cubics(&sm, tangent(&sm, 0, 4, 1), tangent(&sm, sm.len() - 1, 4, -1), st.tol)); +} + +/// The open run `p` as cubic Béziers from its first point to its last, both kept exactly: cut at +/// its corners, each stretch a line, an arc or fitted curves as in a closed outline. (No corner is +/// put back here: a piece of an outline between two junctions ends on pixel corners anyway.) +pub(crate) fn fit_open(p: &[Point], st: &Style, stats: &mut Stats) -> Vec { + let mut segs = Vec::new(); + let (Some(&first), Some(&last)) = (p.first(), p.last()) else { return segs }; + let whole = |segs: &mut Vec| { + if first.distance(last) > 1e-9 { + segs.push(line_cubic(first, last)); + } + }; + let Some((r, step)) = resample_open(p, st.step) else { + whole(&mut segs); + return segs; + }; + let n = r.len(); + let s0 = smooth_open(&r, (0.18 / step).max(1.0)); + let w = ((st.corner_win / step).round() as usize).max(2); + let angle = |i: usize| { + let (Some(&c), Some(&a), Some(&b)) = (s0.get(i), i.checked_sub(w).and_then(|j| s0.get(j)), s0.get(i + w)) else { return 0.0 }; + let (v1, v2) = (c - a, b - c); + v1.cross(v2).atan2(v1.dot(v2)).abs().to_degrees() + }; + let mut cuts = vec![0]; + for i in w..n.saturating_sub(w) { + let here = angle(i); + if here >= st.corner_deg && here >= angle(i - 1) && here > angle(i + 1) && cuts.last().is_none_or(|&l| i - l > w) { + cuts.push(i); + } + } + cuts.push(n - 1); + let sg = st.sigma / step; + for pair in cuts.windows(2) { + let Some(run) = r.get(pair[0]..=pair[1]) else { continue }; + let before = segs.len(); + fit_run(run, sg, st, stats, &mut segs); + // Every stretch must lead on to the next. + if segs.len() == before + && let (Some(&a), Some(&b)) = (run.first(), run.last()) + && a.distance(b) > 1e-9 + { + segs.push(line_cubic(a, b)); + } + } + if !sane(&segs) { + segs.clear(); + whole(&mut segs); + } + segs +} + fn styled_fit(p: &[Point], st: &Style, stats: &mut Stats) -> Option> { let (mut r, step) = resample_closed(p, st.step)?; let sg = st.sigma / step; @@ -147,49 +248,7 @@ fn styled_fit(p: &[Point], st: &Style, stats: &mut Stats) -> Option> let i1 = *corners.get((ci + 1) % corners.len())?; let count = if i1 <= i0 { i1 + n - i0 } else { i1 - i0 } + 1; let run: Vec = (0..count).filter_map(|k| r.get((i0 + k) % n).copied()).collect(); - let (Some(&first), Some(&last)) = (run.first(), run.last()) else { continue }; - if run.len() < 4 { - if run.len() >= 2 && first.distance(last) > 1e-9 { - segs.push(line_cubic(first, last)); - } - continue; - } - let sm = smooth_open(&run, sg); - let (Some(&a), Some(&b)) = (sm.first(), sm.last()) else { continue }; - let len = a.distance(b); - if st.snap && len > 1.5 { - let d = b - a; - let nrm = kurbo::Vec2::new(-d.y, d.x) / len; - if sm.iter().all(|q| (*q - a).dot(nrm).abs() < st.line_tol) { - stats.lines += 1; - segs.push(line_cubic(a, b)); - continue; - } - } - if st.snap - && st.arcs - && sm.len() > 12 - && len > 1.0 - && let Some(c) = circle_fit(&sm) - && c.resid < st.circle_tol - && c.r > 2.5 - && c.r < 400.0 - && let Some((a0, a1)) = sweep(&sm, c.c) - && (a1 - a0).abs() > 0.35 - { - stats.arcs += 1; - let first = segs.len(); - segs.extend(arc_cubics(c.c, c.r, a0, a1)); - // The fitted circle may miss the corners by up to the snap tolerance: end exactly on them. - if let Some(s) = segs.get_mut(first) { - s[0] = a; - } - if let Some(s) = segs.last_mut() { - s[3] = b; - } - continue; - } - segs.extend(fit_cubics(&sm, tangent(&sm, 0, 4, 1), tangent(&sm, sm.len() - 1, 4, -1), st.tol)); + fit_run(&run, sg, st, stats, &mut segs); } (!segs.is_empty()).then_some(segs) } diff --git a/crates/trace/src/subpixel.rs b/crates/trace/src/subpixel.rs index 0b5e4b32..c55c70ab 100644 --- a/crates/trace/src/subpixel.rs +++ b/crates/trace/src/subpixel.rs @@ -40,6 +40,10 @@ pub(crate) struct Crack { } impl Crack { + /// The crack between pixel `inside` and the pixel `step` (one pixel right or down) from it. + pub fn new(inside: (i32, i32), step: (i32, i32), w: usize, h: usize) -> Self { + Self { inside, step, w, h } + } /// The index of the pixel `k` steps out from the inside pixel (0: the inside pixel, 1: the /// outside one, −1: the one behind the inside pixel), if the image has it. pub fn at(&self, k: i32) -> Option { @@ -52,20 +56,58 @@ fn pixel(p: (i32, i32), w: usize, h: usize) -> Option { (x < w && y < h).then(|| y * w + x) } -/// The outline of `l` (a loop of a `w × h` image) as points, and whether its edge is hard. +/// A stretch of an outline with one neighbour along it: its points, and whether its edge is hard. +#[derive(Clone, Debug, PartialEq)] +pub(crate) struct Piece { + pub pts: Vec, + pub hard: bool, + /// The piece is a whole loop without a junction. + pub closed: bool, +} + +/// What lies across a crack on the image's border: one neighbour per side, so that the image's +/// corners are junctions and stay exact. +fn border(dir: (i32, i32)) -> u32 { + u32::MAX + - match dir { + (1, 0) => 0, + (0, 1) => 1, + (-1, 0) => 2, + _ => 3, + } +} + +/// The outline of `l` (a loop of a `w × h` image) as points. /// -/// `shift` says how far (in pixels, −0.5 to 0.5, positive towards the outside pixel) the edge lies -/// from a crack. -pub(crate) fn outline(l: &Loop, w: usize, h: usize, shift: &dyn Fn(Crack) -> f64) -> (Vec, bool) { +/// `across` says, for a crack, how far (in pixels, −0.5 to 0.5, positive towards the outside +/// pixel) the edge lies from it, and which region is on its other side. +/// +/// The outline comes in pieces, cut at its junctions: the pixel corners where the region on the +/// other side changes (three or more regions meet there, or the image's border begins), and +/// those where two parts of a region touch by a corner only (there its outline and its +/// neighbour's part ways without the neighbour changing). `junction_at` says of a pixel corner +/// whether it is a junction of that second kind, when asked without `must`, and where the +/// junction really lies, the same for every region around it. A piece +/// is the whole edge between two regions, and both get exactly the same points for it (a crack +/// gives the same point from either side, shifts are rounded to 1/1024 px so that they agree to +/// the last bit, and whether a piece is hard is decided by the piece alone), so that fitted the +/// same way it is one curve for both. A loop without junctions is one closed piece. +pub(crate) fn outline( + l: &Loop, + w: usize, + h: usize, + across: &dyn Fn(Crack) -> (f64, u32), + junction_at: &dyn Fn(i32, i32) -> Option, +) -> Vec { let v = &l.pts; let n = v.len(); let at = |i: usize| Point::new(f64::from(v[i % n].0), f64::from(v[i % n].1)); - let raw = || (0..n).map(at).collect::>(); if n < 4 { - return (raw(), true); + return vec![Piece { pts: (0..n).map(at).collect(), hard: true, closed: true }]; } let mut edges = Vec::with_capacity(n); - let mut shifts: Vec = Vec::new(); + // Per crack: its shift, the region across it, and the edge it is on. + let (mut shifts, mut others, mut edge_of): (Vec, Vec, Vec) = (vec![], vec![], vec![]); for i in 0..n { let (a, b) = (v[i], v[(i + 1) % n]); let (dx, dy) = (b.0 - a.0, b.1 - a.1); @@ -82,43 +124,95 @@ pub(crate) fn outline(l: &Loop, w: usize, h: usize, shift: &dyn Fn(Crack) -> f64 _ => ((sx, sy - 1), (sx - 1, sy - 1)), }; let crack = Crack { inside, step: (outside.0 - inside.0, outside.1 - inside.1), w, h }; - let s = match crack.at(1) { - Some(_) => shift(crack), + let (s, other) = match crack.at(1) { + Some(_) => across(crack), // The edge of the image is where it is. - _ => 0.0, + _ => (0.0, border(dir)), }; - shifts.push(if s.is_finite() { s.clamp(-0.5, 0.5) } else { 0.0 }); + shifts.push(if s.is_finite() { (s.clamp(-0.5, 0.5) * 1024.0).round() / 1024.0 } else { 0.0 }); + others.push(other); + edge_of.push(i); } } - // A hard edge: nearly every crack moves by the same amount. - let mut sorted = shifts.clone(); - let mid = sorted.len() / 2; - let median = if sorted.is_empty() { 0.0 } else { *sorted.select_nth_unstable_by(mid, f64::total_cmp).1 }; - let hard = shifts.iter().filter(|s| (*s - median).abs() > 0.03).count() * 4 < shifts.len(); + let cracks = shifts.len(); + if cracks == 0 { + return vec![Piece { pts: (0..n).map(at).collect(), hard: true, closed: true }]; + } + // The pixel corner each crack starts at. + let corner_of = |c: usize| { + let (i, e) = (edge_of[c], &edges[edge_of[c]]); + (v[i].0 + e.dir.0 * (c - e.first) as i32, v[i].1 + e.dir.1 * (c - e.first) as i32) + }; + // A junction lies at the start of each crack whose neighbour is not the crack before's, and + // where the callback says one is. + let junctions: Vec> = (0..cracks) + .map(|c| { + let (x, y) = corner_of(c); + let changed = others[c] != others[(c + cracks - 1) % cracks]; + junction_at(x, y).or_else(|| changed.then(|| Point::new(f64::from(x), f64::from(y)))) + }) + .collect(); + let junction = |c: usize| junctions[c].is_some(); + let first = (0..cracks).find(|&c| junction(c)); + // A hard edge: nearly every crack of the piece moves by the same amount. (The middle of the + // two middle shifts, so that the piece is as hard read from its other side, shifts negated.) + let is_hard = |piece: &[f64]| { + let mut sorted = piece.to_vec(); + sorted.sort_by(f64::total_cmp); + let median = (sorted[sorted.len() / 2] + sorted[(sorted.len() - 1) / 2]) / 2.0; + piece.iter().filter(|s| (*s - median).abs() > 0.03).count() * 4 < piece.len() + }; // Which way the loop turns at vertex `i`, and whether edge `i` is a step of a staircase: one // pixel long, turning one way where it starts and the other where it ends. + // (At a junction the loop goes its own way, its neighbour another: a turn there says nothing + // about the edge they share, and counts as none.) let turn = |i: usize| { let (a, b) = (edges[(i + n - 1) % n].dir, edges[i % n].dir); - (a.0 * b.1 - a.1 * b.0).signum() + if junctions[edges[i % n].first].is_some() { 0 } else { (a.0 * b.1 - a.1 * b.0).signum() } }; let step: Vec = (0..n).map(|i| edges[i].len == 1 && turn(i) * turn(i + 1) < 0).collect(); let outward = |d: (i32, i32)| Vec2::new(f64::from(d.1), f64::from(-d.0)); - let shift_of = |e: &Edge, k: usize| shifts.get(e.first + k).copied().unwrap_or(0.0); - let mut out = Vec::with_capacity(if hard { n } else { shifts.len() + n }); - for i in 0..n { - let (before, e) = (&edges[(i + n - 1) % n], &edges[i]); - if !step[i] && !step[(i + n - 1) % n] { - // A true corner: where its two edges, each moved by its own shift, meet. - out.push(at(i) + outward(before.dir) * shift_of(before, before.len.saturating_sub(1)) + outward(e.dir) * shift_of(e, 0)); + let mut pieces: Vec = Vec::new(); + let start = first.unwrap_or(0); + let mut c = 0; + while c < cracks { + // The cracks of one piece: up to the next junction. + let len = (1..cracks - c).find(|&k| junction((start + c + k) % cracks)).unwrap_or(cracks - c); + let own: Vec = (0..len).map(|k| shifts[(start + c + k) % cracks]).collect(); + let hard = is_hard(&own); + let mut pts = Vec::with_capacity(len + 2); + for k in 0..len { + let crack = (start + c + k) % cracks; + let i = edge_of[crack]; + let (e, along_edge) = (&edges[i], crack - edges[i].first); + let corner = at(i) + Vec2::new(f64::from(e.dir.0), f64::from(e.dir.1)) * along_edge as f64; + if k == 0 && first.is_some() { + // The junction itself: the one point every region around it has. + pts.push(junctions[crack].unwrap_or(corner)); + } else if along_edge == 0 && !step[i] && !step[(i + n - 1) % n] { + // A true corner: where its two edges, each moved by its own shift, meet. + let before = &edges[(i + n - 1) % n]; + pts.push(corner + outward(before.dir) * shifts[(crack + cracks - 1) % cracks] + outward(e.dir) * shifts[crack]); + } + if step[i] || !hard { + pts.push(corner + Vec2::new(f64::from(e.dir.0), f64::from(e.dir.1)) * 0.5 + outward(e.dir) * shifts[crack]); + } } - if step[i] || !hard { - let along = Vec2::new(f64::from(e.dir.0), f64::from(e.dir.1)); - out.extend((0..e.len).map(|k| at(i) + along * (k as f64 + 0.5) + outward(e.dir) * shift_of(e, k))); + if first.is_some() { + // It ends on the next junction: the corner the next piece starts on. + let next = (start + c + len) % cracks; + let (x, y) = corner_of(next); + pts.push(junctions[next].unwrap_or(Point::new(f64::from(x), f64::from(y)))); } + pieces.push(Piece { pts, hard, closed: first.is_none() }); + c += len; } - if out.len() < 3 { (raw(), hard) } else { (out, hard) } + if first.is_none() && pieces.first().is_some_and(|p| p.pts.len() < 3) { + return vec![Piece { pts: (0..n).map(at).collect(), hard: true, closed: true }]; + } + pieces } #[cfg(test)] @@ -130,11 +224,27 @@ mod tests { trace_mask(mask, w, h).remove(0).outer } + /// No junctions but where the neighbour changes, and those on the pixel grid. + fn grid(_: i32, _: i32) -> Option { + None + } + + /// The outline with one neighbour all round (the image's border too): its points, and whether + /// it is hard. + fn whole(l: &Loop, w: usize, h: usize, shift: &dyn Fn(Crack) -> f64) -> (Vec, bool) { + let mut pieces = outline(l, w, h, &|c| (shift(c), 0), &grid); + let hard = pieces.iter().all(|p| p.hard); + // Only the image's border makes junctions here: drop each piece's closing point. + let split = pieces.len() > 1; + let pts = pieces.iter_mut().flat_map(|p| p.pts.drain(..p.pts.len() - usize::from(split))).collect(); + (pts, hard) + } + #[test] fn a_hard_rectangle_keeps_its_four_corners() { let (w, h) = (8, 6); let mask: Vec = (0..w * h).map(|i| (2..6).contains(&(i % w)) && (1..5).contains(&(i / w))).collect(); - let (pts, hard) = outline(&loop_of(&mask, w, h), w, h, &|_| 0.0); + let (pts, hard) = whole(&loop_of(&mask, w, h), w, h, &|_| 0.0); assert!(hard); assert_eq!(pts, [(2.0, 1.0), (6.0, 1.0), (6.0, 5.0), (2.0, 5.0)].map(Point::from)); } @@ -144,7 +254,7 @@ mod tests { // Below the line y = x / 4 + 2: treads four pixels long. let (w, h) = (16, 8); let mask: Vec = (0..w * h).map(|i| (i / w) as f64 + 0.5 > (i % w) as f64 / 4.0 + 2.0).collect(); - let (pts, hard) = outline(&loop_of(&mask, w, h), w, h, &|_| 0.0); + let (pts, hard) = whole(&loop_of(&mask, w, h), w, h, &|_| 0.0); assert!(hard); // Every step's middle lies on one line, a quarter of a pixel's rise per pixel. let steps: Vec = pts.iter().copied().filter(|p| p.y.fract() == 0.5 && p.x > 0.0 && p.x < w as f64).collect(); @@ -157,28 +267,66 @@ mod tests { let (w, h) = (6, 4); // The left half is inside; its right edge really lies 0.3 px further right. let mask: Vec = (0..w * h).map(|i| i % w < 3).collect(); - let shift = |c: Crack| if c.at(0).is_some_and(|i| i % w == 2) && c.at(1).is_some_and(|i| i % w == 3) { 0.3 } else { 0.0 }; + // (0.1 px in the lower rows: a shift that is the same all along makes a hard edge.) + let shift = |c: Crack| match (c.at(0), c.at(1)) { + (Some(a), Some(b)) if a % w == 2 && b % w == 3 => { + if a / w < 2 { + 0.3 + } else { + 0.1 + } + } + _ => 0.0, + }; let l = loop_of(&mask, w, h); - let (pts, hard) = outline(&l, w, h, &shift); - assert!(!hard); + let (pts, _) = whole(&l, w, h, &shift); // Each crack comes with the column of pixels across it. - outline(&l, w, h, &|c| { - let (a, b) = (c.at(0).unwrap(), c.at(1).unwrap()); - assert_eq!((c.at(-1), c.at(2)), (Some(a - 1), Some(b + 1))); - assert_eq!((c.at(-3), c.at(4)), (None, None)); - 0.0 - }); - let right: Vec<&Point> = pts.iter().filter(|p| p.x > 2.5).collect(); - // The four cracks' middles and the two corners, all at x = 3.3. - assert_eq!(right.len(), 6); - assert!(right.iter().all(|p| (p.x - 3.3).abs() < 1e-12), "{right:?}"); + outline( + &l, + w, + h, + &|c| { + let (a, b) = (c.at(0).unwrap(), c.at(1).unwrap()); + assert_eq!((c.at(-1), c.at(2)), (Some(a - 1), Some(b + 1))); + assert_eq!((c.at(-3), c.at(4)), (None, None)); + (0.0, 0) + }, + &grid, + ); + // The four cracks' middles, at x = 3.3 (rounded to 1/1024); the edge ends on the image's + // border, at junctions on the pixel grid. + let right: Vec<&Point> = pts.iter().filter(|p| p.x > 3.05).collect(); + assert_eq!(right.len(), 4); + assert!(right.iter().all(|p| (p.x - if p.y < 2.0 { 3.3 } else { 3.1 }).abs() < 1e-3), "{right:?}"); + assert!(pts.contains(&Point::new(3.0, 0.0)) && pts.contains(&Point::new(3.0, 4.0))); } #[test] fn a_shift_that_is_not_a_number_moves_nothing() { let mask = [true, true, false, false, true, true, false, false]; - let (pts, _) = outline(&loop_of(&mask, 4, 2), 4, 2, &|_| f64::NAN); + let (pts, _) = whole(&loop_of(&mask, 4, 2), 4, 2, &|_| f64::NAN); assert_eq!(pts.len(), 4); assert!(pts.iter().all(|p| p.x.is_finite() && p.y.is_finite())); } + + #[test] + fn two_regions_get_the_same_points_for_their_shared_edge() { + // Left and right halves meet along a staircase; each sees the other's shifts negated. + let (w, h) = (12, 10); + let left: Vec = (0..w * h).map(|i| (i % w) as f64 + 0.5 < 4.0 + (i / w) as f64 * 0.4).collect(); + let right: Vec = left.iter().map(|b| !b).collect(); + let wave = |c: Crack| 0.4 * ((c.at(0).unwrap() + c.at(1).unwrap()) as f64).sin(); + let a = outline(&loop_of(&left, w, h), w, h, &|c| (if left[c.at(0).unwrap()] { wave(c) } else { -wave(c) }, 1), &grid); + let b = outline(&loop_of(&right, w, h), w, h, &|c| (if left[c.at(0).unwrap()] { wave(c) } else { -wave(c) }, 2), &grid); + // The piece that is not on the image's border, from either side. + let inner = |pieces: &[Piece]| { + pieces.iter().find(|p| p.pts.iter().any(|q| q.x > 0.0 && q.x < w as f64 && q.y > 0.0 && q.y < h as f64)).unwrap().clone() + }; + let (mut ours, theirs) = (inner(&a), inner(&b)); + ours.pts.reverse(); + assert_eq!(ours, theirs); + assert!(ours.pts.len() > 12); + // Each side of the image is a piece of its own: its corners are exact. + assert!(a.iter().chain(&b).all(|p| p.pts.first().is_some_and(|q| q.x.fract() == 0.0 && q.y.fract() == 0.0))); + } } diff --git a/crates/trace/src/tests.rs b/crates/trace/src/tests.rs index fd7d2bd1..e61a9762 100644 --- a/crates/trace/src/tests.rs +++ b/crates/trace/src/tests.rs @@ -986,3 +986,54 @@ fn stacked_layers_go_by_lightness_and_leave_ignored_white_alone() { assert!(b.x1 <= 20.5 || b.x0 >= 39.5, "a {} layer covers the white stripe: {b:?}", p.color[0]); } } + +/// The cubic pieces of a path: (from, handle, handle, to). +fn pieces_of(p: &vectorcraft_geom::PathData) -> Vec<[Point; 4]> { + p.subpaths + .iter() + .flat_map(|sp| { + (0..sp.segment_count()).map(move |i| { + let c = sp.segment(i); + [c.p0, c.p1, c.p2, c.p3] + }) + }) + .collect() +} + +#[test] +fn abutting_regions_share_one_curve_along_their_edge() { + // A disc of two halves on a field: three colours, two junctions where all three meet. + let color = |x: f64, y: f64| { + if Point::new(x, y).distance(Point::new(50.3, 49.6)) > 35.2 { + [255.0, 255.0, 255.0] + } else if x < 50.3 + 0.2 * (y - 50.0) { + [200.0, 40.0, 50.0] + } else { + [30.0, 90.0, 200.0] + } + }; + let img = Raster::from_fn(100, 100, |x, y| { + let mut sum = [0.0f64; 3]; + for i in 0..16 { + let c = color(f64::from(x) + (f64::from(i % 4) + 0.5) / 4.0, f64::from(y) + (f64::from(i / 4) + 0.5) / 4.0); + for k in 0..3 { + sum[k] += c[k] / 16.0; + } + } + [sum[0].round() as u8, sum[1].round() as u8, sum[2].round() as u8, 255] + }); + let res = trace(&img, &TraceParams { mode: Mode::Color, colors: 3, ..TraceParams::default() }); + assert_eq!(res.paths.len(), 3); + let all: Vec> = res.paths.iter().map(|p| pieces_of(&p.path)).collect(); + // Every curve that is not on the image's border is another path's curve too, run the other way. + let inner = |c: &[Point; 4]| c.iter().all(|p| p.x > 0.5 && p.x < 99.5 && p.y > 0.5 && p.y < 99.5); + let mut shared = 0; + for (i, path) in all.iter().enumerate() { + for c in path.iter().filter(|c| inner(c)) { + let back = [c[3], c[2], c[1], c[0]]; + assert!(all.iter().enumerate().any(|(j, other)| j != i && other.contains(&back)), "path {i} has an edge of its own: {c:?}"); + shared += 1; + } + } + assert!(shared >= 12, "{shared} shared curves"); +} diff --git a/docs/image-trace-quality.md b/docs/image-trace-quality.md index c4c30fa0..4a6faf4d 100644 --- a/docs/image-trace-quality.md +++ b/docs/image-trace-quality.md @@ -1,6 +1,6 @@ # Image Trace quality -> **Last reviewed:** 2026-10-13 · **Last updated:** 2026-10-13 · **Change:** minor (photos: High Fidelity Photo 3,653 paths to 121 with its colour error down from 2.30 to 1.75) +> **Last reviewed:** 2026-10-13 · **Last updated:** 2026-10-13 · **Change:** minor (shared edges: gaps and overlaps between abutting paths from 22 to 50 px down to under 1) What Image Trace (`crates/trace`) makes of images whose right answer is known, measured by a harness and compared with the numbers before each change. Nothing here is a judgement by eye, and nothing is compared @@ -72,25 +72,25 @@ Each preset on the inputs it is meant for, all sizes and variants. | Technical Drawing | polygons, star, letter A, lines | 2.66 | 13.45 | 0.201 | 1.37 | 105.76 | 4.8 | 32 | 2.23 | 100 | 85 | 5.9 | – | – | – | – | 0.1 | 0.0 | | Flat Logo | two touching halves, four-colour badge | 0.43 | 3.53 | 3.106 | 88.50 | 0.78 | 69.9 | 352 | 38.92 | 38 | 80 | 237.0 | 0.0 | 0 | 13.8 | – | 59.1 | 0.2 | -### Now (sub-pixel edges, the palette, photo smoothing) +### Now (sub-pixel edges, the palette, photo smoothing, shared edges) | preset | inputs | ΔE | edge ΔE | off mean | off max | missed max | paths | anchors | × art | lines % | corners % | kinks | odd colours | odd px | gap px | overlap px | specks | outside px | |:--|:--|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:| -| Default | circle, ellipses, badge with a hole, letter D, polygons, star, letter A | 2.60 | 10.12 | 0.091 | 1.02 | 2.17 | 1.9 | 18 | 1.81 | 29 | 68 | 0.4 | – | – | 22.2 | 22.4 | 0.0 | 0.0 | -| High Fidelity Photo | gradient, photo-like | 1.75 | 1.98 | – | – | – | 120.7 | 9818 | – | 43 | – | – | – | – | 0.0 | – | 10.3 | 0.1 | -| Low Fidelity Photo | gradient, photo-like | 2.45 | 2.69 | – | – | – | 37.1 | 2132 | – | 44 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | -| 3 Colors | two touching halves | 0.43 | 4.32 | 0.087 | 0.74 | 0.56 | 2.0 | 9 | 1.57 | 39 | 100 | 0.0 | 0.0 | 0 | 48.6 | 29.4 | 0.0 | 0.0 | -| 6 Colors | two touching halves, four-colour badge | 0.56 | 5.01 | 0.137 | 1.09 | 1.14 | 4.0 | 50 | 3.15 | 40 | 88 | 3.6 | 0.0 | 0 | 39.0 | 35.7 | 0.0 | 0.0 | -| 16 Colors | two touching halves, four-colour badge | 0.55 | 4.89 | 0.133 | 1.09 | 1.15 | 4.2 | 66 | 3.97 | 41 | 88 | 4.4 | 0.0 | 0 | 34.5 | 26.4 | 0.0 | 0.0 | -| Shades of Gray | gradient, photo-like | 9.26 | 9.06 | – | – | – | 16.5 | 879 | – | 53 | – | – | – | – | 0.0 | – | 0.4 | 0.8 | -| Black and White Logo | circle, ellipses, badge with a hole, letter D, polygons, star, letter A | 2.58 | 9.39 | 0.064 | 1.00 | 2.18 | 1.4 | 27 | 2.73 | 40 | 67 | 0.3 | – | – | – | – | 0.0 | 0.0 | -| Sketched Art | circle, ellipses, badge with a hole, letter D, lines | 2.71 | 12.11 | 0.195 | 1.00 | 105.54 | 1.8 | 17 | 1.49 | 16 | 86 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Silhouettes | circle, ellipses, badge with a hole, letter D | 2.98 | 19.28 | 0.532 | 2.24 | 2.24 | 1.2 | 14 | 1.65 | 12 | 79 | 0.1 | – | – | – | – | 0.0 | 0.0 | -| Line Art | lines | 2.65 | 9.87 | 0.093 | 0.89 | 105.71 | 5.4 | 77 | 3.86 | 37 | – | – | – | – | – | – | 0.1 | 0.0 | -| Technical Drawing | polygons, star, letter A, lines | 2.53 | 9.47 | 0.086 | 0.99 | 105.85 | 4.8 | 57 | 3.73 | 69 | 74 | 0.7 | – | – | – | – | 0.3 | 0.0 | +| Default | circle, ellipses, badge with a hole, letter D, polygons, star, letter A | 2.60 | 10.04 | 0.092 | 1.02 | 2.17 | 1.9 | 18 | 1.78 | 29 | 68 | 0.4 | – | – | 0.8 | 0.5 | 0.0 | 0.0 | +| High Fidelity Photo | gradient, photo-like | 1.75 | 1.97 | – | – | – | 120.7 | 10001 | – | 38 | – | – | – | – | 0.0 | – | 10.3 | 0.0 | +| Low Fidelity Photo | gradient, photo-like | 2.45 | 2.69 | – | – | – | 37.1 | 2118 | – | 41 | – | – | – | – | 0.0 | – | 0.0 | 0.0 | +| 3 Colors | two touching halves | 0.42 | 3.98 | 0.104 | 0.91 | 0.91 | 2.0 | 11 | 1.81 | 39 | 100 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 6 Colors | two touching halves, four-colour badge | 0.55 | 4.98 | 0.140 | 1.34 | 1.19 | 4.0 | 50 | 3.13 | 38 | 86 | 5.2 | 0.0 | 0 | 0.2 | 0.3 | 0.0 | 0.0 | +| 16 Colors | two touching halves, four-colour badge | 0.55 | 4.90 | 0.141 | 1.31 | 1.19 | 4.2 | 62 | 3.79 | 39 | 86 | 6.4 | 0.0 | 0 | 0.2 | 0.2 | 0.0 | 0.0 | +| Shades of Gray | gradient, photo-like | 9.26 | 9.06 | – | – | – | 16.5 | 695 | – | 51 | – | – | – | – | 0.0 | – | 0.5 | 0.0 | +| Black and White Logo | circle, ellipses, badge with a hole, letter D, polygons, star, letter A | 2.58 | 9.37 | 0.063 | 1.02 | 2.17 | 1.4 | 27 | 2.69 | 39 | 68 | 0.2 | – | – | – | – | 0.0 | 0.0 | +| Sketched Art | circle, ellipses, badge with a hole, letter D, lines | 2.71 | 12.12 | 0.197 | 1.00 | 105.53 | 1.8 | 17 | 1.48 | 15 | 86 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Silhouettes | circle, ellipses, badge with a hole, letter D | 2.98 | 19.22 | 0.523 | 2.23 | 2.21 | 1.2 | 14 | 1.64 | 11 | 75 | 0.2 | – | – | – | – | 0.0 | 0.0 | +| Line Art | lines | 2.65 | 9.88 | 0.093 | 0.91 | 105.75 | 5.4 | 78 | 3.92 | 36 | – | – | – | – | – | – | 0.1 | 0.0 | +| Technical Drawing | polygons, star, letter A, lines | 2.55 | 9.72 | 0.092 | 1.06 | 105.75 | 4.8 | 56 | 3.67 | 71 | 74 | 0.7 | – | – | – | – | 1.3 | 0.0 | | Flat Logo | two touching halves, four-colour badge | 0.43 | 3.53 | 3.106 | 88.50 | 0.78 | 69.9 | 352 | 38.92 | 38 | 80 | 237.0 | 0.0 | 0 | 13.8 | – | 59.1 | 0.2 | -The sections below are the numbers now (sub-pixel edges, the palette, photo smoothing). +The sections below are the numbers now (sub-pixel edges, the palette, photo smoothing, shared edges). ## 1. Each preset on the inputs it is meant for @@ -98,84 +98,84 @@ All sizes and variants (clean, aliased, blurred, noisy, scanned) of those inputs | preset | inputs | ΔE | edge ΔE | off mean | off max | missed max | paths | anchors | × art | lines % | corners % | kinks | odd colours | odd px | gap px | overlap px | specks | outside px | |:--|:--|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:| -| Default | circle, ellipses, badge with a hole, letter D, polygons, star, letter A | 2.60 | 10.12 | 0.091 | 1.02 | 2.17 | 1.9 | 18 | 1.81 | 29 | 68 | 0.4 | – | – | 22.2 | 22.4 | 0.0 | 0.0 | -| High Fidelity Photo | gradient, photo-like | 1.75 | 1.98 | – | – | – | 120.7 | 9818 | – | 43 | – | – | – | – | 0.0 | – | 10.3 | 0.1 | -| Low Fidelity Photo | gradient, photo-like | 2.45 | 2.69 | – | – | – | 37.1 | 2132 | – | 44 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | -| 3 Colors | two touching halves | 0.43 | 4.32 | 0.087 | 0.74 | 0.56 | 2.0 | 9 | 1.57 | 39 | 100 | 0.0 | 0.0 | 0 | 48.6 | 29.4 | 0.0 | 0.0 | -| 6 Colors | two touching halves, four-colour badge | 0.56 | 5.01 | 0.137 | 1.09 | 1.14 | 4.0 | 50 | 3.15 | 40 | 88 | 3.6 | 0.0 | 0 | 39.0 | 35.7 | 0.0 | 0.0 | -| 16 Colors | two touching halves, four-colour badge | 0.55 | 4.89 | 0.133 | 1.09 | 1.15 | 4.2 | 66 | 3.97 | 41 | 88 | 4.4 | 0.0 | 0 | 34.5 | 26.4 | 0.0 | 0.0 | -| Shades of Gray | gradient, photo-like | 9.26 | 9.06 | – | – | – | 16.5 | 879 | – | 53 | – | – | – | – | 0.0 | – | 0.4 | 0.8 | -| Black and White Logo | circle, ellipses, badge with a hole, letter D, polygons, star, letter A | 2.58 | 9.39 | 0.064 | 1.00 | 2.18 | 1.4 | 27 | 2.73 | 40 | 67 | 0.3 | – | – | – | – | 0.0 | 0.0 | -| Sketched Art | circle, ellipses, badge with a hole, letter D, lines | 2.71 | 12.11 | 0.195 | 1.00 | 105.54 | 1.8 | 17 | 1.49 | 16 | 86 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Silhouettes | circle, ellipses, badge with a hole, letter D | 2.98 | 19.28 | 0.532 | 2.24 | 2.24 | 1.2 | 14 | 1.65 | 12 | 79 | 0.1 | – | – | – | – | 0.0 | 0.0 | -| Line Art | lines | 2.65 | 9.87 | 0.093 | 0.89 | 105.71 | 5.4 | 77 | 3.86 | 37 | – | – | – | – | – | – | 0.1 | 0.0 | -| Technical Drawing | polygons, star, letter A, lines | 2.53 | 9.47 | 0.086 | 0.99 | 105.85 | 4.8 | 57 | 3.73 | 69 | 74 | 0.7 | – | – | – | – | 0.3 | 0.0 | +| Default | circle, ellipses, badge with a hole, letter D, polygons, star, letter A | 2.60 | 10.04 | 0.092 | 1.02 | 2.17 | 1.9 | 18 | 1.78 | 29 | 68 | 0.4 | – | – | 0.8 | 0.5 | 0.0 | 0.0 | +| High Fidelity Photo | gradient, photo-like | 1.75 | 1.97 | – | – | – | 120.7 | 10001 | – | 38 | – | – | – | – | 0.0 | – | 10.3 | 0.0 | +| Low Fidelity Photo | gradient, photo-like | 2.45 | 2.69 | – | – | – | 37.1 | 2118 | – | 41 | – | – | – | – | 0.0 | – | 0.0 | 0.0 | +| 3 Colors | two touching halves | 0.42 | 3.98 | 0.104 | 0.91 | 0.91 | 2.0 | 11 | 1.81 | 39 | 100 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 6 Colors | two touching halves, four-colour badge | 0.55 | 4.98 | 0.140 | 1.34 | 1.19 | 4.0 | 50 | 3.13 | 38 | 86 | 5.2 | 0.0 | 0 | 0.2 | 0.3 | 0.0 | 0.0 | +| 16 Colors | two touching halves, four-colour badge | 0.55 | 4.90 | 0.141 | 1.31 | 1.19 | 4.2 | 62 | 3.79 | 39 | 86 | 6.4 | 0.0 | 0 | 0.2 | 0.2 | 0.0 | 0.0 | +| Shades of Gray | gradient, photo-like | 9.26 | 9.06 | – | – | – | 16.5 | 695 | – | 51 | – | – | – | – | 0.0 | – | 0.5 | 0.0 | +| Black and White Logo | circle, ellipses, badge with a hole, letter D, polygons, star, letter A | 2.58 | 9.37 | 0.063 | 1.02 | 2.17 | 1.4 | 27 | 2.69 | 39 | 68 | 0.2 | – | – | – | – | 0.0 | 0.0 | +| Sketched Art | circle, ellipses, badge with a hole, letter D, lines | 2.71 | 12.12 | 0.197 | 1.00 | 105.53 | 1.8 | 17 | 1.48 | 15 | 86 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Silhouettes | circle, ellipses, badge with a hole, letter D | 2.98 | 19.22 | 0.523 | 2.23 | 2.21 | 1.2 | 14 | 1.64 | 11 | 75 | 0.2 | – | – | – | – | 0.0 | 0.0 | +| Line Art | lines | 2.65 | 9.88 | 0.093 | 0.91 | 105.75 | 5.4 | 78 | 3.92 | 36 | – | – | – | – | – | – | 0.1 | 0.0 | +| Technical Drawing | polygons, star, letter A, lines | 2.55 | 9.72 | 0.092 | 1.06 | 105.75 | 4.8 | 56 | 3.67 | 71 | 74 | 0.7 | – | – | – | – | 1.3 | 0.0 | | Flat Logo | two touching halves, four-colour badge | 0.43 | 3.53 | 3.106 | 88.50 | 0.78 | 69.9 | 352 | 38.92 | 38 | 80 | 237.0 | 0.0 | 0 | 13.8 | – | 59.1 | 0.2 | ## 2. Each preset on each kind of input (clean, three sizes) | preset | inputs | ΔE | edge ΔE | off mean | off max | missed max | paths | anchors | × art | lines % | corners % | kinks | odd colours | odd px | gap px | overlap px | specks | outside px | |:--|:--|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:| -| Default | curved shapes | 0.08 | 3.24 | 0.057 | 0.51 | 0.59 | 1.8 | 16 | 1.72 | 15 | 83 | 0.0 | – | – | 22.7 | 21.1 | 0.0 | 0.0 | -| Default | polygons | 0.05 | 2.11 | 0.036 | 0.46 | 1.23 | 2.0 | 14 | 1.24 | 89 | 90 | 0.0 | – | – | 3.1 | 3.3 | 0.0 | 0.0 | -| Default | thin lines | 0.56 | 4.77 | 0.059 | 0.48 | 105.57 | 3.3 | 22 | 1.12 | 42 | – | – | – | – | 49.1 | 34.0 | 0.0 | 0.0 | -| Default | flat colour art | 19.95 | 18.92 | 0.197 | 0.64 | 179.52 | 1.5 | 22 | 1.32 | 15 | 0 | 0.0 | – | – | 24.3 | 23.0 | 0.0 | 0.0 | -| Default | gradient, photo | 39.13 | 38.78 | – | – | – | 3.2 | 698 | – | 57 | – | – | – | – | 31.2 | 40.7 | 0.0 | 0.3 | -| High Fidelity Photo | curved shapes | 0.04 | 1.74 | 0.026 | 0.16 | 0.16 | 1.2 | 20 | 2.17 | 21 | 100 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | -| High Fidelity Photo | polygons | 0.05 | 1.92 | 0.031 | 0.51 | 1.34 | 1.7 | 17 | 1.50 | 87 | 88 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | -| High Fidelity Photo | thin lines | 0.34 | 6.00 | 0.076 | 0.85 | 4.31 | 40.3 | 333 | 16.67 | 37 | – | – | 27.3 | 4489 | 0.0 | – | 19.0 | 0.0 | -| High Fidelity Photo | flat colour art | 0.14 | 4.17 | 0.028 | 0.20 | 0.20 | 3.5 | 71 | 4.44 | 35 | 100 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | -| High Fidelity Photo | gradient, photo | 1.80 | 2.05 | – | – | – | 134.7 | 11186 | – | 43 | – | – | – | – | 0.0 | – | 7.7 | 0.1 | -| Low Fidelity Photo | curved shapes | 0.06 | 2.65 | 0.045 | 0.27 | 0.27 | 1.2 | 14 | 1.53 | 19 | 100 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | -| Low Fidelity Photo | polygons | 0.06 | 2.25 | 0.037 | 0.51 | 1.34 | 1.7 | 14 | 1.25 | 86 | 88 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | -| Low Fidelity Photo | thin lines | 0.51 | 5.73 | 0.081 | 0.86 | 45.38 | 7.0 | 56 | 2.80 | 47 | – | – | 4.0 | 3974 | 0.0 | – | 0.0 | 0.0 | -| Low Fidelity Photo | flat colour art | 0.15 | 4.33 | 0.046 | 0.27 | 0.27 | 3.5 | 55 | 3.38 | 32 | 100 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | -| Low Fidelity Photo | gradient, photo | 2.53 | 2.80 | – | – | – | 42.7 | 2289 | – | 43 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | -| 3 Colors | curved shapes | 0.06 | 2.65 | 0.046 | 0.33 | 0.24 | 1.8 | 16 | 1.77 | 16 | 100 | 0.0 | 0.0 | 0 | 18.7 | 15.2 | 0.0 | 0.0 | -| 3 Colors | polygons | 0.06 | 2.25 | 0.037 | 0.51 | 1.34 | 2.0 | 15 | 1.35 | 86 | 88 | 0.0 | 0.0 | 0 | 5.1 | 4.7 | 0.0 | 0.0 | -| 3 Colors | thin lines | 0.44 | 4.40 | 0.107 | 0.90 | 45.38 | 5.0 | 44 | 2.22 | 49 | – | – | 2.0 | 290 | 23.8 | 27.4 | 0.0 | 0.0 | -| 3 Colors | flat colour art | 1.32 | 3.85 | 0.113 | 0.90 | 60.22 | 2.5 | 24 | 1.77 | 46 | 100 | 0.0 | 1.0 | 9919 | 30.3 | 31.0 | 0.0 | 0.0 | -| 3 Colors | gradient, photo | 7.49 | 7.60 | – | – | – | 5.7 | 532 | – | 48 | – | – | – | – | 25.5 | 26.9 | 0.0 | 0.2 | -| 6 Colors | curved shapes | 0.06 | 2.38 | 0.042 | 0.28 | 0.24 | 1.8 | 17 | 1.86 | 17 | 100 | 0.0 | 0.0 | 0 | 17.9 | 14.3 | 0.0 | 0.0 | -| 6 Colors | polygons | 0.05 | 2.07 | 0.034 | 0.51 | 1.34 | 2.0 | 16 | 1.42 | 86 | 88 | 0.0 | 0.0 | 0 | 3.9 | 3.9 | 0.0 | 0.0 | -| 6 Colors | thin lines | 0.50 | 4.54 | 0.096 | 0.86 | 45.38 | 4.0 | 32 | 1.60 | 53 | – | – | 1.7 | 398 | 18.5 | 22.8 | 0.0 | 0.0 | -| 6 Colors | flat colour art | 0.12 | 2.66 | 0.044 | 0.25 | 0.20 | 3.0 | 28 | 2.00 | 43 | 100 | 0.0 | 0.0 | 0 | 21.9 | 21.2 | 0.0 | 0.0 | -| 6 Colors | gradient, photo | 5.01 | 5.30 | – | – | – | 13.0 | 833 | – | 36 | – | – | – | – | 42.6 | 37.0 | 0.0 | 0.2 | -| 16 Colors | curved shapes | 0.05 | 2.26 | 0.038 | 0.26 | 0.23 | 1.8 | 18 | 1.93 | 17 | 100 | 0.0 | 0.0 | 0 | 14.9 | 12.5 | 0.0 | 0.0 | -| 16 Colors | polygons | 0.05 | 2.02 | 0.034 | 0.51 | 1.34 | 2.0 | 16 | 1.44 | 86 | 88 | 0.0 | 0.0 | 0 | 3.3 | 4.2 | 0.0 | 0.0 | -| 16 Colors | thin lines | 0.41 | 3.87 | 0.103 | 0.86 | 23.65 | 8.7 | 50 | 2.52 | 51 | – | – | 5.7 | 305 | 18.4 | 25.4 | 0.0 | 0.0 | -| 16 Colors | flat colour art | 0.12 | 2.53 | 0.041 | 0.24 | 0.20 | 3.0 | 28 | 2.07 | 44 | 100 | 0.0 | 0.0 | 0 | 19.8 | 19.5 | 0.0 | 0.0 | -| 16 Colors | gradient, photo | 3.02 | 3.33 | – | – | – | 47.2 | 2154 | – | 29 | – | – | – | – | 89.7 | 80.2 | 0.2 | 0.2 | -| Shades of Gray | curved shapes | 0.06 | 2.72 | 0.046 | 0.48 | 0.65 | 1.2 | 14 | 1.56 | 18 | 92 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | -| Shades of Gray | polygons | 0.05 | 1.97 | 0.033 | 0.42 | 1.26 | 1.7 | 14 | 1.21 | 89 | 91 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | -| Shades of Gray | thin lines | 0.56 | 6.69 | 0.078 | 0.86 | 45.38 | 10.3 | 71 | 3.57 | 49 | – | – | 8.0 | 4283 | 0.0 | – | 0.0 | 0.0 | -| Shades of Gray | flat colour art | 7.33 | 11.25 | 0.264 | 1.47 | 179.38 | 4.7 | 214 | 19.86 | 24 | 50 | 0.3 | 3.7 | 173356 | 0.0 | – | 0.0 | 0.0 | -| Shades of Gray | gradient, photo | 9.71 | 9.55 | – | – | – | 18.2 | 955 | – | 53 | – | – | – | – | 0.0 | – | 0.5 | 0.8 | -| Black and White Logo | curved shapes | 0.04 | 1.52 | 0.024 | 0.50 | 0.60 | 1.2 | 21 | 2.25 | 21 | 75 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Black and White Logo | polygons | 0.04 | 1.83 | 0.030 | 0.45 | 1.23 | 1.7 | 15 | 1.34 | 89 | 90 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Black and White Logo | thin lines | 0.50 | 4.22 | 0.065 | 0.50 | 77.21 | 10.3 | 66 | 3.30 | 65 | – | – | – | – | – | – | 0.0 | 0.0 | -| Black and White Logo | flat colour art | 19.94 | 18.72 | 0.192 | 0.31 | 179.52 | 1.0 | 19 | 1.18 | 24 | 0 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Black and White Logo | gradient, photo | 39.11 | 38.71 | – | – | – | 9.0 | 676 | – | 72 | – | – | – | – | – | – | 0.0 | 0.0 | -| Sketched Art | curved shapes | 0.13 | 5.54 | 0.107 | 0.41 | 0.41 | 1.2 | 13 | 1.43 | 17 | 100 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Sketched Art | polygons | 0.13 | 5.00 | 0.092 | 0.51 | 1.07 | 1.7 | 14 | 1.24 | 82 | 86 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Sketched Art | thin lines | 0.38 | 4.99 | 0.102 | 0.80 | 52.57 | 4.3 | 37 | 1.87 | 35 | – | – | – | – | – | – | 0.0 | 0.0 | -| Sketched Art | flat colour art | 20.32 | 20.95 | 0.175 | 0.89 | 179.64 | 1.5 | 22 | 1.34 | 18 | 0 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Sketched Art | gradient, photo | 45.53 | 45.37 | – | – | – | 1.0 | 251 | – | 47 | – | – | – | – | – | – | 0.0 | 0.3 | -| Silhouettes | curved shapes | 0.34 | 14.15 | 0.274 | 0.66 | 0.66 | 1.2 | 12 | 1.36 | 17 | 100 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Silhouettes | polygons | 0.35 | 14.03 | 0.263 | 0.67 | 0.70 | 1.7 | 14 | 1.26 | 76 | 85 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Silhouettes | thin lines | 1.05 | 16.01 | 0.308 | 1.09 | 18.10 | 5.0 | 42 | 2.08 | 40 | – | – | – | – | – | – | 0.0 | 0.0 | -| Silhouettes | flat colour art | 23.86 | 34.06 | 0.226 | 0.77 | 188.38 | 1.0 | 10 | 0.76 | 26 | 0 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Silhouettes | gradient, photo | 61.56 | 61.35 | – | – | – | 0.2 | 2 | – | 47 | – | – | – | – | – | – | 0.0 | 0.6 | -| Line Art | curved shapes | 0.05 | 1.93 | 0.033 | 0.53 | 0.63 | 1.2 | 17 | 1.86 | 19 | 75 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Line Art | polygons | 0.05 | 1.87 | 0.031 | 0.46 | 1.23 | 1.7 | 14 | 1.27 | 89 | 90 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Line Art | thin lines | 0.54 | 4.38 | 0.049 | 0.47 | 105.71 | 3.3 | 33 | 1.67 | 42 | – | – | – | – | – | – | 0.0 | 0.0 | -| Line Art | flat colour art | 19.94 | 18.69 | 0.192 | 0.49 | 179.52 | 1.0 | 46 | 2.55 | 23 | 0 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Line Art | gradient, photo | 39.11 | 38.71 | – | – | – | 7.7 | 490 | – | 59 | – | – | – | – | – | – | 0.0 | 0.1 | -| Technical Drawing | curved shapes | 0.04 | 1.52 | 0.024 | 0.50 | 0.60 | 1.2 | 21 | 2.25 | 21 | 75 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Technical Drawing | polygons | 0.04 | 1.83 | 0.030 | 0.45 | 1.23 | 1.7 | 15 | 1.34 | 89 | 90 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Technical Drawing | thin lines | 0.39 | 3.88 | 0.075 | 0.50 | 55.75 | 15.3 | 81 | 4.05 | 76 | – | – | – | – | – | – | 0.3 | 0.0 | -| Technical Drawing | flat colour art | 19.94 | 18.72 | 0.192 | 0.31 | 179.52 | 1.0 | 19 | 1.18 | 24 | 0 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Technical Drawing | gradient, photo | 39.08 | 38.69 | – | – | – | 20.0 | 964 | – | 79 | – | – | – | – | – | – | 2.0 | 0.1 | +| Default | curved shapes | 0.09 | 3.51 | 0.062 | 0.64 | 0.78 | 1.8 | 15 | 1.64 | 13 | 83 | 0.0 | – | – | 0.0 | 0.0 | 0.0 | 0.0 | +| Default | polygons | 0.05 | 2.13 | 0.036 | 0.44 | 1.24 | 2.0 | 14 | 1.26 | 89 | 90 | 0.0 | – | – | 0.0 | 0.0 | 0.0 | 0.0 | +| Default | thin lines | 0.56 | 4.77 | 0.061 | 0.47 | 105.57 | 3.3 | 24 | 1.18 | 43 | – | – | – | – | 0.0 | 0.0 | 0.0 | 0.0 | +| Default | flat colour art | 19.95 | 19.00 | 0.199 | 0.53 | 179.52 | 1.5 | 19 | 1.18 | 14 | 0 | 0.0 | – | – | 0.0 | 0.0 | 0.0 | 0.0 | +| Default | gradient, photo | 39.14 | 38.78 | – | – | – | 3.2 | 593 | – | 55 | – | – | – | – | 18.6 | 30.6 | 0.0 | 0.0 | +| High Fidelity Photo | curved shapes | 0.04 | 1.66 | 0.026 | 0.18 | 0.20 | 1.2 | 19 | 2.12 | 20 | 100 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | +| High Fidelity Photo | polygons | 0.05 | 1.88 | 0.031 | 0.51 | 1.34 | 1.7 | 16 | 1.43 | 88 | 89 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | +| High Fidelity Photo | thin lines | 0.34 | 5.96 | 0.075 | 0.85 | 4.31 | 40.3 | 339 | 16.93 | 37 | – | – | 27.3 | 4490 | 0.0 | – | 19.0 | 0.0 | +| High Fidelity Photo | flat colour art | 0.14 | 4.16 | 0.030 | 0.20 | 0.20 | 3.5 | 73 | 4.62 | 35 | 100 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | +| High Fidelity Photo | gradient, photo | 1.80 | 2.04 | – | – | – | 134.7 | 11321 | – | 39 | – | – | – | – | 0.0 | – | 7.3 | 0.0 | +| Low Fidelity Photo | curved shapes | 0.06 | 2.65 | 0.047 | 0.31 | 0.31 | 1.2 | 13 | 1.47 | 17 | 100 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | +| Low Fidelity Photo | polygons | 0.05 | 2.15 | 0.036 | 0.51 | 1.34 | 1.7 | 14 | 1.22 | 88 | 89 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | +| Low Fidelity Photo | thin lines | 0.51 | 5.69 | 0.083 | 0.86 | 45.41 | 7.0 | 56 | 2.80 | 47 | – | – | 4.0 | 3966 | 0.0 | – | 0.0 | 0.0 | +| Low Fidelity Photo | flat colour art | 0.15 | 4.29 | 0.045 | 0.28 | 0.28 | 3.5 | 54 | 3.38 | 31 | 100 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | +| Low Fidelity Photo | gradient, photo | 2.53 | 2.80 | – | – | – | 42.7 | 2282 | – | 41 | – | – | – | – | 0.0 | – | 0.0 | 0.0 | +| 3 Colors | curved shapes | 0.06 | 2.65 | 0.047 | 0.31 | 0.31 | 1.8 | 16 | 1.70 | 15 | 100 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 3 Colors | polygons | 0.05 | 2.15 | 0.036 | 0.51 | 1.34 | 2.0 | 15 | 1.32 | 88 | 89 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 3 Colors | thin lines | 0.45 | 4.38 | 0.113 | 0.90 | 45.41 | 5.0 | 44 | 2.18 | 50 | – | – | 2.0 | 290 | 0.0 | 0.0 | 0.0 | 0.0 | +| 3 Colors | flat colour art | 1.31 | 3.61 | 0.125 | 0.90 | 60.25 | 2.5 | 25 | 1.86 | 45 | 100 | 0.0 | 1.0 | 9914 | 0.0 | 0.0 | 0.0 | 0.0 | +| 3 Colors | gradient, photo | 7.49 | 7.60 | – | – | – | 5.7 | 530 | – | 47 | – | – | – | – | 6.3 | 7.4 | 0.0 | 0.0 | +| 6 Colors | curved shapes | 0.06 | 2.45 | 0.043 | 0.27 | 0.28 | 1.8 | 17 | 1.78 | 15 | 100 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 6 Colors | polygons | 0.05 | 2.08 | 0.035 | 0.51 | 1.34 | 2.0 | 15 | 1.33 | 88 | 89 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 6 Colors | thin lines | 0.50 | 4.49 | 0.102 | 0.86 | 45.41 | 4.0 | 33 | 1.65 | 53 | – | – | 1.7 | 396 | 0.0 | 0.0 | 0.0 | 0.0 | +| 6 Colors | flat colour art | 0.12 | 2.70 | 0.057 | 0.31 | 0.30 | 3.0 | 28 | 2.00 | 43 | 100 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 6 Colors | gradient, photo | 5.00 | 5.28 | – | – | – | 13.0 | 832 | – | 36 | – | – | – | – | 6.1 | 8.2 | 0.0 | 0.0 | +| 16 Colors | curved shapes | 0.05 | 2.21 | 0.038 | 0.24 | 0.25 | 1.8 | 17 | 1.85 | 16 | 100 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 16 Colors | polygons | 0.05 | 1.97 | 0.032 | 0.51 | 1.34 | 2.0 | 16 | 1.39 | 88 | 89 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 16 Colors | thin lines | 0.41 | 3.77 | 0.110 | 0.86 | 23.65 | 8.7 | 50 | 2.52 | 52 | – | – | 5.7 | 305 | 0.0 | 0.0 | 0.0 | 0.0 | +| 16 Colors | flat colour art | 0.12 | 2.52 | 0.052 | 0.31 | 0.30 | 3.0 | 28 | 2.11 | 43 | 100 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 16 Colors | gradient, photo | 3.00 | 3.30 | – | – | – | 47.2 | 2132 | – | 27 | – | – | – | – | 12.3 | 18.0 | 0.0 | 0.0 | +| Shades of Gray | curved shapes | 0.06 | 2.67 | 0.047 | 0.31 | 0.31 | 1.2 | 14 | 1.49 | 17 | 100 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | +| Shades of Gray | polygons | 0.05 | 2.08 | 0.035 | 0.47 | 1.25 | 1.7 | 14 | 1.22 | 88 | 90 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | +| Shades of Gray | thin lines | 0.55 | 6.55 | 0.083 | 0.86 | 45.40 | 10.3 | 73 | 3.67 | 50 | – | – | 8.0 | 4272 | 0.0 | – | 0.0 | 0.0 | +| Shades of Gray | flat colour art | 7.33 | 11.24 | 0.257 | 1.43 | 179.39 | 4.7 | 200 | 18.45 | 22 | 50 | 0.3 | 3.7 | 173367 | 0.0 | – | 0.0 | 0.0 | +| Shades of Gray | gradient, photo | 9.71 | 9.55 | – | – | – | 18.2 | 748 | – | 51 | – | – | – | – | 0.0 | – | 0.5 | 0.0 | +| Black and White Logo | curved shapes | 0.04 | 1.51 | 0.024 | 0.50 | 0.59 | 1.2 | 21 | 2.29 | 20 | 83 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Black and White Logo | polygons | 0.04 | 1.83 | 0.030 | 0.43 | 1.24 | 1.7 | 16 | 1.39 | 90 | 90 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Black and White Logo | thin lines | 0.60 | 6.10 | 0.111 | 0.50 | 77.21 | 10.3 | 48 | 2.38 | 83 | – | – | – | – | – | – | 3.3 | 0.0 | +| Black and White Logo | flat colour art | 19.94 | 18.71 | 0.192 | 0.32 | 179.52 | 1.0 | 20 | 1.22 | 23 | 0 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Black and White Logo | gradient, photo | 39.11 | 38.71 | – | – | – | 9.0 | 574 | – | 67 | – | – | – | – | – | – | 0.0 | 0.0 | +| Sketched Art | curved shapes | 0.14 | 5.77 | 0.112 | 0.47 | 0.47 | 1.2 | 12 | 1.38 | 16 | 100 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Sketched Art | polygons | 0.12 | 4.81 | 0.088 | 0.52 | 1.05 | 1.7 | 13 | 1.18 | 85 | 88 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Sketched Art | thin lines | 0.40 | 5.10 | 0.106 | 0.80 | 52.93 | 4.3 | 39 | 1.93 | 35 | – | – | – | – | – | – | 0.0 | 0.0 | +| Sketched Art | flat colour art | 20.32 | 21.13 | 0.179 | 0.87 | 179.64 | 1.5 | 24 | 1.43 | 16 | 0 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Sketched Art | gradient, photo | 45.54 | 45.39 | – | – | – | 1.0 | 237 | – | 43 | – | – | – | – | – | – | 0.0 | 0.0 | +| Silhouettes | curved shapes | 0.36 | 14.54 | 0.282 | 0.71 | 0.71 | 1.2 | 12 | 1.34 | 15 | 100 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Silhouettes | polygons | 0.35 | 13.93 | 0.261 | 0.67 | 0.69 | 1.7 | 14 | 1.26 | 76 | 85 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Silhouettes | thin lines | 1.03 | 15.78 | 0.304 | 1.09 | 18.10 | 5.0 | 47 | 2.33 | 34 | – | – | – | – | – | – | 0.0 | 0.0 | +| Silhouettes | flat colour art | 23.86 | 33.99 | 0.224 | 0.77 | 188.38 | 1.0 | 11 | 0.78 | 24 | 0 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Silhouettes | gradient, photo | 61.57 | 61.34 | – | – | – | 0.2 | 2 | – | 42 | – | – | – | – | – | – | 0.0 | 0.0 | +| Line Art | curved shapes | 0.04 | 1.86 | 0.032 | 0.54 | 0.62 | 1.2 | 16 | 1.75 | 19 | 83 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Line Art | polygons | 0.05 | 1.90 | 0.031 | 0.40 | 1.24 | 1.7 | 14 | 1.26 | 90 | 90 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Line Art | thin lines | 0.54 | 4.39 | 0.049 | 0.47 | 105.75 | 3.3 | 35 | 1.77 | 41 | – | – | – | – | – | – | 0.0 | 0.0 | +| Line Art | flat colour art | 19.94 | 18.73 | 0.193 | 0.50 | 179.52 | 1.0 | 43 | 2.40 | 22 | 0 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Line Art | gradient, photo | 39.12 | 38.72 | – | – | – | 7.7 | 448 | – | 57 | – | – | – | – | – | – | 0.0 | 0.0 | +| Technical Drawing | curved shapes | 0.04 | 1.51 | 0.024 | 0.50 | 0.59 | 1.2 | 21 | 2.29 | 20 | 83 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Technical Drawing | polygons | 0.04 | 1.83 | 0.030 | 0.43 | 1.24 | 1.7 | 16 | 1.38 | 91 | 91 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Technical Drawing | thin lines | 0.53 | 5.83 | 0.125 | 0.50 | 55.75 | 15.3 | 61 | 3.03 | 88 | – | – | – | – | – | – | 8.3 | 0.0 | +| Technical Drawing | flat colour art | 19.94 | 18.71 | 0.192 | 0.32 | 179.52 | 1.0 | 20 | 1.22 | 23 | 0 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Technical Drawing | gradient, photo | 39.08 | 38.68 | – | – | – | 20.0 | 593 | – | 68 | – | – | – | – | – | – | 2.7 | 0.0 | | Flat Logo | curved shapes | 0.06 | 2.14 | 0.036 | 0.25 | 0.25 | 1.8 | 31 | 3.38 | 19 | 100 | 0.0 | 0.0 | 0 | 6.8 | – | 0.0 | 0.0 | | Flat Logo | polygons | 0.09 | 3.44 | 0.060 | 0.35 | 1.03 | 2.0 | 35 | 3.17 | 67 | 94 | 0.0 | 0.0 | 0 | 6.8 | – | 0.0 | 0.0 | | Flat Logo | thin lines | 1.17 | 11.78 | 0.050 | 0.49 | all | 3.0 | 189 | 9.45 | 28 | – | – | 0.0 | 0 | 5467.1 | – | 0.0 | 0.0 | @@ -186,66 +186,66 @@ All sizes and variants (clean, aliased, blurred, noisy, scanned) of those inputs | preset | variant | ΔE | edge ΔE | off mean | off max | missed max | paths | anchors | × art | lines % | corners % | kinks | odd colours | odd px | gap px | overlap px | specks | outside px | |:--|:--|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:| -| Default | clean | 0.07 | 2.76 | 0.048 | 0.51 | 1.23 | 1.9 | 15 | 1.52 | 46 | 88 | 0.0 | – | – | 14.3 | 13.5 | 0.0 | 0.0 | -| Default | aliased | 0.39 | 21.13 | 0.229 | 1.02 | 1.34 | 1.9 | 14 | 1.42 | 21 | 98 | 0.0 | – | – | 52.7 | 52.9 | 0.0 | 0.0 | -| Default | blurred | 0.82 | 16.65 | 0.078 | 0.86 | 2.17 | 1.9 | 26 | 2.50 | 7 | 19 | 1.6 | – | – | 23.0 | 23.6 | 0.0 | 0.0 | -| Default | noisy | 1.74 | 4.55 | 0.052 | 0.57 | 1.23 | 1.9 | 16 | 1.64 | 38 | 67 | 0.0 | – | – | 16.2 | 15.1 | 0.0 | 0.0 | -| Default | scanned | 15.06 | 20.24 | 0.134 | 0.87 | 2.17 | 1.9 | 26 | 2.53 | 0 | 25 | 1.0 | – | – | 20.8 | 24.7 | 0.0 | 0.0 | -| High Fidelity Photo | clean | 1.80 | 2.05 | – | – | – | 134.7 | 11186 | – | 43 | – | – | – | – | 0.0 | – | 7.7 | 0.1 | -| High Fidelity Photo | aliased | 1.78 | 2.01 | – | – | – | 73.0 | 7695 | – | 45 | – | – | – | – | 0.0 | – | 5.5 | 0.1 | -| High Fidelity Photo | blurred | 1.59 | 1.95 | – | – | – | 72.0 | 7184 | – | 45 | – | – | – | – | 0.0 | – | 0.5 | 0.1 | -| High Fidelity Photo | noisy | 2.02 | 2.19 | – | – | – | 155.5 | 10562 | – | 38 | – | – | – | – | 0.0 | – | 18.5 | 0.1 | -| High Fidelity Photo | scanned | 1.45 | 1.55 | – | – | – | 140.5 | 9726 | – | 41 | – | – | – | – | 0.0 | – | 24.5 | 0.1 | -| Low Fidelity Photo | clean | 2.53 | 2.80 | – | – | – | 42.7 | 2289 | – | 43 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | -| Low Fidelity Photo | aliased | 2.53 | 2.78 | – | – | – | 36.5 | 1504 | – | 46 | – | – | – | – | 0.0 | – | 0.0 | 0.1 | -| Low Fidelity Photo | blurred | 2.35 | 2.75 | – | – | – | 29.0 | 2004 | – | 45 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | -| Low Fidelity Photo | noisy | 2.70 | 2.85 | – | – | – | 32.0 | 1960 | – | 46 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | -| Low Fidelity Photo | scanned | 1.95 | 2.05 | – | – | – | 34.5 | 2588 | – | 42 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | -| 3 Colors | clean | 0.07 | 2.53 | 0.051 | 0.24 | 0.14 | 2.0 | 10 | 1.61 | 39 | 100 | 0.0 | 0.0 | 0 | 40.0 | 25.5 | 0.0 | 0.0 | -| 3 Colors | aliased | 0.18 | 9.81 | 0.236 | 0.74 | 0.56 | 2.0 | 7 | 1.17 | 39 | 100 | 0.0 | 0.0 | 0 | 123.2 | 82.4 | 0.0 | 0.0 | -| 3 Colors | blurred | 0.33 | 7.80 | 0.088 | 0.21 | 0.16 | 2.0 | 10 | 1.67 | 39 | 100 | 0.0 | 0.0 | 0 | 29.7 | 18.6 | 0.0 | 0.0 | -| 3 Colors | noisy | 0.71 | 1.81 | 0.049 | 0.23 | 0.08 | 2.0 | 9 | 1.50 | 39 | 100 | 0.0 | 0.0 | 0 | 35.7 | 9.7 | 0.0 | 0.0 | -| 3 Colors | scanned | 1.57 | 3.23 | 0.082 | 0.34 | 0.22 | 2.0 | 11 | 1.83 | 39 | 100 | 0.0 | 0.0 | 0 | 31.9 | 18.9 | 0.0 | 0.0 | -| 6 Colors | clean | 0.12 | 2.66 | 0.044 | 0.25 | 0.20 | 3.0 | 28 | 2.00 | 43 | 100 | 0.0 | 0.0 | 0 | 21.9 | 21.2 | 0.0 | 0.0 | -| 6 Colors | aliased | 0.31 | 10.53 | 0.291 | 1.00 | 1.00 | 3.0 | 26 | 1.91 | 42 | 100 | 0.0 | 0.0 | 0 | 82.6 | 74.0 | 0.0 | 0.0 | -| 6 Colors | blurred | 0.62 | 9.41 | 0.249 | 1.09 | 1.14 | 6.0 | 115 | 6.33 | 42 | 50 | 9.5 | 0.0 | 0 | 32.6 | 48.3 | 0.0 | 0.0 | -| 6 Colors | noisy | 0.85 | 2.50 | 0.048 | 0.26 | 0.18 | 3.0 | 28 | 2.01 | 33 | 100 | 0.0 | 0.0 | 0 | 29.7 | 22.5 | 0.0 | 0.0 | -| 6 Colors | scanned | 1.76 | 4.63 | 0.240 | 1.09 | 0.94 | 7.0 | 101 | 5.81 | 31 | 62 | 15.5 | 0.0 | 0 | 62.7 | 41.7 | 0.0 | 0.0 | -| 16 Colors | clean | 0.12 | 2.53 | 0.041 | 0.24 | 0.20 | 3.0 | 28 | 2.07 | 44 | 100 | 0.0 | 0.0 | 0 | 19.8 | 19.5 | 0.0 | 0.0 | -| 16 Colors | aliased | 0.30 | 10.39 | 0.274 | 1.00 | 1.00 | 3.0 | 34 | 2.34 | 43 | 100 | 0.0 | 0.0 | 0 | 77.3 | 51.7 | 0.0 | 0.0 | -| 16 Colors | blurred | 0.62 | 9.37 | 0.250 | 1.08 | 1.15 | 7.0 | 157 | 8.43 | 44 | 50 | 11.5 | 0.0 | 0 | 27.8 | 38.2 | 0.0 | 0.0 | -| 16 Colors | noisy | 0.85 | 2.34 | 0.042 | 0.27 | 0.22 | 3.0 | 32 | 2.27 | 34 | 100 | 0.0 | 0.0 | 0 | 23.4 | 15.6 | 0.0 | 0.0 | -| 16 Colors | scanned | 1.74 | 4.56 | 0.243 | 1.09 | 0.96 | 7.5 | 156 | 8.53 | 32 | 62 | 19.0 | 0.0 | 0 | 53.3 | 20.8 | 0.0 | 0.0 | -| Shades of Gray | clean | 9.71 | 9.55 | – | – | – | 18.2 | 955 | – | 53 | – | – | – | – | 0.0 | – | 0.5 | 0.8 | -| Shades of Gray | aliased | 9.70 | 9.52 | – | – | – | 11.0 | 788 | – | 58 | – | – | – | – | 0.0 | – | 0.5 | 0.7 | -| Shades of Gray | blurred | 9.66 | 9.32 | – | – | – | 11.5 | 729 | – | 56 | – | – | – | – | 0.0 | – | 0.5 | 0.7 | -| Shades of Gray | noisy | 9.74 | 9.44 | – | – | – | 19.5 | 823 | – | 47 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | -| Shades of Gray | scanned | 6.58 | 6.46 | – | – | – | 19.0 | 947 | – | 49 | – | – | – | – | 0.0 | – | 0.5 | 0.2 | -| Black and White Logo | clean | 0.04 | 1.65 | 0.027 | 0.50 | 1.23 | 1.4 | 18 | 1.86 | 50 | 86 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Black and White Logo | aliased | 0.39 | 20.41 | 0.176 | 1.00 | 1.34 | 1.4 | 24 | 2.47 | 53 | 98 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Black and White Logo | blurred | 0.81 | 16.37 | 0.047 | 0.80 | 2.18 | 1.4 | 39 | 3.78 | 23 | 19 | 1.0 | – | – | – | – | 0.0 | 0.0 | -| Black and White Logo | noisy | 1.72 | 3.90 | 0.028 | 0.50 | 1.23 | 1.4 | 21 | 2.14 | 41 | 67 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Black and White Logo | scanned | 15.05 | 20.10 | 0.116 | 0.82 | 2.17 | 1.4 | 53 | 5.13 | 11 | 25 | 0.9 | – | – | – | – | 0.0 | 0.0 | -| Sketched Art | clean | 0.18 | 5.43 | 0.106 | 0.80 | 52.57 | 1.9 | 18 | 1.52 | 20 | 100 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Sketched Art | aliased | 0.49 | 20.73 | 0.237 | 1.00 | 105.54 | 1.6 | 10 | 1.02 | 27 | 100 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Sketched Art | blurred | 1.07 | 19.51 | 0.264 | 0.66 | 105.48 | 1.6 | 18 | 1.57 | 13 | 50 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Sketched Art | noisy | 1.75 | 5.86 | 0.108 | 0.95 | 1.03 | 2.0 | 18 | 1.53 | 13 | 100 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Sketched Art | scanned | 15.11 | 22.41 | 0.438 | 0.85 | 105.28 | 1.6 | 20 | 1.73 | 1 | 50 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Silhouettes | clean | 0.34 | 14.15 | 0.274 | 0.66 | 0.66 | 1.2 | 12 | 1.36 | 17 | 100 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Silhouettes | aliased | 0.42 | 23.04 | 0.353 | 1.03 | 1.03 | 1.2 | 9 | 1.05 | 9 | 100 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Silhouettes | blurred | 1.23 | 28.51 | 0.803 | 1.42 | 1.84 | 1.2 | 17 | 1.91 | 13 | 50 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Silhouettes | noisy | 2.10 | 10.67 | 0.274 | 0.64 | 0.64 | 1.2 | 12 | 1.34 | 7 | 100 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Silhouettes | scanned | 16.05 | 30.27 | 1.472 | 2.24 | 2.24 | 1.2 | 23 | 3.15 | 3 | 0 | 1.0 | – | – | – | – | 0.0 | 0.0 | -| Line Art | clean | 0.54 | 4.38 | 0.049 | 0.47 | 105.71 | 3.3 | 33 | 1.67 | 42 | – | – | – | – | – | – | 0.0 | 0.0 | -| Line Art | aliased | 0.66 | 14.39 | 0.110 | 0.74 | 55.44 | 14.0 | 60 | 3.00 | 87 | – | – | – | – | – | – | 0.0 | 0.0 | -| Line Art | blurred | 1.63 | 17.25 | 0.137 | 0.89 | 105.61 | 3.0 | 139 | 6.95 | 3 | – | – | – | – | – | – | 0.0 | 0.0 | -| Line Art | noisy | 1.03 | 4.27 | 0.043 | 0.48 | 56.06 | 8.0 | 56 | 2.80 | 41 | – | – | – | – | – | – | 1.0 | 0.0 | -| Line Art | scanned | 13.60 | 20.04 | 0.212 | 0.84 | 105.58 | 3.0 | 186 | 9.30 | 0 | – | – | – | – | – | – | 0.0 | 0.0 | -| Technical Drawing | clean | 0.13 | 2.34 | 0.041 | 0.50 | 55.75 | 5.1 | 32 | 2.02 | 86 | 90 | 0.0 | – | – | – | – | 0.1 | 0.0 | -| Technical Drawing | aliased | 0.43 | 18.55 | 0.206 | 0.99 | 55.44 | 6.8 | 34 | 2.08 | 95 | 97 | 0.0 | – | – | – | – | 0.0 | 0.0 | -| Technical Drawing | blurred | 1.05 | 16.72 | 0.088 | 0.95 | 105.75 | 2.0 | 97 | 6.62 | 28 | 25 | 2.7 | – | – | – | – | 0.0 | 0.0 | -| Technical Drawing | noisy | 1.39 | 3.88 | 0.042 | 0.50 | 31.23 | 7.8 | 46 | 2.76 | 81 | 90 | 0.0 | – | – | – | – | 1.8 | 0.0 | -| Technical Drawing | scanned | 14.45 | 20.15 | 0.145 | 0.92 | 105.85 | 2.0 | 126 | 8.57 | 22 | 36 | 2.3 | – | – | – | – | 0.0 | 0.0 | +| Default | clean | 0.07 | 2.92 | 0.051 | 0.64 | 1.24 | 1.9 | 15 | 1.48 | 46 | 89 | 0.0 | – | – | 0.0 | 0.0 | 0.0 | 0.0 | +| Default | aliased | 0.37 | 20.23 | 0.233 | 1.02 | 1.35 | 1.9 | 15 | 1.45 | 21 | 96 | 0.0 | – | – | 0.0 | 0.0 | 0.0 | 0.0 | +| Default | blurred | 0.82 | 16.64 | 0.078 | 0.97 | 2.17 | 1.9 | 25 | 2.42 | 5 | 21 | 1.4 | – | – | 0.0 | 0.0 | 0.0 | 0.0 | +| Default | noisy | 1.74 | 4.50 | 0.050 | 0.54 | 1.24 | 1.9 | 16 | 1.64 | 39 | 67 | 0.0 | – | – | 2.3 | 0.6 | 0.0 | 0.0 | +| Default | scanned | 15.06 | 20.19 | 0.132 | 0.86 | 2.17 | 1.9 | 25 | 2.50 | 0 | 25 | 1.1 | – | – | 3.6 | 2.9 | 0.0 | 0.0 | +| High Fidelity Photo | clean | 1.80 | 2.04 | – | – | – | 134.7 | 11321 | – | 39 | – | – | – | – | 0.0 | – | 7.3 | 0.0 | +| High Fidelity Photo | aliased | 1.77 | 2.00 | – | – | – | 73.0 | 8004 | – | 40 | – | – | – | – | 0.0 | – | 5.5 | 0.0 | +| High Fidelity Photo | blurred | 1.59 | 1.95 | – | – | – | 72.0 | 7388 | – | 40 | – | – | – | – | 0.0 | – | 0.5 | 0.0 | +| High Fidelity Photo | noisy | 2.02 | 2.18 | – | – | – | 155.5 | 10856 | – | 33 | – | – | – | – | 0.0 | – | 18.5 | 0.0 | +| High Fidelity Photo | scanned | 1.45 | 1.55 | – | – | – | 140.5 | 9795 | – | 36 | – | – | – | – | 0.0 | – | 25.5 | 0.0 | +| Low Fidelity Photo | clean | 2.53 | 2.80 | – | – | – | 42.7 | 2282 | – | 41 | – | – | – | – | 0.0 | – | 0.0 | 0.0 | +| Low Fidelity Photo | aliased | 2.53 | 2.78 | – | – | – | 36.5 | 1498 | – | 44 | – | – | – | – | 0.0 | – | 0.0 | 0.0 | +| Low Fidelity Photo | blurred | 2.35 | 2.75 | – | – | – | 29.0 | 2005 | – | 42 | – | – | – | – | 0.0 | – | 0.0 | 0.0 | +| Low Fidelity Photo | noisy | 2.70 | 2.85 | – | – | – | 32.0 | 1926 | – | 41 | – | – | – | – | 0.0 | – | 0.0 | 0.0 | +| Low Fidelity Photo | scanned | 1.95 | 2.04 | – | – | – | 34.5 | 2548 | – | 39 | – | – | – | – | 0.0 | – | 0.0 | 0.0 | +| 3 Colors | clean | 0.06 | 2.00 | 0.070 | 0.31 | 0.30 | 2.0 | 11 | 1.78 | 39 | 100 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 3 Colors | aliased | 0.13 | 8.77 | 0.242 | 0.91 | 0.91 | 2.0 | 12 | 2.00 | 39 | 100 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 3 Colors | blurred | 0.34 | 7.83 | 0.073 | 0.24 | 0.24 | 2.0 | 9 | 1.50 | 39 | 100 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 3 Colors | noisy | 0.71 | 2.03 | 0.114 | 0.32 | 0.32 | 2.0 | 11 | 1.83 | 39 | 100 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 3 Colors | scanned | 1.57 | 3.22 | 0.089 | 0.30 | 0.30 | 2.0 | 12 | 2.00 | 39 | 100 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 6 Colors | clean | 0.12 | 2.70 | 0.057 | 0.31 | 0.30 | 3.0 | 28 | 2.00 | 43 | 100 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 6 Colors | aliased | 0.29 | 10.43 | 0.298 | 1.00 | 1.00 | 3.0 | 27 | 2.05 | 43 | 100 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 6 Colors | blurred | 0.62 | 9.33 | 0.204 | 1.34 | 1.19 | 6.0 | 98 | 5.46 | 39 | 50 | 16.0 | 0.0 | 0 | 0.6 | 0.0 | 0.0 | 0.0 | +| 6 Colors | noisy | 0.85 | 2.58 | 0.076 | 0.52 | 0.58 | 3.0 | 34 | 2.34 | 28 | 88 | 0.0 | 0.0 | 0 | 0.3 | 0.3 | 0.0 | 0.0 | +| 6 Colors | scanned | 1.74 | 4.42 | 0.228 | 1.20 | 0.94 | 7.0 | 108 | 6.10 | 28 | 62 | 20.5 | 0.0 | 0 | 0.8 | 1.6 | 0.0 | 0.0 | +| 16 Colors | clean | 0.12 | 2.52 | 0.052 | 0.31 | 0.30 | 3.0 | 28 | 2.11 | 43 | 100 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 16 Colors | aliased | 0.29 | 10.38 | 0.290 | 1.00 | 1.00 | 3.0 | 31 | 2.25 | 43 | 100 | 0.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 16 Colors | blurred | 0.63 | 9.38 | 0.215 | 1.31 | 1.19 | 7.0 | 132 | 7.21 | 42 | 50 | 21.0 | 0.0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | +| 16 Colors | noisy | 0.85 | 2.56 | 0.075 | 0.52 | 0.58 | 3.0 | 35 | 2.45 | 27 | 88 | 0.0 | 0.0 | 0 | 0.2 | 0.2 | 0.0 | 0.0 | +| 16 Colors | scanned | 1.72 | 4.43 | 0.256 | 1.09 | 0.96 | 7.5 | 151 | 8.31 | 33 | 62 | 24.0 | 0.0 | 0 | 1.2 | 1.2 | 0.0 | 0.0 | +| Shades of Gray | clean | 9.71 | 9.55 | – | – | – | 18.2 | 748 | – | 51 | – | – | – | – | 0.0 | – | 0.5 | 0.0 | +| Shades of Gray | aliased | 9.71 | 9.52 | – | – | – | 11.0 | 642 | – | 57 | – | – | – | – | 0.0 | – | 0.5 | 0.0 | +| Shades of Gray | blurred | 9.66 | 9.32 | – | – | – | 11.5 | 577 | – | 55 | – | – | – | – | 0.0 | – | 0.5 | 0.0 | +| Shades of Gray | noisy | 9.74 | 9.45 | – | – | – | 19.5 | 643 | – | 45 | – | – | – | – | 0.0 | – | 0.0 | 0.0 | +| Shades of Gray | scanned | 6.58 | 6.46 | – | – | – | 19.0 | 762 | – | 47 | – | – | – | – | 0.0 | – | 1.0 | 0.0 | +| Black and White Logo | clean | 0.04 | 1.64 | 0.027 | 0.50 | 1.24 | 1.4 | 19 | 1.90 | 50 | 89 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Black and White Logo | aliased | 0.39 | 20.35 | 0.172 | 1.02 | 1.35 | 1.4 | 22 | 2.32 | 53 | 96 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Black and White Logo | blurred | 0.80 | 16.29 | 0.045 | 0.82 | 2.15 | 1.4 | 38 | 3.62 | 21 | 21 | 0.9 | – | – | – | – | 0.0 | 0.0 | +| Black and White Logo | noisy | 1.72 | 3.90 | 0.028 | 0.51 | 1.24 | 1.4 | 22 | 2.18 | 40 | 67 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Black and White Logo | scanned | 15.05 | 20.10 | 0.115 | 0.86 | 2.17 | 1.4 | 51 | 5.02 | 11 | 25 | 0.9 | – | – | – | – | 0.0 | 0.0 | +| Sketched Art | clean | 0.19 | 5.64 | 0.111 | 0.80 | 52.93 | 1.9 | 18 | 1.49 | 19 | 100 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Sketched Art | aliased | 0.46 | 19.57 | 0.213 | 1.00 | 105.53 | 1.6 | 11 | 1.10 | 26 | 100 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Sketched Art | blurred | 1.07 | 19.72 | 0.274 | 0.70 | 105.49 | 1.6 | 17 | 1.53 | 10 | 50 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Sketched Art | noisy | 1.76 | 6.16 | 0.119 | 0.95 | 1.03 | 2.0 | 19 | 1.58 | 12 | 100 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Sketched Art | scanned | 15.12 | 22.50 | 0.442 | 0.86 | 105.27 | 1.6 | 20 | 1.65 | 2 | 50 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Silhouettes | clean | 0.36 | 14.54 | 0.282 | 0.71 | 0.71 | 1.2 | 12 | 1.34 | 15 | 100 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Silhouettes | aliased | 0.39 | 21.69 | 0.289 | 1.00 | 1.00 | 1.2 | 9 | 0.99 | 12 | 100 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Silhouettes | blurred | 1.21 | 28.11 | 0.785 | 1.45 | 1.92 | 1.2 | 15 | 1.82 | 11 | 25 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Silhouettes | noisy | 2.11 | 10.96 | 0.284 | 0.69 | 0.69 | 1.2 | 11 | 1.27 | 7 | 100 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Silhouettes | scanned | 16.05 | 30.19 | 1.458 | 2.23 | 2.21 | 1.2 | 25 | 3.37 | 3 | 0 | 1.2 | – | – | – | – | 0.0 | 0.0 | +| Line Art | clean | 0.54 | 4.39 | 0.049 | 0.47 | 105.75 | 3.3 | 35 | 1.77 | 41 | – | – | – | – | – | – | 0.0 | 0.0 | +| Line Art | aliased | 0.67 | 14.44 | 0.112 | 0.73 | 55.44 | 14.0 | 59 | 2.95 | 87 | – | – | – | – | – | – | 0.0 | 0.0 | +| Line Art | blurred | 1.63 | 17.15 | 0.136 | 0.89 | 105.57 | 3.0 | 143 | 7.15 | 4 | – | – | – | – | – | – | 0.0 | 0.0 | +| Line Art | noisy | 1.04 | 4.35 | 0.045 | 0.48 | 56.06 | 8.0 | 53 | 2.65 | 38 | – | – | – | – | – | – | 1.0 | 0.0 | +| Line Art | scanned | 13.60 | 20.06 | 0.214 | 0.91 | 105.64 | 3.0 | 188 | 9.40 | 1 | – | – | – | – | – | – | 0.0 | 0.0 | +| Technical Drawing | clean | 0.17 | 2.83 | 0.054 | 0.50 | 55.75 | 5.1 | 27 | 1.79 | 90 | 91 | 0.0 | – | – | – | – | 2.1 | 0.0 | +| Technical Drawing | aliased | 0.43 | 18.51 | 0.204 | 1.02 | 55.44 | 6.8 | 33 | 2.06 | 95 | 94 | 0.0 | – | – | – | – | 0.0 | 0.0 | +| Technical Drawing | blurred | 1.04 | 16.59 | 0.082 | 1.06 | 105.75 | 2.0 | 114 | 7.50 | 24 | 28 | 2.3 | – | – | – | – | 0.0 | 0.0 | +| Technical Drawing | noisy | 1.42 | 4.30 | 0.055 | 0.50 | 31.23 | 7.8 | 38 | 2.40 | 85 | 90 | 0.0 | – | – | – | – | 2.8 | 0.0 | +| Technical Drawing | scanned | 14.45 | 20.15 | 0.144 | 0.91 | 105.74 | 2.0 | 123 | 8.33 | 23 | 34 | 2.3 | – | – | – | – | 0.0 | 0.0 | | Flat Logo | clean | 0.07 | 1.53 | 0.065 | 0.31 | 0.27 | 3.0 | 36 | 3.51 | 47 | 100 | 0.0 | 0.0 | 0 | 6.8 | – | 0.0 | 0.0 | | Flat Logo | aliased | 0.13 | 5.87 | 0.218 | 0.65 | 0.65 | 3.0 | 31 | 1.96 | 44 | 50 | 0.0 | 0.0 | 0 | 5.8 | – | 0.0 | 0.0 | | Flat Logo | blurred | 0.54 | 8.33 | 0.052 | 0.62 | 0.78 | 3.0 | 28 | 1.78 | 43 | 50 | 0.0 | 0.0 | 0 | 5.8 | – | 0.0 | 0.0 | @@ -282,89 +282,90 @@ One trace at a time on this machine (all cores); memory is the peak allocated ab | preset | image | megapixels | result | |:--|:--|--:|:--| -| Default | photo-like | 1 | 0.05 s, 29 paths, 7947 anchors, 15 MB | -| Default | four-colour badge | 1 | 0.03 s, 3 paths, 106 anchors, 15 MB | -| High Fidelity Photo | photo-like | 1 | 0.25 s, 968 paths, 113205 anchors, 238 MB | -| High Fidelity Photo | four-colour badge | 1 | 0.06 s, 6 paths, 192 anchors, 34 MB | -| Low Fidelity Photo | photo-like | 1 | 0.13 s, 129 paths, 22788 anchors, 141 MB | -| Low Fidelity Photo | four-colour badge | 1 | 0.05 s, 6 paths, 144 anchors, 36 MB | -| 3 Colors | photo-like | 1 | 0.07 s, 9 paths, 3391 anchors, 26 MB | -| 3 Colors | four-colour badge | 1 | 0.05 s, 4 paths, 79 anchors, 21 MB | -| 6 Colors | photo-like | 1 | 0.08 s, 78 paths, 9239 anchors, 42 MB | -| 6 Colors | four-colour badge | 1 | 0.05 s, 5 paths, 89 anchors, 33 MB | -| 16 Colors | photo-like | 1 | 0.11 s, 178 paths, 21069 anchors, 102 MB | -| 16 Colors | four-colour badge | 1 | 0.05 s, 5 paths, 92 anchors, 33 MB | -| Shades of Gray | photo-like | 1 | 0.09 s, 82 paths, 8511 anchors, 65 MB | -| Shades of Gray | four-colour badge | 1 | 0.06 s, 10 paths, 780 anchors, 56 MB | -| Black and White Logo | photo-like | 1 | 0.05 s, 71 paths, 9067 anchors, 9 MB | -| Black and White Logo | four-colour badge | 1 | 0.02 s, 1 paths, 58 anchors, 8 MB | -| Sketched Art | photo-like | 1 | 0.05 s, 5 paths, 3207 anchors, 9 MB | -| Sketched Art | four-colour badge | 1 | 0.02 s, 2 paths, 145 anchors, 8 MB | -| Silhouettes | photo-like | 1 | 0.04 s, 2 paths, 851 anchors, 11 MB | -| Silhouettes | four-colour badge | 1 | 0.02 s, 1 paths, 29 anchors, 9 MB | -| Line Art | photo-like | 1 | 0.05 s, 54 paths, 4751 anchors, 9 MB | -| Line Art | four-colour badge | 1 | 0.02 s, 1 paths, 243 anchors, 8 MB | -| Technical Drawing | photo-like | 1 | 0.06 s, 221 paths, 10646 anchors, 9 MB | -| Technical Drawing | four-colour badge | 1 | 0.02 s, 1 paths, 58 anchors, 8 MB | +| Default | photo-like | 1 | 0.04 s, 29 paths, 6888 anchors, 15 MB | +| Default | four-colour badge | 1 | 0.02 s, 3 paths, 96 anchors, 15 MB | +| High Fidelity Photo | photo-like | 1 | 0.21 s, 968 paths, 114383 anchors, 238 MB | +| High Fidelity Photo | four-colour badge | 1 | 0.06 s, 6 paths, 172 anchors, 36 MB | +| Low Fidelity Photo | photo-like | 1 | 0.11 s, 129 paths, 22929 anchors, 144 MB | +| Low Fidelity Photo | four-colour badge | 1 | 0.05 s, 6 paths, 136 anchors, 36 MB | +| 3 Colors | photo-like | 1 | 0.08 s, 9 paths, 3367 anchors, 26 MB | +| 3 Colors | four-colour badge | 1 | 0.05 s, 4 paths, 88 anchors, 21 MB | +| 6 Colors | photo-like | 1 | 0.08 s, 78 paths, 9008 anchors, 42 MB | +| 6 Colors | four-colour badge | 1 | 0.05 s, 5 paths, 84 anchors, 33 MB | +| 16 Colors | photo-like | 1 | 0.10 s, 178 paths, 20466 anchors, 102 MB | +| 16 Colors | four-colour badge | 1 | 0.05 s, 5 paths, 88 anchors, 33 MB | +| Shades of Gray | photo-like | 1 | 0.08 s, 81 paths, 6698 anchors, 65 MB | +| Shades of Gray | four-colour badge | 1 | 0.06 s, 10 paths, 733 anchors, 56 MB | +| Black and White Logo | photo-like | 1 | 0.04 s, 71 paths, 5465 anchors, 9 MB | +| Black and White Logo | four-colour badge | 1 | 0.02 s, 1 paths, 52 anchors, 8 MB | +| Sketched Art | photo-like | 1 | 0.04 s, 5 paths, 2971 anchors, 9 MB | +| Sketched Art | four-colour badge | 1 | 0.02 s, 2 paths, 131 anchors, 8 MB | +| Silhouettes | photo-like | 1 | 0.04 s, 2 paths, 791 anchors, 11 MB | +| Silhouettes | four-colour badge | 1 | 0.02 s, 1 paths, 25 anchors, 9 MB | +| Line Art | photo-like | 1 | 0.04 s, 54 paths, 4421 anchors, 9 MB | +| Line Art | four-colour badge | 1 | 0.02 s, 1 paths, 232 anchors, 8 MB | +| Technical Drawing | photo-like | 1 | 0.04 s, 221 paths, 7680 anchors, 9 MB | +| Technical Drawing | four-colour badge | 1 | 0.02 s, 1 paths, 52 anchors, 8 MB | | Flat Logo | photo-like | 1 | refused after 0.09 s (not flat art), 40 MB | | Flat Logo | four-colour badge | 1 | 0.64 s, 5 paths, 78 anchors, 146 MB | -| Default | photo-like | 4 | 0.19 s, 48 paths, 20717 anchors, 60 MB | -| Default | four-colour badge | 4 | 0.10 s, 3 paths, 148 anchors, 64 MB | -| High Fidelity Photo | photo-like | 4 | 0.88 s, 4475 paths, 344985 anchors, 964 MB | -| High Fidelity Photo | four-colour badge | 4 | 0.22 s, 6 paths, 216 anchors, 152 MB | -| Low Fidelity Photo | photo-like | 4 | 0.38 s, 304 paths, 61608 anchors, 592 MB | -| Low Fidelity Photo | four-colour badge | 4 | 0.23 s, 6 paths, 169 anchors, 152 MB | -| 3 Colors | photo-like | 4 | 0.28 s, 20 paths, 8647 anchors, 104 MB | +| Default | photo-like | 4 | 0.18 s, 48 paths, 17801 anchors, 60 MB | +| Default | four-colour badge | 4 | 0.09 s, 3 paths, 178 anchors, 64 MB | +| High Fidelity Photo | photo-like | 4 | 0.72 s, 4475 paths, 341272 anchors, 981 MB | +| High Fidelity Photo | four-colour badge | 4 | 0.24 s, 6 paths, 200 anchors, 152 MB | +| Low Fidelity Photo | photo-like | 4 | 0.38 s, 304 paths, 61093 anchors, 568 MB | +| Low Fidelity Photo | four-colour badge | 4 | 0.23 s, 6 paths, 152 anchors, 152 MB | +| 3 Colors | photo-like | 4 | 0.28 s, 20 paths, 8453 anchors, 104 MB | | 3 Colors | four-colour badge | 4 | 0.18 s, 4 paths, 122 anchors, 84 MB | -| 6 Colors | photo-like | 4 | 0.27 s, 115 paths, 24075 anchors, 165 MB | -| 6 Colors | four-colour badge | 4 | 0.19 s, 5 paths, 116 anchors, 128 MB | -| 16 Colors | photo-like | 4 | 0.33 s, 353 paths, 54215 anchors, 380 MB | -| 16 Colors | four-colour badge | 4 | 0.18 s, 5 paths, 124 anchors, 128 MB | -| Shades of Gray | photo-like | 4 | 0.29 s, 137 paths, 22704 anchors, 232 MB | -| Shades of Gray | four-colour badge | 4 | 0.27 s, 10 paths, 1234 anchors, 220 MB | -| Black and White Logo | photo-like | 4 | 0.21 s, 208 paths, 25916 anchors, 36 MB | -| Black and White Logo | four-colour badge | 4 | 0.08 s, 1 paths, 64 anchors, 36 MB | -| Sketched Art | photo-like | 4 | 0.21 s, 9 paths, 6875 anchors, 36 MB | -| Sketched Art | four-colour badge | 4 | 0.08 s, 2 paths, 279 anchors, 36 MB | -| Silhouettes | photo-like | 4 | 0.18 s, 2 paths, 2133 anchors, 44 MB | +| 6 Colors | photo-like | 4 | 0.37 s, 115 paths, 23128 anchors, 168 MB | +| 6 Colors | four-colour badge | 4 | 0.19 s, 5 paths, 92 anchors, 128 MB | +| 16 Colors | photo-like | 4 | 0.32 s, 353 paths, 52749 anchors, 408 MB | +| 16 Colors | four-colour badge | 4 | 0.19 s, 5 paths, 96 anchors, 128 MB | +| Shades of Gray | photo-like | 4 | 0.29 s, 138 paths, 18794 anchors, 224 MB | +| Shades of Gray | four-colour badge | 4 | 0.27 s, 10 paths, 1265 anchors, 220 MB | +| Black and White Logo | photo-like | 4 | 0.20 s, 208 paths, 17188 anchors, 36 MB | +| Black and White Logo | four-colour badge | 4 | 0.09 s, 1 paths, 64 anchors, 36 MB | +| Sketched Art | photo-like | 4 | 0.20 s, 9 paths, 6884 anchors, 36 MB | +| Sketched Art | four-colour badge | 4 | 0.09 s, 2 paths, 236 anchors, 36 MB | +| Silhouettes | photo-like | 4 | 0.19 s, 2 paths, 1951 anchors, 44 MB | | Silhouettes | four-colour badge | 4 | 0.10 s, 1 paths, 32 anchors, 36 MB | -| Line Art | photo-like | 4 | 0.21 s, 127 paths, 12595 anchors, 36 MB | -| Line Art | four-colour badge | 4 | 0.08 s, 1 paths, 465 anchors, 36 MB | -| Technical Drawing | photo-like | 4 | 0.22 s, 931 paths, 33946 anchors, 36 MB | +| Line Art | photo-like | 4 | 0.19 s, 127 paths, 12091 anchors, 36 MB | +| Line Art | four-colour badge | 4 | 0.09 s, 1 paths, 419 anchors, 36 MB | +| Technical Drawing | photo-like | 4 | 0.20 s, 931 paths, 23132 anchors, 36 MB | | Technical Drawing | four-colour badge | 4 | 0.08 s, 1 paths, 64 anchors, 36 MB | | Flat Logo | photo-like | 4 | refused after 0.10 s (not flat art), 40 MB | -| Flat Logo | four-colour badge | 4 | 0.66 s, 5 paths, 69 anchors, 146 MB | -| Default | photo-like | 16 | 1.08 s, 127 paths, 46199 anchors, 256 MB | -| Default | four-colour badge | 16 | 0.46 s, 3 paths, 284 anchors, 240 MB | -| High Fidelity Photo | photo-like | 16 | 3.48 s, 31131 paths, 1254672 anchors, 3954 MB | -| High Fidelity Photo | four-colour badge | 16 | 1.07 s, 6 paths, 248 anchors, 576 MB | -| Low Fidelity Photo | photo-like | 16 | 1.57 s, 2036 paths, 185091 anchors, 2050 MB | -| Low Fidelity Photo | four-colour badge | 16 | 1.08 s, 6 paths, 188 anchors, 576 MB | -| 3 Colors | photo-like | 16 | 1.27 s, 76 paths, 23365 anchors, 416 MB | -| 3 Colors | four-colour badge | 16 | 0.80 s, 4 paths, 179 anchors, 336 MB | -| 6 Colors | photo-like | 16 | 1.17 s, 470 paths, 63030 anchors, 673 MB | -| 6 Colors | four-colour badge | 16 | 0.84 s, 5 paths, 118 anchors, 512 MB | -| 16 Colors | photo-like | 16 | 1.30 s, 1973 paths, 149717 anchors, 1633 MB | -| 16 Colors | four-colour badge | 16 | 0.84 s, 5 paths, 120 anchors, 504 MB | -| Shades of Gray | photo-like | 16 | 1.32 s, 688 paths, 65052 anchors, 850 MB | -| Shades of Gray | four-colour badge | 16 | 1.28 s, 9 paths, 2296 anchors, 800 MB | -| Black and White Logo | photo-like | 16 | 1.04 s, 1128 paths, 77629 anchors, 144 MB | -| Black and White Logo | four-colour badge | 16 | 0.45 s, 1 paths, 103 anchors, 128 MB | -| Sketched Art | photo-like | 16 | 1.15 s, 15 paths, 17817 anchors, 144 MB | -| Sketched Art | four-colour badge | 16 | 0.48 s, 2 paths, 478 anchors, 128 MB | -| Silhouettes | photo-like | 16 | 1.40 s, 3 paths, 4891 anchors, 176 MB | -| Silhouettes | four-colour badge | 16 | 0.55 s, 1 paths, 44 anchors, 144 MB | -| Line Art | photo-like | 16 | 1.21 s, 713 paths, 64481 anchors, 144 MB | -| Line Art | four-colour badge | 16 | 0.45 s, 1 paths, 786 anchors, 128 MB | -| Technical Drawing | photo-like | 16 | 1.20 s, 4578 paths, 114292 anchors, 144 MB | -| Technical Drawing | four-colour badge | 16 | 0.44 s, 1 paths, 103 anchors, 128 MB | +| Flat Logo | four-colour badge | 4 | 0.65 s, 5 paths, 69 anchors, 146 MB | +| Default | photo-like | 16 | 1.04 s, 127 paths, 43656 anchors, 256 MB | +| Default | four-colour badge | 16 | 0.47 s, 3 paths, 250 anchors, 240 MB | +| High Fidelity Photo | photo-like | 16 | 2.85 s, 31125 paths, 1175671 anchors, 3856 MB | +| High Fidelity Photo | four-colour badge | 16 | 1.11 s, 6 paths, 274 anchors, 576 MB | +| Low Fidelity Photo | photo-like | 16 | 1.49 s, 2036 paths, 181832 anchors, 1972 MB | +| Low Fidelity Photo | four-colour badge | 16 | 1.07 s, 6 paths, 187 anchors, 576 MB | +| 3 Colors | photo-like | 16 | 1.22 s, 76 paths, 22878 anchors, 416 MB | +| 3 Colors | four-colour badge | 16 | 0.82 s, 4 paths, 190 anchors, 336 MB | +| 6 Colors | photo-like | 16 | 1.13 s, 470 paths, 60539 anchors, 672 MB | +| 6 Colors | four-colour badge | 16 | 0.82 s, 5 paths, 126 anchors, 500 MB | +| 16 Colors | photo-like | 16 | 1.18 s, 1973 paths, 145173 anchors, 1625 MB | +| 16 Colors | four-colour badge | 16 | 0.84 s, 5 paths, 128 anchors, 504 MB | +| Shades of Gray | photo-like | 16 | 1.48 s, 686 paths, 53872 anchors, 852 MB | +| Shades of Gray | four-colour badge | 16 | 1.40 s, 9 paths, 2216 anchors, 800 MB | +| Black and White Logo | photo-like | 16 | 1.15 s, 1128 paths, 52547 anchors, 144 MB | +| Black and White Logo | four-colour badge | 16 | 0.47 s, 1 paths, 95 anchors, 128 MB | +| Sketched Art | photo-like | 16 | 1.16 s, 15 paths, 16298 anchors, 144 MB | +| Sketched Art | four-colour badge | 16 | 0.47 s, 2 paths, 414 anchors, 128 MB | +| Silhouettes | photo-like | 16 | 1.34 s, 3 paths, 4516 anchors, 176 MB | +| Silhouettes | four-colour badge | 16 | 0.53 s, 1 paths, 40 anchors, 144 MB | +| Line Art | photo-like | 16 | 1.04 s, 713 paths, 43982 anchors, 144 MB | +| Line Art | four-colour badge | 16 | 0.45 s, 1 paths, 707 anchors, 128 MB | +| Technical Drawing | photo-like | 16 | 1.21 s, 4578 paths, 84475 anchors, 144 MB | +| Technical Drawing | four-colour badge | 16 | 0.46 s, 1 paths, 95 anchors, 128 MB | | Flat Logo | photo-like | 16 | refused after 0.11 s (not flat art), 40 MB | -| Flat Logo | four-colour badge | 16 | 0.66 s, 5 paths, 67 anchors, 146 MB | +| Flat Logo | four-colour badge | 16 | 0.69 s, 5 paths, 67 anchors, 146 MB | ## Revision history | date | change | |:--|:--| +| 2026-10-13 | Shared edges: outlines are cut at their junctions and each piece is fitted once, the same from either side | | 2026-10-13 | Photos: continuous-tone images are smoothed within their tones before quantising, and stacked layers go by lightness | | 2026-10-13 | The palette: made of the picture's own colours, noise-made colours merged, blend pixels settled, cuts where colours differ most, colours compared in Oklab | | 2026-10-13 | Sub-pixel edges and the outline fitter in Black and White, Grayscale and Color; the harness gains an aliased variant and an "outside px" column, so the baseline was measured again with it (same tracer, main at `baf9693f`) |