I need to print a PNG image onto a label with a ZPL printer. The idea is to convert the PNG image to a monochrome one and then generate the necessary ZPL code with the image data to print the image.
After some googling and coding, I have a piece of code that does just that. The generated ZPL code seems fine on labelary (http://labelary.com).
The code for generating the ZPL code was mostly taken from here --> How to optimize ASCII HEX for BMP to ZPL as using in Labelary
Unfortunately, when trying to print a label with the generated ZPL code, it comes out like this: Not supposed to look like this
Image should look like this: ImageToConvert
The code that i use is this:
static void Main(string[] args)
{
// 1. Convert Image to monochrome bmp
string bitmapFilePath = @"somepath.bmp";
Bitmap imageToConvert = new Bitmap(bitmapFilePath);
var rectangle = new Rectangle(0, 0, imageToConvert.Width, imageToConvert.Height);
Bitmap monochromeImage = imageToConvert.Clone(rectangle, PixelFormat.Format1bppIndexed);
// Mirror image
monochromeImage.RotateFlip(RotateFlipType.Rotate180FlipX);
// Save mono image
monochromeImage.Save("somePathMono.bmp", ImageFormat.Bmp);
// 2. Convert to ZPL
ConvertImage();
}
public static void ConvertImage()
{
string bitmapFilePath = "somePathMono.bmp";
int w, h;
Bitmap b = new Bitmap(bitmapFilePath);
w = b.Width; h = b.Height;
byte[] bitmapFileData = System.IO.File.ReadAllBytes(bitmapFilePath);
int fileSize = bitmapFileData.Length;
int bitmapDataOffset = int.Parse(bitmapFileData[10].ToString()); ;
int width = w; // int.Parse(bitmapFileData[18].ToString()); ;
int height = h; // int.Parse(bitmapFileData[22].ToString()); ;
int bitsPerPixel = int.Parse(bitmapFileData[28].ToString());
int bitmapDataLength = bitmapFileData.Length - bitmapDataOffset;
double widthInBytes = Math.Ceiling(width / 8.0);
while (widthInBytes % 4 != 0)
{
widthInBytes++;
}
// Copy over the actual bitmap data without header data
byte[] bitmap = new byte[bitmapDataLength];
Buffer.BlockCopy(bitmapFileData, bitmapDataOffset, bitmap, 0, bitmapDataLength);
// Invert bitmap colors
for (int i = 0; i < bitmapDataLength; i++)
{
bitmap[i] ^= 0xFF;
}
// Create ASCII ZPL string of hexadecimal bitmap data
string ZPLImageDataString = BitConverter.ToString(bitmap);
ZPLImageDataString = ZPLImageDataString.Replace("-", string.Empty);
// Add new line every 1023 chars characters
string ZPLImageDataStringWithNewLine = SpliceText(ZPLImageDataString, 1023);
// Create ZPL command to print image
string ZPLCommand = string.Empty;
ZPLCommand += "^XA";
ZPLCommand += "^FO20,20";
ZPLCommand +=
"^GFA," +
bitmapDataLength.ToString() + "," +
bitmapDataLength.ToString() + "," +
widthInBytes.ToString() + "," +
System.Environment.NewLine +
ZPLImageDataStringWithNewLine;
ZPLCommand += "^XZ";
System.IO.StreamWriter sr = new System.IO.StreamWriter("zplCodePath", false, System.Text.Encoding.Default);
sr.Write(ZPLCommand);
sr.Close();
}
public static string SpliceText(string text, int lineLength)
{
return Regex.Replace(text, "(.{" + lineLength + "})", "$1" + Environment.NewLine);
}
We use the Zebra ZT 410 printer
Can someone help me figure out what the problem could be? I'm out of ideas at this point.
Thanks!
UPDATE: Seems like the problem is the newline that I put after every x characters in the image data. I don't understand why. My code works perfectly for smaller image (where I don't have to put new lines), but for big images with long imagedata strings it does not print if I don't put the new lines.
Any help would be appreciated!
Z64
andB64
can be found in the ZPL guide, page 1366. "Introduction to B64 and Z64". – Polybius