Show / Hide Table of Contents

Export Labels to Image

PrintJob.ExportToImage() renders a ThermalLabel to an image file or to a Stream. Depending on the label (single label, Counters, Data Masking, Data Binding, multi-column or sheet of labels) you get one image or many images; this page explains exactly when and how they are named or packed.

Supported output image formats

The format is selected with ImageSettings.ImageFormat:

ImageFormat Type Notes
Jpeg Raster Default. Quality set with JpegQualityLevel (1-100, default 80). Always written with the DPI metadata (when DPI is not 96).
Png Raster Supports a transparent background (TransparentBackground). The DPI metadata is written only if PngIncludeDpiMetadata = True.
Pcx Raster 1-bit black & white. Colors and grays are converted to black or white, and the width is padded to a multiple of 8 pixels.
Svg Vector Resolution independent. DPI, JPEG quality and thumbnail settings do not apply.
Important

The output format is always taken from ImageSettings.ImageFormat, never from the file extension. If you ask for ImageFormat.Png but the file is called label.jpg, the file will contain a PNG. Use the extension that matches the format.

How Labels to Image works

The object in charge of the exportation is PrintJob. These are the overloads:

Method Output
ExportToImage(string pathFile, ImageSettings imgSettings, double dpi) File. Exports PrintJob.ThermalLabel.
ExportToImage(ThermalLabel thermalLabel, string pathFile, ImageSettings imgSettings, double dpi) File.
ExportToImage(Stream stream, ImageSettings imgSettings, double dpi) Stream. Exports PrintJob.ThermalLabel.
ExportToImage(ThermalLabel thermalLabel, Stream stream, ImageSettings imgSettings, double dpi) Stream.
  • pathFile can't be null or empty and the destination folder must already exist. An existing file is overwritten.
  • imgSettings can be Nothing/null: a default ImageSettings is used (JPEG, quality 80).
  • dpi is the output resolution. Values lower than 96 are raised to 96.
  • Image size. The size in pixels is label size (inches) x dpi (multiplied by ImageSettings.ScaleX / ScaleY). For example, a 4 x 3 inch label at 300 dpi gives a 1200 x 900 pixel image. With PrintOrientation = Landscape90 or Landscape270 the width and height are swapped.
  • The label is cloned before rendering, so the label's own properties are not changed by the rendering (see the source notes at the end).

ImageSettings

Property Type Default Description
ImageFormat ImageFormat Jpeg Jpeg, Png, Svg or Pcx.
JpegQualityLevel Integer 80 JPEG quality, from 1 (lowest) to 100 (highest). Any other value throws ArgumentOutOfRangeException. Not used for thumbnails (always 100).
AntiAlias Boolean False Applies anti-aliasing to all the items. Keep it False to get crisp, printer-like output.
TransparentBackground Boolean False Transparent label background. Effective for PNG and SVG; with JPEG and PCX the background is white.
PngIncludeDpiMetadata Boolean False Writes the DPI (pHYs chunk) into the PNG. Needed if the PNG will later be printed at its real size.
ThumbnailSize Integer 0 Size in pixels of a square thumbnail. 0 disables it. See Thumbnails.
ScaleX, ScaleY Double 1 Scale factors applied to the output width and height. A negative value throws ArgumentException; 0 makes the rendering fail because the image would have no size.

How many images do I get?

The number of outputs depends on the scenario, not on the format.

Scenario Images To a file To a Stream
Single label (no DataSource, no Counters, no Mask, one label per row) 1 The file as is. The raw image bytes.
Counters, Data Masking and/or Data Binding One per generated label (see Counters, Data Masking and Data Binding) name1.ext, name2.ext... A ZIP file with one entry per image.
Multi-column labels (LabelsPerRow > 1) One per row of labels Same as above. Same as above.
Sheet of labels (IsSheetOfLabels) One per sheet Same as above. Same as above.

Also note:

  • A data-bound job with only one label still returns a ZIP to a stream. The ZIP is chosen by the scenario, not by the number of images. To handle both cases, check whether the stream starts with PK (see Example #3).
  • PrintJob.Copies is ignored for a plain single label: you always get one image. With Counters or Masks each copy is a different label (see Counters), and with a DataSource there is one label per data row.
  • PrintJob.Replicates (data-bound jobs only) repeats every generated label that many times.

Files

When there is more than one label, the index is inserted before the extension, starting at 1 and without zero padding: exporting to c:\temp\myLabel.jpg creates myLabel1.jpg, myLabel2.jpg, ... myLabel10.jpg (sorted by name, myLabel10.jpg comes before myLabel2.jpg). If there is only one label the name is used as is.

  • With Replicates > 1 each repeated copy is saved as myLabel1_2.jpg, myLabel1_3.jpg, ...
  • Use a file name with an extension that matches the format. Without an extension the index is simply appended (myLabel1, myLabel2...).
  • Existing files, including the _2, _3... replicates, are overwritten.

Streams

  • With a single label the stream receives the image bytes only. The stream is not rewound: set stream.Position = 0 before reading it.
  • With several labels the stream receives a ZIP file. Each entry is one image named with the DateTime ticks at the moment it was created (always increasing, so the names are unique) plus the format extension (.jpg, .png, .svg, .pcx). The entries are stored in label order, so use the entry order to know which label is which.
  • The ZIP is complete when ExportToImage returns; the stream is left open.

Getting every label without a ZIP

If you need each image as soon as it is generated (for example, to send it to a browser or a queue), handle the PrintJob.LabelProgress event. PrintJobLabelProgressEventArgs.LabelImage holds the encoded image (JPEG, PNG, PCX or SVG) of just that label, LabelIndex/TotalLabels tell you where you are, and Cancel = True stops the remaining labels (a PrintJobCanceledException is thrown, but the images already generated are kept in the file or stream). The event is not raised for plain single labels.

DPI metadata

The resolution is stored inside the image when it is different from 96 dpi:

Format Includes the DPI?
JPEG Always.
PNG Only if PngIncludeDpiMetadata = True.
PCX Always (the header stores the DPI; thumbnails use 96).
SVG No.

Thumbnails do not include the DPI metadata.

Thumbnails

Set ImageSettings.ThumbnailSize to a value greater than zero (in pixels) to generate a thumbnail instead of the full-size image.

  • It works with PNG, JPEG and PCX. It is ignored for SVG.
  • The thumbnail replaces the full-size image: you get one or the other, not both. Export twice (with and without ThumbnailSize) if you need both.
  • The thumbnail is a square of ThumbnailSize x ThumbnailSize pixels. The label is scaled down keeping its proportions and centered; the remaining area is empty.
  • JpegQualityLevel is not used for thumbnails (they are encoded with quality 100).

Other things that affect the output

  • Orientation. PrintJob.PrintOrientation rotates the image (Landscape90, Portrait180, Landscape270).
  • Margin. ThermalLabel.Margin moves all the items.
  • Expressions. Item and Global Expressions are evaluated for every label, and PAGE_NUMBER, TOTAL_PAGES, LABEL_WIDTH and LABEL_HEIGHT are available.
  • Items Caching. PrintJob.RenderCacheEnabled (default True) reuses the rendering of items whose content repeats between the labels of a data-bound job (see Items Caching).
  • Trial version. The trial mark is stamped on raster images, and in SVG output the items are not drawn at all.

Labels to Image samples

  • Example #1: The following code exports a single ThermalLabel object to JPEG format at 300 dpi.

VB

'Define a ThermalLabel object and set unit to inch and label size
Dim tLabel As New ThermalLabel(UnitType.Inch, 4, 3)
tLabel.GapLength = 0.2

'Define a TextItem object
Dim txtItem As New TextItem(0.2, 0.2, 1, 0.5, "Thermal Label Test")

'Define a BarcodeItem object
Dim bcItem As New BarcodeItem(0.2, 1, 2, 1, BarcodeSymbology.Code128, "ABC 12345")
'Set bars height to .75inch
bcItem.BarHeight = 0.75
'Set bars width to 0.0104inch
bcItem.BarWidth = 0.0104

'Add items to ThermalLabel object...
tLabel.Items.Add(txtItem)
tLabel.Items.Add(bcItem)

'Create a PrintJob object
Using pj As New PrintJob()
    'Save output to image...
    pj.ExportToImage(tLabel, "c:\temp\myLabel.jpg", New ImageSettings(ImageFormat.Jpeg), 300)
End Using

CS

//Define a ThermalLabel object and set unit to inch and label size
ThermalLabel tLabel = new ThermalLabel(UnitType.Inch, 4, 3);
tLabel.GapLength = 0.2;

//Define a TextItem object
TextItem txtItem = new TextItem(0.2, 0.2, 1, 0.5, "Thermal Label Test");

//Define a BarcodeItem object
BarcodeItem bcItem = new BarcodeItem(0.2, 1, 2, 1, BarcodeSymbology.Code128, "ABC 12345");
//Set bars height to .75inch
bcItem.BarHeight = 0.75;
//Set bars width to 0.0104inch
bcItem.BarWidth = 0.0104;

//Add items to ThermalLabel object...
tLabel.Items.Add(txtItem);
tLabel.Items.Add(bcItem);

//Create a PrintJob object
using (PrintJob pj = new PrintJob())
{
    //Save output to image...
    pj.ExportToImage(tLabel, @"c:\temp\myLabel.jpg", new ImageSettings(ImageFormat.Jpeg), 300);
}
  • Example #2: The following code exports a ThermalLabel object that uses Counters to 5 JPEG files at 300 dpi: myLabel1.jpg ... myLabel5.jpg. The text goes from This is a Counter: 0 to This is a Counter: 4 and the barcode from ABC 12345 to ABC 12349.

VB

'Define a ThermalLabel object and set unit to inch and label size
Dim tLabel As New ThermalLabel(UnitType.Inch, 4, 3)
tLabel.GapLength = 0.2

'Define a TextItem object
Dim txtItem As New TextItem(0.2, 0.2, 2, 0.5, "This is a Counter: 0")
'Set counter
txtItem.CounterStep = 1

'Define a BarcodeItem object
Dim bcItem As New BarcodeItem(0.2, 1, 2, 1, BarcodeSymbology.Code128, "ABC 12345")
'Set counter
bcItem.CounterStep = 1
'Set bars height to .75inch
bcItem.BarHeight = 0.75
'Set bars width to 0.0104inch
bcItem.BarWidth = 0.0104

'Add items to ThermalLabel object...
tLabel.Items.Add(txtItem)
tLabel.Items.Add(bcItem)

'Create a PrintJob object
Using pj As New PrintJob()
    'Set number of labels to generate
    pj.Copies = 5
    'Save output to image...
    pj.ExportToImage(tLabel, "c:\temp\myLabel.jpg", New ImageSettings(ImageFormat.Jpeg), 300)
End Using

CS

//Define a ThermalLabel object and set unit to inch and label size
ThermalLabel tLabel = new ThermalLabel(UnitType.Inch, 4, 3);
tLabel.GapLength = 0.2;

//Define a TextItem object
TextItem txtItem = new TextItem(0.2, 0.2, 2, 0.5, "This is a Counter: 0");
//Set counter
txtItem.CounterStep = 1;

//Define a BarcodeItem object
BarcodeItem bcItem = new BarcodeItem(0.2, 1, 2, 1, BarcodeSymbology.Code128, "ABC 12345");
//Set counter
bcItem.CounterStep = 1;
//Set bars height to .75inch
bcItem.BarHeight = 0.75;
//Set bars width to 0.0104inch
bcItem.BarWidth = 0.0104;

//Add items to ThermalLabel object...
tLabel.Items.Add(txtItem);
tLabel.Items.Add(bcItem);

//Create a PrintJob object
using (PrintJob pj = new PrintJob())
{
    //Set number of labels to generate
    pj.Copies = 5;
    //Save output to image...
    pj.ExportToImage(tLabel, @"c:\temp\myLabel.jpg", new ImageSettings(ImageFormat.Jpeg), 300);
}
  • Example #3: The following code exports the same Counters label to a Stream in PNG format. Because the job generates several labels, the stream contains a ZIP file that is read entry by entry. The same code also works when the job generates a single label.

VB

Using pj As New PrintJob()
    pj.Copies = 5

    Using ms As New MemoryStream()
        Dim imgSettings As New ImageSettings(ImageFormat.Png)
        imgSettings.PngIncludeDpiMetadata = True

        pj.ExportToImage(tLabel, ms, imgSettings, 300)

        'the stream is positioned at the end, go back to the beginning
        ms.Position = 0

        'a ZIP file starts with "PK"
        Dim isZip As Boolean = (ms.Length > 1 AndAlso ms.ReadByte() = &H50 AndAlso ms.ReadByte() = &H4B)
        ms.Position = 0

        If isZip Then
            Using zip As New ZipArchive(ms, ZipArchiveMode.Read)
                Dim n As Integer = 1
                'entries are stored in label order
                For Each entry As ZipArchiveEntry In zip.Entries
                    Using entryStream As Stream = entry.Open()
                        Using fs As FileStream = File.Create("c:\temp\label_" & n.ToString() & ".png")
                            entryStream.CopyTo(fs)
                        End Using
                    End Using
                    n += 1
                Next
            End Using
        Else
            'just one image
            File.WriteAllBytes("c:\temp\label_1.png", ms.ToArray())
        End If
    End Using
End Using

CS

using (PrintJob pj = new PrintJob())
{
    pj.Copies = 5;

    using (MemoryStream ms = new MemoryStream())
    {
        ImageSettings imgSettings = new ImageSettings(ImageFormat.Png);
        imgSettings.PngIncludeDpiMetadata = true;

        pj.ExportToImage(tLabel, ms, imgSettings, 300);

        // the stream is positioned at the end, go back to the beginning
        ms.Position = 0;

        // a ZIP file starts with "PK"
        bool isZip = ms.Length > 1 && ms.ReadByte() == 0x50 && ms.ReadByte() == 0x4B;
        ms.Position = 0;

        if (isZip)
        {
            using (ZipArchive zip = new ZipArchive(ms, ZipArchiveMode.Read))
            {
                int n = 1;
                // entries are stored in label order
                foreach (ZipArchiveEntry entry in zip.Entries)
                {
                    using (Stream entryStream = entry.Open())
                    using (FileStream fs = File.Create(@"c:\temp\label_" + n + ".png"))
                    {
                        entryStream.CopyTo(fs);
                    }
                    n++;
                }
            }
        }
        else
        {
            // just one image
            File.WriteAllBytes(@"c:\temp\label_1.png", ms.ToArray());
        }
    }
}

ZipArchive and ZipArchiveEntry are in System.IO.Compression.

  • Example #4: Other ImageSettings combinations (C#; the properties are the same in VB).
using (PrintJob pj = new PrintJob())
{
    // PNG with transparent background and DPI metadata, 300 dpi
    var png = new ImageSettings(ImageFormat.Png) { TransparentBackground = true, PngIncludeDpiMetadata = true };
    pj.ExportToImage(tLabel, @"c:\temp\label.png", png, 300);

    // high quality JPEG
    var jpg = new ImageSettings(ImageFormat.Jpeg) { JpegQualityLevel = 100 };
    pj.ExportToImage(tLabel, @"c:\temp\label_hq.jpg", jpg, 300);

    // 128 x 128 pixel thumbnail (replaces the full-size image)
    var thumb = new ImageSettings(ImageFormat.Png) { ThumbnailSize = 128 };
    pj.ExportToImage(tLabel, @"c:\temp\label_thumb.png", thumb, 96);

    // vector output
    pj.ExportToImage(tLabel, @"c:\temp\label.svg", new ImageSettings(ImageFormat.Svg), 203);

    // black & white PCX
    pj.ExportToImage(tLabel, @"c:\temp\label.pcx", new ImageSettings(ImageFormat.Pcx), 203);
}

Common mistakes

  • Expecting the extension to select the format. Use ImageSettings.ImageFormat.
  • Expecting a single file from a Counters, Masks or Data Binding job. You get one file per label (name1.ext, name2.ext...), or a ZIP in a stream.
  • Reading a stream without rewinding it. Set stream.Position = 0 first.
  • Treating a stream as a plain image when the job is data-bound. It is a ZIP, even with a single label.
  • Setting Copies to repeat a plain single label. Copies is ignored when exporting a plain single label; use Counters, a DataSource or Replicates.
  • Exporting to a folder that doesn't exist. The export fails; create the folder first.
  • Printing a PNG that has no DPI. Set PngIncludeDpiMetadata = True.
  • TransparentBackground with JPEG or PCX. They have no transparency: the background is white.
  • Asking for a thumbnail and the full image in the same call. Only the thumbnail is saved.
  • Using SVG with the trial version. The items are not drawn.
Back to top Copyright © 2003- Neodynamic SRL
http://www.neodynamic.com