Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting PNG image to ZPL code

Tags:

c#

.net

png

zpl

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!

like image 742
Lenquist Avatar asked Apr 12 '18 14:04

Lenquist


People also ask

How do I add an image to ZPL?

If that's the case, the easiest solution is probably to go to the Labelary online ZPL viewer, paste your ZPL into the viewer, click "Add image", and upload the image that you want to add to the ZPL. This should modify your ZPL by adding the image ZPL commands that you need, and you can then tweak the position, etc.

How do you convert to ZPL?

ZPL to PDF conversion settings in FolderMill To specify label size, add Convert to PDF Action and press Ctrl + Alt + i on your keyboard. Then set the size of output labels by changing the values of lines Zpl_height=152 and Zpl_width=101. The values should be set in millimeters.

What is ZPL format?

The Zebra Printer Language (ZPL) format is a full-featured printer language for producing labels that contain text, barcodes, lines and boxes, and graphics. When using a ZPL file as input, eFORMz reads in the individual elements on the label and converts them into the eFORMz proprietary device-independent format.


1 Answers

Because I had such issue with the ZPL guide and various references providing different solutions (that never seemed to fully work with my use-case) I created a simple .net core application which takes a label image and converts it to ZPL, either to a file (if output is provided) or directly to the console so it's pipeable in bash scripts.

like image 120
nelsontruran Avatar answered Oct 21 '22 05:10

nelsontruran