问题
I have a problem.
I´m generating a dynamic BMP image and trying to send this to a ZEBRA printer by ZPL commands. I need to convert my BMP to a GRF image. I think that my Hexadecimal extracted by the BMP image isn´t correct.
The printed image is blurred and incorrect.
This is my code:
string bitmapFilePath = @oldArquivo; // file is attached to this support article
byte[] bitmapFileData = System.IO.File.ReadAllBytes(bitmapFilePath);
int fileSize = bitmapFileData.Length;
Bitmap ImgTemp = new Bitmap(bitmapFilePath);
Size ImgSize = ImgTemp.Size;
ImgTemp.Dispose();
// The following is known about test.bmp. It is up to the developer
// to determine this information for bitmaps besides the given test.bmp.
int width = ImgSize.Width;
int height = ImgSize.Height;
int bitmapDataOffset = 62; // 62 = header of the image
int bitmapDataLength = fileSize - 62;// 8160;
double widthInBytes = Math.Ceiling(width / 8.0);
// Copy over the actual bitmap data from the bitmap file.
// This represents the bitmap data without the header information.
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).Replace("-", string.Empty);
string comandoCompleto = "~DG" + nomeImagem + ".GRF,0" + bitmapDataLength.ToString() + ",0" + widthInBytes.ToString() + "," + ZPLImageDataString;
回答1:
Try the following code. Not tested!
public static string CreateGRF(string filename, string imagename)
{
Bitmap bmp = null;
BitmapData imgData = null;
byte[] pixels;
int x, y, width;
StringBuilder sb;
IntPtr ptr;
try
{
bmp = new Bitmap(filename);
imgData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format1bppIndexed);
width = (bmp.Width + 7) / 8;
pixels = new byte[width];
sb = new StringBuilder(width * bmp.Height * 2);
ptr = imgData.Scan0;
for (y = 0; y < bmp.Height; y++)
{
Marshal.Copy(ptr, pixels, 0, width);
for (x = 0; x < width; x++)
sb.AppendFormat("{0:X2}", (byte)~pixels[x]);
ptr = (IntPtr)(ptr.ToInt64() + imgData.Stride);
}
}
finally
{
if (bmp != null)
{
if (imgData != null) bmp.UnlockBits(imgData);
bmp.Dispose();
}
}
return String.Format("~DG{0}.GRF,{1},{2},", imagename, width * y, width) + sb.ToString();
}
回答2:
One thing to point out is that the bitmap being converted must be monochrome (that is, 1 bit per pixel). There is an example on Zebra's knowledgebase that demonstrates printing a simple monochrome image in ZPL: https://km.zebra.com/kb/index?page=answeropen&type=open&searchid=1356730396931&answerid=16777216&iqaction=5&url=https%3A%2F%2Fkm.zebra.com%2Fkb%2Findex%3Fpage%3Dcontent%26id%3DSA304%26actp%3Dsearch%26viewlocale%3Den_US&highlightinfo=4194550,131,153#. If you can convert your images into monochrome bitmaps, then you should be able to follow that example.
// Given a monochrome bitmap file, one can read
// information about that bitmap from the header
// information in the file. This information includes
// bitmap height, width, bitsPerPixel, etc. It is required
// that a developer understands the basic bitmap format and
// how to extract the following data in order to proceed.
// A simple search online for 'bitmap format' should yield
// all the needed information. Here, for our example, we simply
// declare what the bitmap information is, since we are working
// with a known sample file.
string bitmapFilePath = @"test.bmp"; // file is attached to this support article
byte[] bitmapFileData = System.IO.File.ReadAllBytes(bitmapFilePath);
int fileSize = bitmapFileData.Length;
// The following is known about test.bmp. It is up to the developer
// to determine this information for bitmaps besides the given test.bmp.
int bitmapDataOffset = 62;
int width = 255;
int height = 255;
int bitsPerPixel = 1; // Monochrome image required!
int bitmapDataLength = 8160;
double widthInBytes = Math.Ceiling(width / 8.0);
// Copy over the actual bitmap data from the bitmap file.
// This represents the bitmap data without the header information.
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);
// Create ZPL command to print image
string[] ZPLCommand = new string[4];
ZPLCommand[0] = "^XA";
ZPLCommand[1] = "^FO20,20";
ZPLCommand[2] =
"^GFA, " +
bitmapDataLength.ToString() + "," +
bitmapDataLength.ToString() + "," +
widthInBytes.ToString() + "," +
ZPLImageDataString;
ZPLCommand[3] = "^XZ";
// Connect to printer
string ipAddress = "10.3.14.42";
int port = 9100;
System.Net.Sockets.TcpClient client =
new System.Net.Sockets.TcpClient();
client.Connect(ipAddress, port);
System.Net.Sockets.NetworkStream stream = client.GetStream();
// Send command strings to printer
foreach (string commandLine in ZPLCommand)
{
stream.Write(ASCIIEncoding.ASCII.GetBytes(commandLine), 0, commandLine.Length);
stream.Flush();
}
// Close connections
stream.Close();
client.Close();
回答3:
Please add 2 to widthInBytes - it works!!!
int bitmapDataOffset = int.Parse(bitmapFileData[10].ToString()); ;
int width = 624;// int.Parse(bitmapFileData[18].ToString()); ;
int height = int.Parse(bitmapFileData[22].ToString()); ;
int bitsPerPixel = int.Parse(bitmapFileData[28].ToString()); // Monochrome image required!
int bitmapDataLength = bitmapFileData.Length - bitmapDataOffset;
double widthInBytes = Math.Ceiling(width / 8.0)+2;
来源:https://stackoverflow.com/questions/14054626/how-to-generate-a-dynamic-grf-image-to-zpl-zebra-print