This report demonstrates every image method in the library. All SVG is generated inline — no external files or image-processing libraries are required for the SVG sections.
The most efficient way to embed vector graphics. The SVG markup is written directly into the HTML — no encoding overhead, fully self-contained, and scales perfectly at every zoom level.
The same SVG constrained to different widths via the optional maxWidthPercent parameter:
All image methods accept an optional alignment parameter. Here the same SVG badge is placed at each of the three positions:
Pass a caption string to any image method to wrap the image in a semantic HTML5 <figure>/<figcaption> element:
When you have image data as a byte array or Stream — for example from a cross-platform image library — use these overloads. The image is base64-encoded into the HTML, keeping the report self-contained.
This library has zero dependencies and does not ship an image-processing package. To produce bitmap data from code, use one of these cross-platform libraries:
// ── SkiaSharp (recommended cross-platform) ──────────────────────────────
// NuGet: SkiaSharp
using SkiaSharp;
using var surface = SKSurface.Create(new SKImageInfo(400, 200));
var canvas = surface.Canvas;
canvas.Clear(SKColors.White);
// ... draw on canvas ...
using var image = surface.Snapshot();
using var data = image.Encode(SKEncodedImageFormat.Png, 100);
// Option A — byte array
report.AddImage(data.ToArray(), "image/png", "My chart");
// Option B — stream (avoids the extra byte[] allocation)
using var stream = data.AsStream();
report.AddImage(stream, "image/png", "My chart");
// ── SixLabors.ImageSharp (cross-platform) ──────────────────────────────
// NuGet: SixLabors.ImageSharp
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
using var img = new Image<Rgba32>(400, 200);
// ... draw on img ...
using var ms = new MemoryStream();
img.Save(ms, new PngEncoder());
ms.Position = 0;
report.AddImage(ms, "image/png", caption: "Figure 1");
// ── System.Drawing.Bitmap (Windows only) ───────────────────────────────
// Note: System.Drawing.Common is Windows-only on .NET 6+.
// Throws PlatformNotSupportedException on macOS and Linux.
using var bmp = new System.Drawing.Bitmap(400, 200);
// ... draw on bmp ...
using var ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
report.AddImage(ms.ToArray(), "image/png");
The ConsoleTest project references SkiaSharp (NuGet: SkiaSharp 3.x). The three images below are produced by the private helper methods in this class — they load the sample PNG from disk and apply real pixel operations.
The original file is decoded into an SKBitmap, then re-encoded to PNG bytes and embedded via AddImage(byte[]):
using var bitmap = SKBitmap.Decode(sampleImagePath);
using var image = SKImage.FromBitmap(bitmap);
using var data = image.Encode(SKEncodedImageFormat.Png, quality: 90);
report.AddImage(data.ToArray(), "image/png", alt: "My image");
The image is scaled down to 280 px wide using Mitchell cubic resampling, then embedded at 35% of the report width:
using var original = SKBitmap.Decode(sampleImagePath);
int targetWidth = 280;
int targetHeight = (int)((float)original.Height / original.Width * targetWidth);
using var resized = original.Resize(
new SKImageInfo(targetWidth, targetHeight),
new SKSamplingOptions(SKCubicResampler.Mitchell));
using var image = SKImage.FromBitmap(resized!);
using var data = image.Encode(SKEncodedImageFormat.Png, 90);
report.AddImage(data.ToArray(), "image/png",
maxWidthPercent: 35, alignment: ImageAlignment.Left);
An SKSurface is created at the original dimensions, the bitmap is drawn onto it, then a diagonal semi-transparent "DRAFT" text is composited using SKCanvas:
using var bitmap = SKBitmap.Decode(sampleImagePath);
using var surface = SKSurface.Create(new SKImageInfo(bitmap.Width, bitmap.Height));
var canvas = surface.Canvas;
canvas.DrawBitmap(bitmap, 0, 0);
using var font = new SKFont(SKTypeface.Default, size: 72);
using var paint = new SKPaint { Color = new SKColor(200, 30, 30, 140), IsAntialias = true };
float textWidth = font.MeasureText("DRAFT");
canvas.Save();
canvas.Translate(bitmap.Width / 2f, bitmap.Height / 2f);
canvas.RotateDegrees(-35);
canvas.DrawText("DRAFT", -textWidth / 2f, font.Size / 3f, font, paint);
canvas.Restore();
using var image = surface.Snapshot();
using var data = image.Encode(SKEncodedImageFormat.Png, 90);
report.AddImage(data.ToArray(), "image/png");
Instead of embedding image data, this overload emits a standard <img src="url"> tag. The report file stays small, but the image is only visible when the viewer has network access.
// Suitable for: intranet dashboards, stable CDN assets, live reports.
// Not suitable for: email attachments, fully offline reports.
report.AddImageFromUrl(
"https://example.com/company-logo.png",
alt: "Company logo",
maxWidthPercent: 30,
alignment: ImageAlignment.Left,
caption: "Our logo");
Images work inside BeginColumns/EndColumns for side-by-side comparisons: