ACadSharp.Image.Cli 0.1.5

dotnet tool install --global ACadSharp.Image.Cli --version 0.1.5
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local ACadSharp.Image.Cli --version 0.1.5
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=ACadSharp.Image.Cli&version=0.1.5
                    
nuke :add-package ACadSharp.Image.Cli --version 0.1.5
                    

ACadSharp.Image

NuGet downloads License: MIT .NET CI

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.

Rendered sample


✨ Features

  • 🎨 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 modesscreen and plot honour off, frozen, non-plottable and viewport-frozen layers
  • 🎭 Layer filtering — Include and exclude layer lists, with --hide-layer and --only-layer CLI 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

📦 Installation

NuGet Package

dotnet add package ACadSharp.Image

CLI as Global Tool

dotnet tool install --global ACadSharp.Image.Cli

Update to latest version:

dotnet tool update --global ACadSharp.Image.Cli

🚀 Quick Start

Library Usage

Render 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);

CLI Usage

Basic rendering:

cad-to-image "drawing.dxf" --format webp --width 1400 --height 1400 --quality 85

Custom 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,20

Hide 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-layers

📖 CLI Reference

Usage:
  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.

🏗️ Architecture

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

💡 Advanced Usage

Layer selection

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.

Layer visibility

exporter.Configuration.LayerVisibility = LayerVisibilityMode.Plot; // All (default), Screen, Plot

Screen 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.

Supported entities

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.

Linetypes, transparency and colour 7

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.

SVG output

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.

Custom Line Weights

Override default line weight values:

exporter.Configuration.SetLineWeight(LineWeightType.W25, 0.30);
exporter.Configuration.LineWeightScale = 1.5f; // Scale all weights

Text & Font Configuration

Customize text rendering:

exporter.Configuration.FontFamilyName = "Consolas";
exporter.Configuration.ArcPrecision = 512; // Higher = smoother arcs

🛠️ Development

Prerequisites

  • .NET 8.0 SDK or later
  • Any IDE with C# support (VS 2022, VS Code, Rider)

Build & Test

# 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 test

Measure Render Performance

Use the repeatable sample-render benchmark script:

powershell -ExecutionPolicy Bypass -File .\artifacts\measure-render.ps1
powershell -ExecutionPolicy Bypass -File .\artifacts\measure-render.ps1 -Iterations 10

Run Examples

dotnet 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 plot

Build NuGet Package

dotnet 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.Cli

Publish Native Binary (AOT)

Zero-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=true

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📄 License

This project is released under the MIT License.


🌟 Support

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.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
0.1.5 60 9/11/2026
0.1.4 99 9/7/2026
0.1.3 112 8/26/2026
0.1.2 180 4/29/2026
0.1.1 125 4/24/2026
0.1.0 124 4/7/2026
0.0.4 127 4/7/2026