I wrote a easy program to convert a monochrome bitmap data to a byte array, and then reverse it (0->1, 1->0) in order to send it as a ZPL to a label printer.
Bitmap bmp = (Bitmap)pictureBox1.Image;
Rectangle rectangle = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bd = bmp.LockBits(rectangle, ImageLockMode.ReadOnly, bmp.PixelFormat);
IntPtr ptr = bd.Scan0;
byte[] b = new byte[Math.Abs(bd.Stride) * bmp.Height];
Marshal.Copy(ptr, b, 0, b.Length);
bmp.UnlockBits(bd);
StringBuilder sb = new StringBuilder();
foreach (byte i in b)
{
sb.Append((255 - i).ToString("X2"));
}
textBox1.Text = string.Format(@"^XA^FO100,0^GFA,{0},{0},{1},{2}^FS^XZ", b.Length, Math.Abs(bd.Stride), sb.ToString());
But it draws an unnecessary black bar that was originally not there!
I first thought it might be because the rectangle I assigned to the BitmapData was too big so there included some "unused" areas, but apparently I was wrong and the 07FFFFs was still there!
I even tried to just replace it with empty string for the hack of it!
But it was wrong because it mess up the ZPL output!
Of course I could just store the replaced string and recalculate the length for the ^GFA command, but what if the picture "just so happen" to have some 07FFFFs in itself!? I essentially mess up the picture itself by doing so!
The 07FFFF was "reversed" by my code, so it was F80000 in the original byte array, so I figure it might be some thing similar to "\n" in the bitmap data to tell the picture to "keep drawing from the new line"!
And I can't find anything online explaining why there are F80000s in the bitmap files.
It's all good for the picture, but how could I "get rid of it"!?
I "only" want the data that was "the picture itself".
Could somebody please be so kind and help me out!?
Much appreciated!

The Reason
The
Strideproperty gives you the length of each scanline of the image in bytes, rounded up the next 4-byte boundary. And if a line in the image does not fill the whole scanline, it is padded with 0. Your code processed and included this padding data in the^GFAcommand producing the black bars on the right side. If you don't invert the image, you won't notice the problem.You need to invert the image because the value of each pixel is not only black and white. It is an index to a two-color table. And each entry in the color table defines the actual color of the pixel in RGB. In your case
Color[0]=blackandColor[1]=white.With the pixel format of
Format1bppIndexedyou get additional complexity if the image width is not a multiple of 8. Then there are padding bits in the last used byte of each line in the image.Let's take your image as an example. You have an image width of 173. Each line need at least 22 (=ceil(173 / 8)) bytes to store the data of one line. In the last byte, only the first 5 bits (=173 % 8) have real pixel data. The next multiple of 4 above 22 is 24. So each line takes 24 bytes of memory. The additional 2 bytes are padding bytes filled with zeros.
The ZPL Command
^GFAThe Format:
^GFa,b,c,d,datawhere a, b, c, d and data are parameters to the command.Afor ASCII-HEX (Base16),BbinaryAs far as I understand the documentation of the command, it only supports image widths that are a multiple of 8, because you can only specify the number of bytes for a row/line. If the source image does not have the correct width, you can expand the image where all the padding bits set to 0/white/inactive.
The Solution
I have implemented two methods to solve the problem. The first one reads a monochrome bitmap and returns a
StringBuilderobject with the appropriate^GFAcommand.ZPLCommandFromArrayconverts the byte array to the image data for the^GFAcommand.