zplCore.comzplCore.com

02ZplRenderer

ZplRenderer processes ZPL strings, byte arrays (code page 850 as on the printer, or UTF-8 with BOM) and files. Each printed label produces one encoded image – for PDF, one document with one page per label.

Settings (ZplRenderSettings)

var settings = new ZplRenderSettings
{
    Dpi = 300,                                   // 152, 203, 300 or 600
    OutputFormat = ZplOutputFormat.Webp,         // Png, Jpeg, Webp, Bmp, Pdf, Grf
    Quality = 90,                                // JPEG/WebP
    AntiAlias = false,                           // pure 1-bit like a thermal printer
    InkColor = new SKColor(0x1d, 0x3b, 0x8a),    // ribbon
    BackgroundColor = SKColors.LightYellow,      // label stock
    OutputRotation = ZplRotation.Rotate90,
    TraceElements = true,                        // collect the positions of all fields
    Clock = () => new DateTime(2026, 10, 18),    // deterministic ^FC fields
}.WithLabelSizeInches(4, 6);

string json = settings.ToJson();                 // save ...
var restored = ZplRenderSettings.FromJson(json); // ... and load
PropertyDefaultMeaning
Dpi203Print resolution 152/203/300/600
LabelWidth / LabelHeight4×6 inchesin dots; overridden by ^PW/^LL unless ForceLabelWidth/Height
InkColor / BackgroundColorBlack / WhiteRibbon and paper color
OutputFormat / QualityPng / 95Png, Jpeg, Webp, Bmp, Pdf, Grf
OutputRotationNoneRotate output by 90/180/270°
AntiAlias / InvertColorstrue / falseSmoothing or negative
BackgroundImage / WatermarkImage + WatermarkOpacity– / 0.25Pre-print below or watermark above the content
RfidIndicator + RfidIndicatorColor / RfidIndicatorOpacityWatermark / #C0C0C0 / 1gray RFID symbol behind the content on labels with ^RF/^WT/^WF/^RQ (preview formats only, see ^RF)
ThumbnailSize0Downscale output to max. N pixels
RenderOutputIndexesnullencode only selected labels
DefaultCodePage850Field encoding without ^CI
TraceElementsfalseCollect position/content of each field (editors, tests)
ClockDateTime.NowClock for ^FC
DrawRfidfalseDraw ^RF data visibly
PdfTitle/Author/Subject/Keywords/Creator–PDF metadata
PaperWidth/PaperHeight/PaperMargin/LabelGap0PDF sheet layout: multiple labels per page
using var watermark = SKBitmap.Decode("muster.png");
var renderer = new ZplRenderer(new ZplRenderSettings
{
    WatermarkImage = watermark,
    WatermarkOpacity = 0.35f,
    ThumbnailSize = 200,              // scale output down to max. 200 px
    RenderOutputIndexes = [0, 2],     // encode only labels 1 and 3
    DrawRfid = true,                  // draw ^RF data as a box
});

// PDF: metadata + several labels per sheet (A4 @ 203 dpi)
var pdf = new ZplRenderer(new ZplRenderSettings
{
    OutputFormat = ZplOutputFormat.Pdf,
    PdfTitle = "Lieferung 42", PdfAuthor = "Lager", PdfSubject = "Versand", PdfKeywords = "zpl",
    PaperWidth = 1680, PaperHeight = 2376, PaperMargin = 40, LabelGap = 16,
}.WithLabelSizeMm(100, 50));
byte[] sheet = pdf.ProcessCommands(zpl)[0];

Watermark

WatermarkImage with opacity 0.35

Visible RFID (DrawRfid)

^RF data with DrawRfid = true

More on zplCloud.com: Guide: Label size and media (^PW, ^LL)

Output formats & bitmaps

PNG · JPEG · WebP · BMP

One image per label. BMP as 24-bit (own encoder).

PDF

One document, one page per label at physical size – or a sheet layout. Sample PDF

GRF

The rendered label as a single ^GFA in ^XA…^XZ – for printers without matching fonts.

TIFF · PCX

Tiff: all labels in one multi-page 1-bit TIFF (TiffCompression); Pcx: one 1-bit PCX per label.

PCL · EPL · Fingerprint

The raster image as a PCL 5 page (laser printers), EPL2 GW graphic or Intermec Fingerprint – output ZPL on third-party printers.

ESC/POS

Raster image for receipt printers, including cut.

var renderer = new ZplRenderer(new ZplRenderSettings { OutputFormat = ZplOutputFormat.Tiff }.WithLabelSizeMm(100, 60));
byte[] tiff = renderer.ProcessCommands(zpl)[0];         // ONE multi-page 1-bit TIFF

foreach (var format in new[] { ZplOutputFormat.Pcx, ZplOutputFormat.Pcl, ZplOutputFormat.Epl,
                               ZplOutputFormat.Fingerprint, ZplOutputFormat.EscPos })
{
    renderer.Settings.OutputFormat = format;            // one byte array per label
    List<byte[]> outputs = renderer.ProcessCommands(zpl);
}

// background (e.g. a preprinted form) and watermark from file, data: URI or Base64;
// URLs only asynchronously (size-limited): ZplRenderSettings.LoadImageFromUrlAsync(new Uri("https://…"))
var preview = new ZplRenderSettings()
    .WithBackgroundImage("formular.png")
    .WithWatermarkImage("muster.png", opacity: 0.3f);
SKBitmap logo = ZplRenderSettings.LoadImage("data:image/png;base64,iVBORw0KGgo…");
var renderer = new ZplRenderer(new ZplRenderSettings { TraceElements = true });
foreach (ZplRenderResult result in renderer.Render(zpl))
{
    using SKBitmap bmp = result.Bitmap;              // caller owns the bitmaps
    foreach (var e in result.Elements)
        Console.WriteLine($"{e.Command} @ {e.X},{e.Y} {e.Width}x{e.Height}: {e.Content}");
    File.WriteAllText("label.grf.zpl", ZplExport.ToGrfZpl(bmp));  // as ^GFA graphic
}

Try it online on zplCloud.com: ZPL to PDF · ZPL to PNG · ZPL to JPG · ZPL to SVG

Background & watermark from file, URL or Base64

ZplRenderSettings.LoadImage(source) loads images from a file path, http(s) URL, data: URI or plain Base64. WithBackgroundImage places an image (e.g. a scanned pre-printed form) beneath the label, WithWatermarkImage one above it – see the code above and the watermark example.

Events, status queries & ~WC

Commands without visual effect (media, darkness, calibration, ~HS …) raise PrinterControl; replies to host queries end up in Responses. LabelRendered fires after each encoded label. ~WC prints a configuration label.

var renderer = new ZplRenderer();
renderer.PrinterControl += (_, e) =>
{
    Console.WriteLine($"Steuerbefehl {e.Command.Prefix}{e.Command.Name} {e.Command.Parameters}");
    // e.Response is prefilled for ~HS and can be overridden
};
renderer.LabelRendered += (_, e) =>
    File.WriteAllBytes($"label{e.Index + 1}.png", e.Data);

renderer.ProcessCommands("~SD25^XA^MD10^FO50,50^GB100,100,4^FS^XZ~HS");
var status = ZplPrinterStatus.Parse(renderer.Responses[0]);
Console.WriteLine(status.IsReady ? "bereit" : "Fehler");

~WC configuration label

~WC configuration label – rendered with zplCore.com

Stored formats

Formats (^DF/^XF), graphics (~DG, ~DY, ^IS) and fonts live in renderer.Store (ZplResourceStore), which can also be shared between multiple renderers (new ZplRenderer { Store = shared }).

Printer memory: ^DF / ^XF, ^IS / ^IL

var renderer = new ZplRenderer();

// ^DF stores a format in printer memory, ^XF recalls it, ^FN fills the fields
renderer.ProcessCommands("^XA^DFR:ADR.ZPL^FS^FO50,50^A0N,40,40^FN1^FS^FO50,110^A0N,30,30^FN2^FS^XZ");
var labels = renderer.ProcessCommands(
    "^XA^XFR:ADR.ZPL^FN1^FDMax Mustermann^FS^FN2^FDGraz^FS^XZ" +
    "^XA^XFR:ADR.ZPL^FN1^FDErika Muster^FS^FN2^FDWien^FS^XZ");

// memory persists between calls – like a real printer
Console.WriteLine(string.Join(", ", renderer.Store.Formats));
renderer.Store.AddGraphic("R:LOGO.GRF", SKBitmap.Decode("logo.png"), dither: true);
renderer.Reset();                      // Power-on-Reset (~JR)
^XA^FO10,10^GB300,80,3^FS^FO30,30^A0N,40,40^FDFormular^FS
^ISR:FORM.GRF^XZ                 ← save label as image (and print)
^XA^ILR:FORM.GRF                 ← load image as background
^FO30,120^A0N,30,30^FDVariable Daten^FS^XZ

More on zplCloud.com: Guide: ^DF · Guide: ^XF

Filling ^FN fields: FieldValues

ZplRenderSettings.FieldValues (IReadOnlyDictionary<int, string>) sets the data of every field with that ^FN number – in plain labels and in formats recalled with ^XF, for all labels and ^PQ copies of one call. The value wins over a ^FD default and over the ^XF data block; ^FH, ^FC and ^SN/^SF still apply. Keys without a matching ^FN are reported as diagnostic ZPL1301 (ZplDiagnosticCodes.InvalidFieldValueKey, INVALID_FIELD_VALUE_KEY) on the first label. ZplFields.Find lists the fields with prompt (^FN1"Name") and default value, ZplFields.Fill returns the filled ZPL. CLI: zplcore render label.zpl --field 1=ACME --field 2=Vienna.

Try it online on zplCloud.com: ZPL Template Filler

More on zplCloud.com: Guide: ^FN

// Fill ^FN fields without ^DF/^XF: test data for previews or ERP templates
const string template = "^XA^FO50,50^A0N,40,40^FN1\"Name\"^FDMuster^FS^FO50,110^A0N,30,30^FN2\"Ort\"^FS^XZ";
var renderer = new ZplRenderer(new ZplRenderSettings
{
    FieldValues = new Dictionary<int, string> { [1] = "Erika Muster", [2] = "Wien" },
});
var png = renderer.ProcessCommands(template);      // applies to all labels, also in ^XF formats

// List the fields for a form (number, prompt, default value)
foreach (var f in ZplFields.Find(template))
    Console.WriteLine($"^FN{f.Number} {f.Prompt}: {f.Value}");

// ZPL with the values filled in (^DF/^XF merged into plain labels)
string filled = ZplFields.Fill(template, renderer.Settings.FieldValues!);

Serial numbers, clock, ^MC, ^RF

^MC Map Clear

^MCN keeps the image for the next label (overlay), ^MCY clears it again.

^RF RFID watermark

RfidIndicator = Watermark (default)

Labels with an RFID operation (^RF, ^WT, ^WF, ^RQ) show a gray RFID symbol in the preview: centered, approx. 0.86" in size, behind the content, rotated with ^PO I; as a path in SVG/vector PDF. Only PNG/JPEG/WebP/BMP/GIF/PDF/SVG/HTML/EPS – never in GRF, EPL, PCL, Fingerprint, ESC/POS or 1-bit TIFF/PCX. RfidIndicator = ZplRfidIndicator.None turns it off.

^SO / ^ST

Secondary and tertiary clock with offset (e.g. best-before +2 months) or setting the clock. ^CD/^CC/^CT change the control characters, ^TO copies stored objects, ^JM halves the dot density.

More on zplCloud.com: Guide: ^SN