title: Converting PNG image to ZPL code
body: <p>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.</p>
  
  <p>After some googling and coding, I have  a piece of code that does just that. The generated ZPL code seems fine on labelary (<a href="http://labelary.com" rel="noreferrer">http://labelary.com</a>).</p>
  
  <p>The code for generating the ZPL code was mostly taken from here --> <a href="https://stackoverflow.com/questions/35474520/how-to-optimize-ascii-hex-for-bmp-to-zpl-as-using-in-labelary">How to optimize ASCII HEX for BMP to ZPL as using in Labelary</a></p>
  
  <p>Unfortunately, when trying to print a label with the generated ZPL code, it comes out like this:
  <a href="https://i.stack.imgur.com/wBXEt.jpg" rel="noreferrer">Not supposed to look like this</a></p>
  
  <p>Image should look like this:
  <a href="https://i.stack.imgur.com/IN1u2.png" rel="noreferrer">ImageToConvert</a></p>
  
  <p>The code that i use is this:</p>
  
  <pre><code>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 &lt; 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);
      }
  </code></pre>
  
  <p>We use the Zebra ZT 410 printer</p>
  
  <p>Can someone help me figure out what the problem could be? I'm out of ideas at this point.</p>
  
  <p>Thanks! </p>
  
  <p>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.</p>
  
  <p>Any help would be appreciated!</p>