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. |
pathFilecan't be null or empty and the destination folder must already exist. An existing file is overwritten.imgSettingscan beNothing/null: a defaultImageSettingsis used (JPEG, quality 80).dpiis the output resolution. Values lower than 96 are raised to 96.- Image size. The size in pixels is
label size (inches) x dpi(multiplied byImageSettings.ScaleX/ScaleY). For example, a 4 x 3 inch label at 300 dpi gives a 1200 x 900 pixel image. WithPrintOrientation = Landscape90orLandscape270the 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.Copiesis 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 > 1each repeated copy is saved asmyLabel1_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 = 0before reading it. - With several labels the stream receives a ZIP file. Each entry is one image named with the
DateTimeticks 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
ExportToImagereturns; 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 ThumbnailSizepixels. The label is scaled down keeping its proportions and centered; the remaining area is empty. JpegQualityLevelis not used for thumbnails (they are encoded with quality 100).
Other things that affect the output
- Orientation.
PrintJob.PrintOrientationrotates the image (Landscape90,Portrait180,Landscape270). - Margin.
ThermalLabel.Marginmoves all the items. - Expressions. Item and Global Expressions are evaluated for every label, and
PAGE_NUMBER,TOTAL_PAGES,LABEL_WIDTHandLABEL_HEIGHTare available. - Items Caching.
PrintJob.RenderCacheEnabled(defaultTrue) 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 fromThis is a Counter: 0toThis is a Counter: 4and the barcode fromABC 12345toABC 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
Streamin 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());
}
}
}
ZipArchiveandZipArchiveEntryare inSystem.IO.Compression.
- Example #4: Other
ImageSettingscombinations (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 = 0first. - Treating a stream as a plain image when the job is data-bound. It is a ZIP, even with a single label.
- Setting
Copiesto repeat a plain single label.Copiesis ignored when exporting a plain single label; use Counters, a DataSource orReplicates. - 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. TransparentBackgroundwith 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.