mirror of
https://github.com/visioncortex/vtracer.git
synced 2026-08-30 17:05:57 -07:00
Improve core lib docs for docs.rs
- lib.rs: rewrite the crate landing page — single-line pipeline diagram, define the Segmentation/VectorDoc IRs, stage->trait->module table with intra-doc links, and Quick start / Interactive tuning / Extending / wasm-safe sections. - config.rs: fix stale Hierarchical::Cutout doc (it is the implemented seam-free mosaic, not "not yet implemented"); document the previously bare Hierarchical/FitMode/Preset enums and variants, the hierarchical/ mode/max_iterations fields, and from_preset. - frontend: surface adaptive thresholding — BinaryFrontend module bullet and struct doc now point at Threshold::Fixed / Threshold::Adaptive. - error.rs: add the missing module-level doc. - Fix two pre-existing rustdoc link warnings (private-item link in config.rs, redundant explicit target in session.rs); crate now documents warning-free under -D warnings.
This commit is contained in:
@@ -30,31 +30,46 @@ pub enum Clustering {
|
||||
Watershed,
|
||||
}
|
||||
|
||||
/// How regions are combined into the final document.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Hierarchical {
|
||||
/// Trace each layer independently and stack them in paint order (painter's
|
||||
/// algorithm). Simple and robust; smoothed neighbours may drift slightly
|
||||
/// apart along a shared edge.
|
||||
Stacked,
|
||||
/// True mosaic cutout — not yet implemented (separate milestone).
|
||||
/// Seam-free, gapless mosaic: each shared boundary is fitted once and
|
||||
/// referenced by both adjacent faces, so the tessellation never cracks.
|
||||
/// See [`crate::mosaic`].
|
||||
Cutout,
|
||||
}
|
||||
|
||||
/// How a region's pixel outline is turned into vector geometry.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum FitMode {
|
||||
/// Exact pixel-lattice polyline; no smoothing.
|
||||
Pixel,
|
||||
/// Douglas–Peucker polygon — straight edges, fewer points.
|
||||
Polygon,
|
||||
/// Corner detection plus least-squares cubic Béziers — smooth curves.
|
||||
Spline,
|
||||
}
|
||||
|
||||
/// A starting point for [`Config`], tuned for a common kind of input. See
|
||||
/// [`Config::from_preset`].
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Preset {
|
||||
/// Black-and-white line art (binary clustering).
|
||||
Bw,
|
||||
/// Flat, poster-like color with a fuller palette.
|
||||
Poster,
|
||||
/// Photographic input: heavier speckle filtering and coarser layering.
|
||||
Photo,
|
||||
}
|
||||
|
||||
/// The clustering-relevant projection of a [`Config`]. Two configs with equal
|
||||
/// keys produce the same [`Segmentation`](crate::Segmentation), so a cached one
|
||||
/// stays valid — this is what [`Session`](crate::Session) compares to decide
|
||||
/// whether to re-segment. Kept in sync with [`Config::frontend`] in one place.
|
||||
/// whether to re-segment. Produced by [`Config::segment_key`].
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct SegmentKey {
|
||||
clustering: Clustering,
|
||||
@@ -74,6 +89,8 @@ pub struct SegmentKey {
|
||||
pub struct Config {
|
||||
/// Region-forming algorithm (see [`Clustering`]).
|
||||
pub clustering: Clustering,
|
||||
/// How regions are combined — stacked layers or a seam-free mosaic (see
|
||||
/// [`Hierarchical`]).
|
||||
pub hierarchical: Hierarchical,
|
||||
/// Speckle filter given as a side length; the area threshold is its square.
|
||||
pub filter_speckle: usize,
|
||||
@@ -81,11 +98,13 @@ pub struct Config {
|
||||
pub color_precision: i32,
|
||||
/// Color difference between gradient layers.
|
||||
pub layer_difference: i32,
|
||||
/// Curve-fitting mode (see [`FitMode`]).
|
||||
pub mode: FitMode,
|
||||
/// Corner threshold in degrees.
|
||||
pub corner_threshold: i32,
|
||||
/// Segment length threshold in pixels.
|
||||
pub length_threshold: f64,
|
||||
/// Maximum least-squares refinement iterations per spline segment.
|
||||
pub max_iterations: usize,
|
||||
/// Splice threshold in degrees.
|
||||
pub splice_threshold: i32,
|
||||
@@ -145,6 +164,8 @@ impl Default for Config {
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Build a [`Config`] from a [`Preset`], adjusting the defaults for a
|
||||
/// common kind of input.
|
||||
pub fn from_preset(preset: Preset) -> Self {
|
||||
match preset {
|
||||
Preset::Bw => Self {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
//! The crate's [`Error`] type, returned by the pipeline and every stage.
|
||||
|
||||
use std::fmt;
|
||||
|
||||
/// Errors produced by the framework stages and the pipeline driver.
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
//! Built-ins:
|
||||
//! * [`ColorClusterFrontend`] — hierarchical color clustering (the classic
|
||||
//! VTracer color path), including transparency keying.
|
||||
//! * [`BinaryFrontend`] — threshold to black/white then cluster.
|
||||
//! * [`BinaryFrontend`] — threshold to black/white then cluster; the
|
||||
//! [`Threshold`] can be a fixed global cutoff or Bradley–Roth adaptive
|
||||
//! thresholding for unevenly-lit input.
|
||||
//! * [`WatershedFrontend`] — hierarchical watershed on the pixel graph.
|
||||
//!
|
||||
//! Third parties can implement [`Frontend`] to feed external label maps or ML
|
||||
|
||||
@@ -53,11 +53,16 @@ impl Default for Threshold {
|
||||
/// Binary (black/white) frontend: threshold the image then cluster the
|
||||
/// foreground. Every region is painted black.
|
||||
///
|
||||
/// The [`Threshold`] chooses how foreground is separated from background — a
|
||||
/// fixed global cutoff ([`Threshold::Fixed`]) or Bradley–Roth adaptive
|
||||
/// thresholding ([`Threshold::Adaptive`]) for scans and photos with uneven
|
||||
/// lighting.
|
||||
///
|
||||
/// Speckle removal drops clusters smaller than `min_area` px as the clusters
|
||||
/// are collected, matching the pre-1.0 binary path (`cluster.size() >= area`).
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BinaryFrontend {
|
||||
/// How foreground pixels are selected.
|
||||
/// How foreground pixels are selected (see [`Threshold`]).
|
||||
pub threshold: Threshold,
|
||||
/// Whether to connect clusters diagonally.
|
||||
pub diagonal: bool,
|
||||
|
||||
+65
-16
@@ -1,33 +1,82 @@
|
||||
//! # vtracer
|
||||
//!
|
||||
//! A vectorization *framework*: raster images become vector graphics through a
|
||||
//! pipeline of pluggable stages.
|
||||
//! Convert raster images into vector graphics (SVG). VTracer is a
|
||||
//! *framework*: the conversion runs as a pipeline of small, swappable stages,
|
||||
//! so you can reach for a one-line convenience call or rebuild the pipeline
|
||||
//! stage by stage.
|
||||
//!
|
||||
//! ## The pipeline
|
||||
//!
|
||||
//! ```text
|
||||
//! Frontend ─▶ ColorFitter* ─▶ Compositing ─▶ CurveFitter ─▶ CurvePass* ─▶ VectorDoc
|
||||
//! │
|
||||
//! OptimizerPass* ─────┤
|
||||
//! ▼
|
||||
//! SvgWriter ─▶ SVG
|
||||
//! image ──▶ Frontend ──▶ ColorFitter ──▶ Compositing ──▶ Optimizer ──▶ SvgWriter ──▶ SVG
|
||||
//! ```
|
||||
//!
|
||||
//! The crate is wasm-safe: it performs no file or image I/O (that lives in the
|
||||
//! `vtracer-cli` wrapper). Everything here compiles to
|
||||
//! `wasm32-unknown-unknown`.
|
||||
//! Two intermediate representations carry the work between stages:
|
||||
//!
|
||||
//! * a [`Segmentation`] — the frontend's output: flat-color regions (paint
|
||||
//! layers) over the canvas, which the color fitters may recolor or quantize;
|
||||
//! * a [`VectorDoc`] — the output document: resolved shapes with fitted vector
|
||||
//! paths, which the optimizer passes shrink and the writer serializes.
|
||||
//!
|
||||
//! Compositing is where the geometry is built — it runs the curve
|
||||
//! [`CurveFitter`](fitter::CurveFitter) on each region outline, then any
|
||||
//! geometry [`CurvePass`](simplify::CurvePass)es (curve simplification and the
|
||||
//! like) over the fitted curves. Every stage is a trait in its own module, and
|
||||
//! most can run more than once (a chain of color fitters, several optimizer
|
||||
//! passes):
|
||||
//!
|
||||
//! | Stage | Trait | Module |
|
||||
//! |---|---|---|
|
||||
//! | Region forming | [`Frontend`](frontend::Frontend) | [`frontend`] |
|
||||
//! | Recolor / quantize | [`ColorFitter`](colorfit::ColorFitter) | [`colorfit`] |
|
||||
//! | Curve fitting | [`CurveFitter`](fitter::CurveFitter) | [`fitter`] |
|
||||
//! | Geometry passes | [`CurvePass`](simplify::CurvePass) | [`simplify`] |
|
||||
//! | Compositing | *(stacked or mosaic)* | [`compose`], [`mosaic`] |
|
||||
//! | Optimization | [`OptimizerPass`](optimize::OptimizerPass) | [`optimize`] |
|
||||
//! | Serialization | *(SVG writer)* | [`svg`] |
|
||||
//!
|
||||
//! ## Quick start
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use vtracer::{Config, ColorImage};
|
||||
//! [`Config`] is the high-level entry point: choose options (or start from a
|
||||
//! [`Preset`]), [`build`](Config::build) a [`Pipeline`], and run it. The crate
|
||||
//! does no image decoding — hand it a decoded [`ColorImage`] and get back an
|
||||
//! SVG string.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use vtracer::{Config, ColorImage, Preset};
|
||||
//! # fn load() -> ColorImage { todo!() }
|
||||
//! let img: ColorImage = load();
|
||||
//! let svg = Config::default().build().unwrap().to_svg(&img).unwrap();
|
||||
//!
|
||||
//! // one-shot: image → SVG string, all defaults
|
||||
//! let svg = Config::default().build()?.to_svg(&img)?;
|
||||
//!
|
||||
//! // start from a preset and tweak
|
||||
//! let mut cfg = Config::from_preset(Preset::Poster);
|
||||
//! cfg.simplify = Some(1.5); // paper.js-style curve simplification
|
||||
//! let svg = cfg.build()?.to_svg(&img)?;
|
||||
//! # Ok::<(), vtracer::Error>(())
|
||||
//! ```
|
||||
//!
|
||||
//! For finer control, assemble a [`Pipeline`] directly from the stage traits
|
||||
//! in [`frontend`], [`colorfit`], [`fitter`], [`simplify`], [`compose`],
|
||||
//! [`optimize`], and [`svg`].
|
||||
//! ## Interactive tuning
|
||||
//!
|
||||
//! Segmentation is the expensive stage. A [`Session`] caches it and re-renders
|
||||
//! only the cheap downstream stages when a non-clustering parameter changes,
|
||||
//! re-segmenting automatically when it must — ideal behind a live UI with
|
||||
//! sliders. See the [`session`] module.
|
||||
//!
|
||||
//! ## Extending the pipeline
|
||||
//!
|
||||
//! Build a [`Pipeline`] by hand to mix in your own stages: implement
|
||||
//! [`Frontend`](frontend::Frontend) to feed an external label map or ML
|
||||
//! segmentation, [`ColorFitter`](colorfit::ColorFitter) for a custom palette
|
||||
//! policy, or [`CurvePass`](simplify::CurvePass) for a geometry transform.
|
||||
//!
|
||||
//! ## No I/O, wasm-safe
|
||||
//!
|
||||
//! Because it performs no file or image I/O, the crate compiles cleanly to
|
||||
//! `wasm32-unknown-unknown`. Decoding and file handling live in the wrappers:
|
||||
//! the `vtracer-cli` command-line tool, the `vtracer` Python package, and the
|
||||
//! `@visioncortex/vtracer` Node package.
|
||||
|
||||
pub mod colorfit;
|
||||
pub mod compose;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//!
|
||||
//! A desktop app loads an image once, then calls [`Session::render`] on every
|
||||
//! slider change with a fresh [`Config`]. The session compares the config's
|
||||
//! [`SegmentKey`](crate::config::SegmentKey) to what it last clustered and
|
||||
//! [`SegmentKey`] to what it last clustered and
|
||||
//! re-segments only if a clustering parameter changed — the caller never has to
|
||||
//! know which parameters those are.
|
||||
//!
|
||||
|
||||
Reference in New Issue
Block a user