OfficeIMO.Drawing 3.0.0

Prefix Reserved
dotnet add package OfficeIMO.Drawing --version 3.0.0
                    
NuGet\Install-Package OfficeIMO.Drawing -Version 3.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="OfficeIMO.Drawing" Version="3.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OfficeIMO.Drawing" Version="3.0.0" />
                    
Directory.Packages.props
<PackageReference Include="OfficeIMO.Drawing" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add OfficeIMO.Drawing --version 3.0.0
                    
#r "nuget: OfficeIMO.Drawing, 3.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package OfficeIMO.Drawing@3.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=OfficeIMO.Drawing&version=3.0.0
                    
Install as a Cake Addin
#tool nuget:?package=OfficeIMO.Drawing&version=3.0.0
                    
Install as a Cake Tool

OfficeIMO.Drawing - shared document and drawing primitives

nuget version nuget downloads

OfficeIMO.Drawing is the zero-dependency shared foundation for OfficeIMO packages. It owns common document lifecycle contracts plus color conversion, image metadata, font and text measurement, vector scenes, reusable ink and math models, chart snapshots, SVG, raster canvases, PNG/JPEG/TIFF/WebP encoding, and drawing-quality primitives. Format packages keep their file-format behavior while reusing these document-agnostic models and renderers.

Install

dotnet add package OfficeIMO.Drawing

Quick start

Document lifecycle policy

using OfficeIMO.Drawing;

var loadOptions = new DocumentLoadOptions {
    AccessMode = DocumentAccessMode.ReadOnly,
    PersistenceMode = DocumentPersistenceMode.Explicit
};

Word, Excel, and PowerPoint expose format-specific options derived from these shared contracts.

Colors and vector intent

using OfficeIMO.Drawing;

OfficeColor accent = OfficeColor.Parse("#336699");
OfficeColor printBlue = OfficeColorSpaceConverter.FromCmyk(1, 0.45, 0, 0.15);
OfficeImageFit fit = OfficeImageFit.Contain;

var badge = OfficeShape.RoundedRectangle(120, 32, 8);
badge.FillColor = OfficeColor.WhiteSmoke;
badge.StrokeColor = accent;
badge.Shadow = new OfficeShadow(OfficeColor.Black, 0.18, 3, 4);

Image metadata without decoding pixels

using OfficeIMO.Drawing;

OfficeImageInfo info = OfficeImageReader.Identify("logo.png");
Console.WriteLine($"{info.Width}x{info.Height} {info.MimeType}");

// Use content verification when an extension must not identify invalid bytes.
byte[] bytes = File.ReadAllBytes("upload.svg");
bool verified = OfficeImageReader.TryIdentifyByContent(bytes, "upload.svg", out OfficeImageInfo upload);

OfficeImageFit fit = OfficeImageFit.Contain;

TryIdentify(...) retains the metadata reader's extension fallback. TryIdentifyByContent(...) may use a file name to select the SVG parser, but succeeds only when the bytes match a supported format.

Encode common raster formats

using OfficeIMO.Drawing;

var image = new OfficeRasterImage(320, 180, OfficeColor.White);
var options = new OfficeRasterEncodingOptions {
    Jpeg = new OfficeJpegEncodeOptions { Quality = 90 },
    Tiff = new OfficeTiffEncodeOptions { Compression = OfficeTiffCompression.PackBits }
};

byte[] jpeg = OfficeRasterImageEncoder.Encode(image, OfficeImageExportFormat.Jpeg, options);
byte[] tiff = OfficeRasterImageEncoder.Encode(image, OfficeImageExportFormat.Tiff, options);
byte[] webp = OfficeRasterImageEncoder.Encode(image, OfficeImageExportFormat.Webp, options);

WebP output is deterministic, lossless VP8L. TIFF output is a single-page baseline RGBA image with uncompressed or PackBits strips. JPEG uses the existing managed quality, subsampling, progressive, metadata, and transparency-flattening settings.

OfficeRasterExportPlanner is the shared pre-allocation owner for image export. It combines the caller's MaximumRasterPixels with renderer and encoder dimension/pixel limits, then either reduces scale with IMAGE_RASTER_SCALE_REDUCED or throws OfficeImageExportLimitException, according to RasterOverflowBehavior. The returned plan also owns the effective encoding settings: CreateEncodingOptions() reduces encoded density with the raster scale so safety limits preserve the document's physical size. Explicit top-level DpiX/DpiY values apply across formats; when those values are not assigned, format-specific PNG, JPEG, and TIFF density remains authoritative. Drawing's managed PNG, JPEG, baseline chunky RGB/RGBA TIFF, uncompressed BMP, first-frame GIF, and OfficeIMO literal-lossless WebP decoders enforce encoded-payload and source-pixel guards; the TIFF and WebP readers intentionally reject variants outside those bounded profiles. OfficeRasterImageFallbackCodec can wrap an application codec at the final raster boundary. It reports IMAGE_SOURCE_DECODED_BY_CALLER_CODEC when that codec succeeds; if neither Drawing nor the application can decode a source image, it returns a visible placeholder and IMAGE_SOURCE_DECODE_FALLBACK instead of allowing the renderer to omit the image silently.

Deterministic text measurement

using OfficeIMO.Drawing;

var measurer = OfficeTextMeasurer.Create();
var style = measurer.CreateStyle(new OfficeFontInfo("Aptos", 11, OfficeFontStyle.Regular));
OfficeTextMetrics metrics = measurer.Measure("Quarterly report", style);

if (metrics.WidthPixels > 240) {
    Console.WriteLine("The label needs wrapping or a smaller font.");
}

Reusable ink

using OfficeIMO.Drawing;

var stroke = new OfficeInkStroke {
    Color = OfficeColor.Crimson,
    Width = 2.2,
    Height = 2.2,
    Bias = OfficeInkBias.Handwriting,
    RecognizedText = "hello"
};
stroke.AddPoint(8, 30, 0.35)
      .AddPoint(60, 12, 1.0)
      .AddPoint(120, 36, 0.55);

var ink = new OfficeInkDocument().Add(stroke);
OfficeDrawing inkDrawing = OfficeInkRenderer.Render(ink, width: 140, height: 60);

The model keeps sampled geometry, normalized pressure, pen dimensions and tip shape, transforms, handwriting/drawing bias, language, and recognition alternatives. A format adapter decides how those values map to native storage.

Structured math

using OfficeIMO.Drawing;

OfficeMathExpression expression = OfficeMath.Fraction(
    OfficeMath.Row(
        OfficeMath.Identifier("x"),
        OfficeMath.Operator("+"),
        OfficeMath.Number("1")),
    OfficeMath.Radical(OfficeMath.Identifier("y")));

string mathMl = OfficeMathMarkup.ToMathMl(expression);
string latex = OfficeMathMarkup.ToLatex(expression);
OfficeDrawing mathDrawing = OfficeMathRenderer.Render(expression);

The same immutable expression tree feeds native OneNote math and Word OMML adapters. The shared model includes right and left scripts, centered upper/lower limits, built-up and slashed fractions, delimiter lists, stacks, matrices, equation arrays, n-ary operators, accents, bars, boxes, and phantoms. OneNote maps all of those structures natively. Word maps the lossless OMML subset; Stack and StretchStack fail with NotSupportedException because OMML has no equivalent, and callers can choose EquationArray explicitly when that projection is intended. Drawing owns the AST, portable markup, measurement, and visual layout; each document package owns only its native codec. MathML and LaTeX parsing default to a nesting limit of 128 and expose bounded overloads; excessive nesting fails with OfficeMathParseException.Code == "DRAWING_MATH_DEPTH".

Examples

Build a reusable vector scene

using OfficeIMO.Drawing;

var drawing = new OfficeDrawing(width: 420, height: 180)
    .AddShape(new OfficeShape {
        Kind = OfficeShapeKind.Rectangle,
        Width = 420,
        Height = 180,
        FillGradient = OfficeLinearGradient.Horizontal(
            OfficeColor.Parse("#F8FBFF"),
            OfficeColor.Parse("#EAF4FF")),
        StrokeColor = OfficeColor.Parse("#B7D7F5"),
        StrokeWidth = 1
    }, x: 0, y: 0)
    .AddText("OfficeIMO.Drawing", 20, 18, 380, 32,
        new OfficeFontInfo("Aptos", 18, OfficeFontStyle.Bold),
        OfficeColor.Parse("#1F2937"),
        OfficeTextAlignment.Left)
    .AddShape(OfficeShape.RoundedRectangle(140, 44, 10), 20, 86)
    .AddText("Shared vector intent", 34, 98, 240, 24);

OfficeDrawingQualityReport report = OfficeDrawingQualityAnalyzer.Analyze(drawing);
if (report.HasIssues) {
    foreach (var issue in report.Issues) {
        Console.WriteLine($"{issue.Kind}: {issue.Message}");
    }
}

Render a chart snapshot to drawing primitives

using OfficeIMO.Drawing;

var snapshot = new OfficeChartSnapshot(
    name: "RevenueChart",
    title: "Revenue by quarter",
    chartKind: OfficeChartKind.ColumnClustered,
    data: new OfficeChartData(
        new[] { "Q1", "Q2", "Q3", "Q4" },
        new[] {
            new OfficeChartSeries("Revenue", new[] { 10d, 18d, 24d, 30d }),
            new OfficeChartSeries("Forecast", new[] { 12d, 19d, 25d, 33d })
        }),
    widthPoints: 420,
    heightPoints: 260);

OfficeChartRenderingResult rendered = OfficeChartDrawingRenderer.RenderWithQuality(snapshot);
OfficeDrawing chartDrawing = rendered.Drawing;

foreach (var issue in rendered.QualityReport.Issues) {
    Console.WriteLine(issue.Message);
}

Read TrueType outlines for renderers

using OfficeIMO.Drawing;

OfficeTrueTypeFont? font = OfficeTrueTypeFont.TryLoadDefault(out string? path);
if (font != null) {
    Console.WriteLine($"Loaded {path}");
}

What it provides

  • DocumentAccessMode, DocumentPersistenceMode, DocumentCreateOptions, and DocumentLoadOptions for one lifecycle vocabulary across document packages.
  • OfficeColor immutable RGBA values with named colors and hex parsing.
  • OfficeColorSpaceConverter for dependency-free CMYK, CIE Lab/XYZ, calibrated gray, and calibrated RGB conversion to sRGB.
  • OfficeImageReader and OfficeImageInfo for dependency-free image inspection where supported.
  • OfficeImageFit for shared stretch, contain, and cover intent.
  • OfficeFontInfo, OfficeFontStyle, OfficeTextMeasurer, and OfficeTextMetrics for deterministic layout estimates.
  • OfficeTrueTypeFont for dependency-free font-outline reading when renderers need glyph contours.
  • OfficeInkDocument, OfficeInkStroke, sampled pressure/style metadata, recognition alternatives, and OfficeInkRenderer for reusable ink capture and projection.
  • OfficeMathExpression, OfficeMath, MathML/LaTeX conversion, deterministic measurement, and OfficeMathRenderer for reusable structured equations.
  • OfficeShape, OfficeDrawing, gradients, shadows, transforms, clipping, and vector descriptors that format-specific packages can map into their own coordinate systems.
  • OfficeChartSnapshot and chart rendering primitives shared by PDF and Office exporters.
  • OfficeRasterImage, OfficeRasterCanvas, OfficeRasterRenderTarget, and OfficeDrawingRasterRenderer for shared dependency-free raster rendering.
  • OfficePngReader, OfficePngWriter, and OfficeJpegCodec for PNG/JPEG paths that should not be reimplemented by document packages.
  • OfficeTiffCodec, OfficeWebpCodec, and OfficeRasterImageEncoder for shared baseline TIFF, lossless WebP, and format-neutral raster output.
  • Shared SVG formatting, primitive writing, image projection, text-block rendering, hatch-pattern, data-bar, and sparkline helpers.
  • Drawing quality diagnostics for canvas bounds and text overlap checks.

Boundaries

  • This package owns shared lifecycle contracts, persistence mechanics, drawing intent, ink/math models and renderers, raster buffers, SVG and raster encoding primitives, image projection, text layout helpers, chart drawing, and document-agnostic visual diagnostics.
  • Word, Excel, PowerPoint, Visio, and PDF packages own source-document semantics: package parsing, layout policy, coordinate systems, style/theme resolution, and user-facing export APIs.
  • Document packages should not add private ink or math ASTs, pixel engines, image encoders/decoders, SVG primitive writers, text wrapping engines, or duplicate image-transform loops when the behavior can reasonably live here.
  • PDF keeps PDF-stream and page-writer behavior in OfficeIMO.Pdf; when it needs generic image-like drawing, vector descriptors, colors, chart snapshots, PNG helpers, or raster visual QA, it should use OfficeIMO.Drawing.
  • Unsupported or approximate source features belong in stable diagnostics from the adapter, not as silent omissions in a renderer.

Targets and license

Dependency footprint

  • External: None.
  • OfficeIMO: This is the shared foundation; it does not depend on another OfficeIMO runtime package.

See the complete OfficeIMO package map for related formats and conversion paths.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 is compatible.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETFramework 4.7.2

    • No dependencies.
  • .NETStandard 2.0

    • No dependencies.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages (41)

Showing the top 5 NuGet packages that depend on OfficeIMO.Drawing:

Package Downloads
OfficeIMO.Word

An Open Source cross-platform .NET library providing an easy way to create Microsoft Word (DocX) documents.

OfficeIMO.Markdown

Markdown builder, typed reader/AST, and HTML renderer for .NET with GitHub-like output and an optional portable reader profile.

OfficeIMO.Excel

An Open Source cross-platform .NET library providing an easy way to create Excel documents.

OfficeIMO.PowerPoint

An Open Source cross-platform .NET library for creating, reading, editing, and writing Microsoft PowerPoint PPTX/PPTM and PPT/POT/PPS presentations.

OfficeIMO.Pdf

First-party PDF builder, reader, editor, renderer, and signature workflow for .NET.

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on OfficeIMO.Drawing:

Repository Stars
EvotecIT/PSWriteOffice
PowerShell Module to create and edit Microsoft Word, Microsoft Excel, and Microsoft PowerPoint documents without having Microsoft Office installed.
Version Downloads Last Updated
3.0.0 2,851 7/20/2026
2.0.1 3,999 7/14/2026
2.0.0 2,110 7/14/2026
1.0.29 2,143 7/9/2026
1.0.28 1,487 7/8/2026
1.0.27 1,732 7/5/2026
1.0.26 1,399 7/4/2026
1.0.25 1,833 6/27/2026
1.0.24 1,152 6/27/2026
1.0.23 1,670 6/24/2026
1.0.22 1,434 6/23/2026
1.0.21 1,362 6/21/2026
1.0.20 1,630 6/16/2026
1.0.19 1,340 6/16/2026
1.0.18 2,116 6/15/2026
1.0.17 2,241 6/13/2026
1.0.16 1,055 6/12/2026
1.0.15 1,091 6/9/2026
1.0.14 1,174 6/5/2026
1.0.13 9,797 5/27/2026
Loading failed