Repository navigation
Home
github-actions[bot] edited this page Oct 17, 2026
·
9 revisions
SvgCreator turns a raster image, such as an anime character illustration, into a line-art SVG: black ink outlines with no colouring. These pages record the techniques used in the project, why each one was chosen over the alternatives, and the pitfalls hit along the way, with the measurements that drove each decision.
These pages are generated from
docs/in the repository, which is the source of truth. Edit them there; direct wiki edits are overwritten on the next sync.
flowchart LR
A[Image file] --> B[Decode<br/>SkiaSharp]
B --> C[Extract ink<br/>DoG + hysteresis<br/>+ Lab colour edges]
C --> D[Label components<br/>union-find]
D --> E[Trace contours<br/>pixel-edge following]
E --> F[Fit shapes & curves<br/>ellipses, corners + Schneider]
F --> G[Write SVG<br/>compact relative paths]
| Stage | Page | Code |
|---|---|---|
| Extract ink | Line Extraction, Colour Edges | src/SvgCreator/Imaging/ |
| Label components | Connected Components | Tracing/ComponentLabeler.cs |
| Trace contours | Contour Tracing | Tracing/ContourTracer.cs |
| Fit curves | Curve Fitting | Fitting/ |
| Recognize circles and ellipses | Shape Recognition | Fitting/EllipseFitter.cs |
| Write SVG | SVG Output | Svg/SvgWriter.cs |
| Optional stamp / postmark look | Stamp and Postmark Styles |
Svg/SvgStyle.cs, Svg/StampFilter.cs, Svg/PostmarkCancellation.cs
|
| Postage stamp (separate generator) | Postage Stamp |
PostageStampGenerator.cs, Svg/PostageStampWriter.cs
|
| Airmail envelope (separate generator) | Envelope |
EnvelopeGenerator.cs, Svg/EnvelopeWriter.cs
|
| Envelope + stamp + postmark, composed | Mail Piece |
MailPieceGenerator.cs, Composition/MailPieceComposer.cs
|
Cross-cutting topics:
- Native AOT: keeping the library trim- and AOT-safe for AWS Lambda.
- Licensing and Dependencies: why there's no Potrace and no ImageSharp.
- Tuning Guide: which option to change for which symptom.
- Debugging Techniques: how we measured instead of guessing.
- Measure before fixing. Several obvious explanations turned out to be wrong. Probing actual pixel values or filter responses found the real cause each time; see Debugging Techniques.
- Prefer evidence over prediction. For example, close gaps by following faint lines that really exist in the image (hysteresis) before inventing geometry.
-
Output is filled shapes, not strokes. Each ink region is a filled path under
fill-rule="evenodd", which keeps the original line weight. Most later choices follow from this. - Everything is O(pixels) over flat arrays. No reflection and no per-pixel allocation, which suits Native AOT and Lambda.