High-performance DXF/DWG to image renderer for .NET, built on ACadSharp and ImageSharp.
Transform CAD drawings into raster images or SVG for previews, CI/CD pipelines, web applications, documentation, and automated workflows β with zero AutoCAD dependency.
- π¨ Multi-format export β PNG, BMP, JPEG, GIF, WebP, and SVG support
- π Full CAD support β Render DXF and DWG files with ACadSharp
- πΌοΈ Customizable output β Control width, height, padding, background color, and quality
- π Space support β Model space, paper layouts, and viewports
- ποΈ SVG output β One
<g>per layer,data-*attributes and real<text>, ready for React pan/zoom viewers - ποΈ Layer visibility modes β
screenandplothonour off, frozen, non-plottable and viewport-frozen layers - π Layer filtering β Include and exclude layer lists, with
--hide-layerand--only-layerCLI options - γ°οΈ Linetypes, transparency and hatches β Dashed linetypes, entity transparency and hatch fills are rendered
- β‘ CLI tool β Cross-platform command-line interface for automation
- π§ Library API β Full .NET integration with intuitive fluent-style configuration
- π Native AOT - Publish as standalone native binaries with zero .NET runtime requirement
- π Fully documented β Complete XML IntelliSense support
dotnet add package ACadSharp.Imagedotnet tool install --global ACadSharp.Image.CliUpdate to latest version:
dotnet tool update --global ACadSharp.Image.CliRender a DWG file with custom settings:
using ACadSharp.IO;
using ACadSharp.Image;
using SixLabors.ImageSharp;
// Load CAD document
var document = DwgReader.Read("part.dwg");
// Configure and export
var exporter = new ImageExporter();
exporter.Configuration.Width = 2000;
exporter.Configuration.Height = 1400;
exporter.Configuration.SetPadding(24, 12);
exporter.Configuration.BackgroundColor = Color.Parse("#ffffff");
exporter.Configuration.OutputQuality = 90;
// Optional: hide specific layers
exporter.Configuration.HideLayer("DIMENSIONS");
exporter.Configuration.HideLayer("ANNOTATIONS");
exporter.AddModelSpace(document);
exporter.Save("./output-directory/filename.webp", ImageExportFormat.Webp);Multi-page export:
var exporter = new ImageExporter();
exporter.AddPaperLayouts(document);
exporter.Save("./output-directory/filename.png", ImageExportFormat.Png);Basic rendering:
cad-to-image "drawing.dxf" --format webp --width 1400 --height 1400 --quality 85Custom background & dimensions:
cad-to-image "part.dwg" --format png --width 1800 --height 1200 --background "#0c0c0c"Add padding around the drawing:
cad-to-image "part.dwg" --format png --padding 24
cad-to-image "part.dwg" --format png --padding 24,12
cad-to-image "part.dwg" --format png --padding 24,12,40,20Hide multiple layers:
cad-to-image "complex.dxf" --hide-layer "DIMENSIONS" --hide-layer "ANNOTATIONS" --hide-layer "BORDER"Export paper layouts:
cad-to-image "multi-sheet.dwg" --paper-layouts --output ./sheets/Render to SVG:
cad-to-image "drawing.dxf" --format svg --layer-visibility plot --only-layer "A-WALL" --only-layer "A-DOOR"List a drawing's layers:
cad-to-image "drawing.dxf" --list-layersUsage:
cad-to-image <input.dxf|input.dwg> [options]
Options:
-o, --output <path> Output file or directory path.
-f, --format <format> png, bmp, jpg, jpeg, gif, webp, svg.
-w, --width <pixels> Output width in pixels. Default: 1600.
-H, --height <pixels> Output height in pixels. Default: 900.
-p, --padding <value> Padding in pixels: <all>, <x,y>, or <left,top,right,bottom>.
-b, --background <color> Background color name or hex value. Default: white.
-q, --quality <1-100> Output quality for lossy formats. Default: 90.
--paper-layouts Export paper layouts instead of model space.
--hide-layer <name> Hide entities on the specified layer. Can be used multiple times.
--only-layer <name> Render only the specified layer(s). Can be used multiple times.
--layer-visibility <m> all (default), screen (honour off/frozen), or plot (also honour non-plottable).
--list-layers Print the drawing's layers and exit without rendering.
--svg-no-scaling-stroke Write SVG stroke widths in drawing units instead of constant pixels.
--svg-no-entity-attributes
Omit data-handle/data-type/data-parent/data-block attributes from SVG.
--svg-size Emit width/height on the SVG root from --width/--height.
--svg-id-prefix <text> Prefix for SVG ids so several drawings can share one page.
--svg-precision <0-8> Decimal places for SVG coordinates. Default: adaptive.
--help, -h, -? Show this help text.
ACadSharp.Image/
βββ ImageExporter.cs # Main public API
βββ ImageConfiguration.cs # Configuration (layers, colours, SVG options)
βββ ImagePage.cs # Page representation
βββ RenderedPage.cs # Abstract rendered output (Save to path/stream)
βββ RenderedImagePage.cs # Raster output (ImageSharp)
βββ RenderedSvgPage.cs # SVG output
βββ SvgOptions.cs # SVG-only settings
βββ LayerVisibilityMode.cs # All / Screen / Plot
βββ ImageExportFormat.cs # Png, Bmp, Jpeg, Gif, Webp, Svg
βββ ImageExportFormatExtensions.cs # Format <-> file extension helpers
βββ Rendering/
βββ IDrawingSurface.cs # Backend-neutral primitives
βββ RasterDrawingSurface.cs # ImageSharp backend
βββ Svg/
β βββ SvgDrawingSurface.cs # SVG backend
β βββ SvgIdSanitizer.cs # HTML-safe id generation
β βββ SvgNumberFormatter.cs # Coordinate formatting/precision
βββ ImagePageRenderer.cs # Page-level rendering and viewports
βββ EntityRenderDispatcher.cs # Entity routing, layer filtering, hatches
βββ EntityRenderInfo.cs # Handle/type/parent/block identity for a drawn entity
βββ EntityVisibilityFilter.cs # Include/hide lists and layer state
βββ ImageStyle.cs # Resolved colour, width, dashes, opacity for one entity
βββ ImageStyleResolver.cs # Colour, width, dashes, opacity
βββ LineTypeDashResolver.cs # Linetype to dash array
βββ SplineRenderer.cs / SplineBezierConverter.cs
βββ CurveTessellation.cs # Arc/circle/ellipse sampling for raster and off-plane entities
βββ TextRenderer.cs # Text to SurfaceText
βββ SurfacePoint.cs # Surface-space point/rect primitives
βββ SurfaceText.cs # Backend-neutral text placement
βββ ImageRenderContext.cs # Coordinate transforms
The library follows a clean architecture pattern:
- ImageExporter - Public API for adding CAD content
- ImagePage - Represents individual renderable pages
- Rendering pipeline - Transforms CAD entities to surface coordinates and draws them through a backend-neutral
IDrawingSurface, implemented by a raster (ImageSharp) and an SVG surface - Configuration - Fluent, extensible settings for customization
var exporter = new ImageExporter();
exporter.Configuration.IncludeLayers(["A-WALL", "A-DOOR"]); // render only these (optional)
exporter.Configuration.HideLayer("A-DOOR"); // then remove one of them
exporter.AddModelSpace(document);Filtering happens when rendering, so it also applies to block contents, dimension geometry and paper-space viewport contents. Entities on layer 0 inside a block take the layer of the insert that placed them, including its colour, line weight and linetype when theirs are ByLayer; ByBlock attributes resolve to the placing insert's own (colour 7 and defaults at top level). Text inside block references is placed through the insert's transform from the original entity, because ACadSharp 3.7.1 leaves TEXT alignment points and MTEXT directions untransformed when exploding. Rendering never modifies the pages, so changing filters between renders is safe.
exporter.Configuration.LayerVisibility = LayerVisibilityMode.Plot; // All (default), Screen, PlotScreen hides off and frozen layers, invisible entities and layers frozen per viewport. Plot also hides non-plottable layers such as DEFPOINTS. Hidden block attributes and the drawing's ATTMODE are honoured in the same two modes.
Lines, arcs, circles, ellipses, polylines (2D, 3D, lightweight, with bulges), splines, points, solids, 3D faces (edges, honouring invisible-edge flags), hatches (solid and pattern), TEXT, MTEXT, dimensions, block references, block attributes (ATTRIB; hidden ones follow ATTMODE under Screen/Plot; a multi-line attribute is laid out from its embedded MTEXT; an attribute belonging to an insert nested inside another block is laid out in that block's own coordinates; only top-level attributes are placed), leaders (straight and splined, with the default arrowhead or a custom arrowhead block placed at the tip; a custom arrowhead falls back to the default triangle, with a warning, when its block is empty, references itself, is degenerately sized, or sits inside a non-uniformly scaled block reference), multilines (element offsets, fill, square caps; cut segments are drawn from DXF group 41 read as absolute positions β the DXF reference reads that way, but ezdxf reads the same values as relative dash and gap lengths and no implementation settles it, so a drawing with more than one cut per element may differ from AutoCAD; fill cuts are not drawn), wipeouts (masked with the background colour; an inverted clip masks the frame minus the boundary; needs an opaque BackgroundColor; in SVG the mask stays within layer-group order) and paper-space viewports. Entities, including paper-space viewports, are drawn in the drawing's draw order (handle order overridden by DRAWORDER), so later entities paint over earlier ones (in SVG, within each layer group; layer grouping comes first). Draw order applies to the page's own entities; the contents of a block reference are drawn in the block's stored order at the first nesting level, and in handle order (not DRAWORDER) below that. A block reference whose block is missing is skipped with a warning, and so is one whose block graph references itself (directly, through a nested block, through a dimension style's arrowhead block, or through the picture block of a dimension inside it). A paper-space viewport's contents are the model-space entities whose bounds overlap or touch its view box in the XY plane, including an entity that encloses the view box or crosses it without a corner inside it.
Dashed linetypes are rendered using LTSCALE, the entity linetype scale and PSLTSCALE (honoured from the raw $PSLTSCALE header value) in paper space; patterns shorter than MinimumDashPixels are drawn solid (pixel-width modes only; not applied in SVG drawing-unit mode), and embedded shapes and text in a linetype render as gaps. Entity transparency becomes opacity (ByLayer is treated as opaque because the ACadSharp layer table carries no transparency). Colour index 7 resolves to black or white from the background luminance, or to ForegroundColor when set.
exporter.Configuration.Svg.NonScalingStroke = true; // constant on-screen stroke width when zooming (default)
exporter.Configuration.Svg.IdPrefix = "plan1-"; // when inlining several drawings in one page
exporter.Save("plan.svg", ImageExportFormat.Svg);The SVG has a drawing-unit viewBox, no width/height unless Svg.EmitSize is set, an attribute-free <g class="cad-root"> for your pan/zoom transform, and one <g data-layer="..."> per layer. Every element carries data-handle and data-type (plus data-parent/data-block for block contents); data-handle is omitted for exploded block contents, since they are transient clones with no handle of their own. In React, prefer injecting the markup at runtime or configure SVGO to keep ids; data-* attributes survive the default SVGR pipeline. Toggle a layer with CSS display: none on its group.
SVG and PNG are built from the same geometry and never disagree on it, but they intentionally differ in fidelity: SVG keeps native arcs, Beziers and <text>, while raster output tessellates curves and outlines glyphs. SVG text is sized and wrapped to match the PNG output; glyph shapes still depend on the viewer's fonts. Repeated spaces inside text are preserved in both outputs. ImageConfiguration.Dpi affects only line weights; text is sized from the drawing on both backends. Entities with a non-world extrusion normal (an OCS other than the default) are brought into world coordinates first: arcs, circles and ellipses through ACadSharp's own tessellation, polylines, hatches and solids through the renderer's OCS transform. Single-line TEXT on another plane is placed on the mirrored extent with readable glyphs; AutoCAD would draw the glyphs themselves mirrored, so this is a deliberate readability choice, not a parity guarantee. Text height follows the transformed up axis and width the transformed reading axis of whatever places the text, block reference or OCS plane. MTEXT and dimension geometry are already world coordinates in DXF; MTEXT is placed through the same projection (its height likewise follows the projected up-axis length) and dimensions need no transform. The available Svg options are NonScalingStroke, EmitEntityAttributes, EmitSize, IdPrefix, and Precision.
Thread safety: Rendering temporarily mutates block MLINEs and LEADERs while working around ACadSharp 3.7.1's destructive MLine.Clone() and Leader.Clone() and restores them before returning; a CadDocument must not be rendered concurrently by two exporters, and Insert.Explode() itself is not safe for concurrent use either.
Override default line weight values:
exporter.Configuration.SetLineWeight(LineWeightType.W25, 0.30);
exporter.Configuration.LineWeightScale = 1.5f; // Scale all weightsCustomize text rendering:
exporter.Configuration.FontFamilyName = "Consolas";
exporter.Configuration.ArcPrecision = 512; // Higher = smoother arcs- .NET 8.0 SDK or later
- Any IDE with C# support (VS 2022, VS Code, Rider)
# Clone and build
git clone https://github.com/slaveoftime/ACadSharp.Image.git
cd ACadSharp.Image
dotnet restore
dotnet build
dotnet format --verify-no-changes
# Run tests
dotnet testUse the repeatable sample-render benchmark script:
powershell -ExecutionPolicy Bypass -File .\artifacts\measure-render.ps1
powershell -ExecutionPolicy Bypass -File .\artifacts\measure-render.ps1 -Iterations 10dotnet run --project ./ACadSharp.Image.Cli/ACadSharp.Image.Cli.csproj -- "./Samples/6-57-1119.dxf" --width 300 --height 200 --hide-layer OPTIONAL_DIMENSIONS
dotnet run --project ./ACadSharp.Image.Cli/ACadSharp.Image.Cli.csproj -- "./Samples/HSK80AHCP16190M_BMG.dwg" --format webp --width 1200 --height 760
dotnet run --project ./ACadSharp.Image.Cli/ACadSharp.Image.Cli.csproj -- "./Samples/Subaru Logo Vector Free Wrap.dxf" --format webp --width 1200 --height 700 --background "#a0a7ae"
dotnet run --project ./ACadSharp.Image.Cli/ACadSharp.Image.Cli.csproj -- "./Samples/6-57-1119.dxf" --format svg --layer-visibility plotdotnet pack ./ACadSharp.Image/ACadSharp.Image.csproj -c Release
dotnet pack ./ACadSharp.Image.Cli/ACadSharp.Image.Cli.csproj -c Release
dotnet tool install -g --add-source ./ACadSharp.Image.Cli/bin/Release ACadSharp.Image.CliZero-dependency standalone executables:
# Windows x64
dotnet publish ./ACadSharp.Image.Cli/ -c Release -r win-x64 --self-contained -p:PublishAot=true
# Linux x64
dotnet publish ./ACadSharp.Image.Cli/ -c Release -r linux-x64 --self-contained -p:PublishAot=true
# macOS ARM64
dotnet publish ./ACadSharp.Image.Cli/ -c Release -r osx-arm64 --self-contained -p:PublishAot=trueContributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is released under the MIT License.
If you find this project helpful, please consider giving it a βοΈ on GitHub! It helps others discover the project.
Questions or issues? Open an issue or start a Discussion.
