相关文章推荐
没读研的冰淇淋  ·  mysql ...·  1 月前    · 
爱旅游的伤疤  ·  Word JavaScript API ...·  1 年前    · 
没人理的面包  ·  matlab fprintf font ...·  1 年前    · 
/// ZPL压缩字典 /// private static List> compressDictionary = new List>(); #endregion #region 构造方法 static ZebraUnity() InitCompressCode(); #endregion #region 定义属性 /// /// 图像的二进制数据 /// public static byte[] GraphBuffer { get; set; } /// /// 图像的宽度 /// private static int GraphWidth { get; set; } /// /// 图像的高度 /// private static int GraphHeight { get; set; } private static int RowSize return (((GraphWidth) + 31) >> 5) << 2; /// /// 每行的字节数 /// private static int RowRealBytesCount if ((GraphWidth % 8) > 0) return GraphWidth / 8 + 1; return GraphWidth / 8; #endregion #region 位图转斑马指令字符串 /// /// 位图转斑马指令字符串 /// /// 位图数据 /// 总共的字节数 /// 每行的字节数 /// 斑马ZPL 2命令 public static string BmpToZpl(byte[] bitmap, out int totalBytes, out int rowBytes) GraphBuffer = bitmap; byte[] bmpData = getBitmapData(); string textHex = BitConverter.ToString(bmpData).Replace("-", string.Empty); string textBitmap = CompressLZ77(textHex); totalBytes = GraphHeight * RowRealBytesCount; rowBytes = RowRealBytesCount; return textBitmap; catch (Exception ex) throw ex; /// /// 位图转ZPL指令 /// /// 位图 /// 返回参数总共字节数 /// 返回参数每行的字节数 /// ZPL命令 public static string BmpToZpl(Image bitmap, out int totalBytes, out int rowBytes) using (MemoryStream stream = new MemoryStream()) bitmap.Save(stream, ImageFormat.Bmp); return BmpToZpl(stream.ToArray(), out totalBytes, out rowBytes); /// /// 根据图片生成图片的ASCII 十六进制 /// /// 原始图片 /// 总共字节数 /// 每行的字节数 /// ASCII 十六进制 public static string BitmapToHex(Image sourceBmp, out int totalBytes, out int rowBytes) // 转成单色图 Bitmap grayBmp = ConvertToGrayscale(sourceBmp as Bitmap); // 锁定位图数据 Rectangle rect = new Rectangle(0, 0, grayBmp.Width, grayBmp.Height); System.Drawing.Imaging.BitmapData bmpData = grayBmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, grayBmp.PixelFormat); // 获取位图数据第一行的起始地址 IntPtr ptr = bmpData.Scan0; // 定义数组以存放位图的字节流数据 // 处理像素宽对应的字节数,如不为8的倍数,则对最后一个字节补0 int width = (int)Math.Ceiling(grayBmp.Width / 8.0); // 获取位图实际的字节宽,这个值因为要考虑4的倍数关系,可能大于width int stride = Math.Abs(bmpData.Stride); // 计算位图数据实际所占的字节数,并定义数组 int bitmapDataLength = stride * grayBmp.Height; byte[] ImgData = new byte[bitmapDataLength]; // 从位图文件复制图像数据到数组,从实际图像数据的第一行开始;因ptr指针而无需再考虑行倒序存储的处理 System.Runtime.InteropServices.Marshal.Copy(ptr, ImgData, 0, bitmapDataLength); // 计算异或操作数,以处理包含图像数据但又有补0操作的那个字节 byte mask = 0xFF; // 计算这个字节补0的个数 //int offset = 8 * width - grayBmp.Width; int offset = 8 - (grayBmp.Width % 8); //offset %= 8; offset = offset % 8; // 按补0个数对0xFF做相应位数的左移位操作 mask <<= (byte)offset; // 图像反色处理 for (int j = 0; j < grayBmp.Height; j++) for (int i = 0; i < stride; i++) if (i < width - 1) //无补0的图像数据 ImgData[j * stride + i] ^= 0xFF; else if (i == width - 1) //有像素的最后一个字节,可能有补0 ImgData[j * stride + i] ^= mask; else //为满足行字节宽为4的倍数而最后补的字节 //ImgData[j * stride + i] = 0x00; ImgData[j * stride + i] ^= 0x00; // 将位图数据转换为16进制的ASCII字符 string zplString = BitConverter.ToString(ImgData); zplString = CompressLZ77(zplString.Replace("-", string.Empty)); totalBytes = bitmapDataLength; rowBytes = stride; return zplString; #endregion #region 获取单色位图数据 /// /// 获取单色位图数据 /// /// /// private static Bitmap ConvertToGrayscale(Bitmap pimage) Bitmap source = null; // If original bitmap is not already in 32 BPP, ARGB format, then convert if (pimage.PixelFormat != PixelFormat.Format32bppArgb) source = new Bitmap(pimage.Width, pimage.Height, PixelFormat.Format32bppArgb); source.SetResolution(pimage.HorizontalResolution, pimage.VerticalResolution); using (Graphics g = Graphics.FromImage(source)) g.DrawImageUnscaled(pimage, 0, 0); source = pimage; // Lock source bitmap in memory BitmapData sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); // Copy image data to binary array int imageSize = sourceData.Stride * sourceData.Height; byte[] sourceBuffer = new byte[imageSize]; Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize); // Unlock source bitmap source.UnlockBits(sourceData); // Create destination bitmap Bitmap destination = new Bitmap(source.Width, source.Height, PixelFormat.Format1bppIndexed); // Lock destination bitmap in memory BitmapData destinationData = destination.LockBits(new Rectangle(0, 0, destination.Width, destination.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed); // Create destination buffer imageSize = destinationData.Stride * destinationData.Height; byte[] destinationBuffer = new byte[imageSize]; int sourceIndex = 0; int destinationIndex = 0; int pixelTotal = 0; byte destinationValue = 0; int pixelValue = 128; int height = source.Height; int width = source.Width; int threshold = 500; // Iterate lines for (int y = 0; y < height; y++) sourceIndex = y * sourceData.Stride; destinationIndex = y * destinationData.Stride; destinationValue = 0; pixelValue = 128; // Iterate pixels for (int x = 0; x < width; x++) // Compute pixel brightness (i.e. total of Red, Green, and Blue values) pixelTotal = sourceBuffer[sourceIndex + 1] + sourceBuffer[sourceIndex + 2] + sourceBuffer[sourceIndex + 3]; if (pixelTotal > threshold) destinationValue += (byte)pixelValue; if (pixelValue == 1) destinationBuffer[destinationIndex] = destinationValue; destinationIndex++; destinationValue = 0; pixelValue = 128; pixelValue >>= 1; sourceIndex += 4; if (pixelValue != 128) destinationBuffer[destinationIndex] = destinationValue; // Copy binary image data to destination bitmap Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize); // Unlock destination bitmap destination.UnlockBits(destinationData); // Dispose of source if not originally supplied bitmap if (source != pimage) source.Dispose(); // Return return destination; /// /// 获取单色位图数据(1bpp),不含文件头、信息头、调色板三类数据。 /// /// private static byte[] getBitmapData() MemoryStream srcStream = new MemoryStream(); MemoryStream dstStream = new MemoryStream(); Bitmap srcBmp = null; Bitmap dstBmp = null; byte[] srcBuffer = null; byte[] dstBuffer = null; byte[] result = null; srcStream = new MemoryStream(GraphBuffer); srcBmp = Bitmap.FromStream(srcStream) as Bitmap; srcBuffer = srcStream.ToArray(); GraphWidth = srcBmp.Width; GraphHeight = srcBmp.Height; //dstBmp = srcBmp.Clone(new Rectangle(0, 0, srcBmp.Width, srcBmp.Height), PixelFormat.Format1bppIndexed); dstBmp = ConvertToGrayscale(srcBmp); dstBmp.Save(dstStream, ImageFormat.Bmp); dstBuffer = dstStream.ToArray(); result = dstBuffer; int bfOffBits = BitConverter.ToInt32(dstBuffer, 10); result = new byte[GraphHeight * RowRealBytesCount]; 读取时需要反向读取每行字节实现上下翻转的效果,打印机打印顺序需要这样读取。 for (int i = 0; i < GraphHeight; i++) int sindex = bfOffBits + (GraphHeight - 1 - i) * RowSize; int dindex = i * RowRealBytesCount; Array.Copy(dstBuffer, sindex, result, dindex, RowRealBytesCount); for (int i = 0; i < result.Length; i++) result[i] ^= 0xFF; catch (Exception ex) throw new Exception(ex.Message, ex); finally if (srcStream != null) srcStream.Dispose(); srcStream = null; if (dstStream != null) dstStream.Dispose(); dstStream = null; if (srcBmp != null) srcBmp.Dispose(); srcBmp = null; if (dstBmp != null) dstBmp.Dispose(); dstBmp = null; return result; #endregion #region LZ77图像字节流压缩方法 private static string CompressLZ77(string text) //将转成16进制的文本进行压缩 string result = string.Empty; char[] arrChar = text.ToCharArray(); int count = 1; for (int i = 1; i < text.Length; i++) if (arrChar[i - 1] == arrChar[i]) count++; result += convertNumber(count) + arrChar[i - 1]; count = 1; if (i == text.Length - 1) result += convertNumber(count) + arrChar[i]; return result; private static string DecompressLZ77(string text) string result = string.Empty; char[] arrChar = text.ToCharArray(); int count = 0; for (int i = 0; i < arrChar.Length; i++) if (isHexChar(arrChar[i])) //十六进制值 result += new string(arrChar[i], count == 0 ? 1 : count); count = 0; //压缩码 int value = GetCompressValue(arrChar[i]); count += value; return result; private static int GetCompressValue(char c) int result = 0; for (int i = 0; i < compressDictionary.Count; i++) if (c == compressDictionary[i].Key) result = compressDictionary[i].Value; return result; private static bool isHexChar(char c) return c > 47 && c < 58 || c > 64 && c < 71 || c > 96 && c < 103; private static string convertNumber(int count) //将连续的数字转换成LZ77压缩代码,如000可用I0表示。 string result = string.Empty; if (count > 1) while (count > 0) for (int i = compressDictionary.Count - 1; i >= 0; i--) if (count >= compressDictionary[i].Value) result += compressDictionary[i].Key; count -= compressDictionary[i].Value; break; return result; private static void InitCompressCode() //G H I J K L M N O P Q R S T U V W X Y 对应1,2,3,4……18,19。 //g h i j k l m n o p q r s t u v w x y z 对应20,40,60,80……340,360,380,400。 for (int i = 0; i < 19; i++) compressDictionary.Add(new KeyValuePair (Convert.ToChar(71 + i), i + 1 )); for (int i = 0; i < 20; i++) compressDictionary.Add(new KeyValuePair(Convert.ToChar(103 + i), (i + 1) * 20)); #endregion
string data = ZebraUnity.BitmapToHex(image, out int to, out int row);
string zpl = string.Format("~DGR:Temp0.GRF,{0},{1},{2}", to, row, data);
cmd.Append(zpl);
cmd.AppendFormat("^FO0,0^XGR:Temp0.GRF,1,1^FS");

打印一个图片的ZPL指令:

^LH0,0^LL80^PW580 ~DGR:Temp0.GRF,5120,32,uK01E07Ci0F038Q03C0F8hJ07818Q01E07hK07818Q01E06hK07818Q01F06hK07C18Q01F06hK07E18Q01F86hK06E18Q01F86hK06E180FC1HFBEI01B86hK067181CF0E71CI019C603F83FE78gV067183870E318I019C6071C18E3gW0639870386398I018E60E0E1CE3gW0639870387398I018E60C0E1CE6gW063D87038H79J018F61C071CE6gW061F87HF8H7BJ018761C070CF6gW061F8FI03HFJ0187E1IF0DF6gW060F87I03HFJ0183E1CI0HFCgW060F87I03DFJ0183E1CI0HFCgW060787I03DEJ0181E1CI0FBCgW0607870183CEJ0181E1C02073CgW0603838301CEJ0180E0E060738gW060381HE018EJ0180E0F0C0738gV01F01807C018CJ01C0607FC0718hR03E0601FH0218zzzzzzkN03C0F8hY01E06i01E06i01F06i01F06i01F86i01F86i01B86H04H03048hQ019C603F83DE78hQ019C6071C18E3hR018E60E0E1CE2hR018E61C0E1CE6hR018761C061CE6hR018761C0F0CF6hR0187E1IF0DF6hR0183E1CI0HFChR0183E1CI0HFChR0181E1CI0F3ChR0181E1C06073ChR0180E0E060738hR0180E070C0738hR03C0603F80718hR024J06zzzzzzoS0781Fi0380EhK0F03EQ03C0ChK07818Q03C0ChK07808Q03E0ChK07C18Q03E0ChK07C18Q03F0ChK07E18Q0370ChK06E18Q0378C07F0HFCFgW06F1803C0HFDEI0H38C0E3871C6gW067180HF0F38EI0H3HC1C1C31C4gW067981C38738CI031HC181C39HCgW063983838738CI031EC381C39HCgW063C8301C7398I030EC381E39HCgW061C8701CH3D8I030FC3HFE1BECgW061E8701CH3D8I0307C38H01HF8gW060F87HFC3BD8I0307C38H01HF8gW060F87I03HFJ0303C38H01E78gW060787I03EFJ0303C38041E78gW060787I01EFJ0301C1C0C0E7gX0603838081CFJ0301C1C180E7gX0603838181CFJ03H0C0HFH0E7gX060181C301C6J0FC0C03EH042gX0F8180FEH0C6zhQ0^FO30,0^XGR:Temp0.GRF,1,1^FS

~DG指令

使用TSC TE344打印机,正常

转自:https://www.cnblogs.com/chuci/p/4462378.html

代码:using System;using System.Collections.Generic;using System.Drawing;using System.Drawing.Imaging;using System.IO;using System.Linq;using System.Runtime.InteropServices;using System.Text;...
实现思路: 1、获取图片的二值化字节数组 这一步是关键 2、将字节数组转为十六进制 3、压缩十六进制字符串 结尾为1、0或者与上一行相同的;相同的连续字符压缩 4、拼凑ZPL编码,宽度需要扩大,因为需要时8个点(1字节)的整数倍 条码名称如下: "CODE 39" "PDF417" "Interleaved 2 of 5" " MaxiCode" "EAN 8""Code11" "UPC-E" "Micro PDF417" "Code93" "Code49" "Code 128" "CoderBar" "EAN 13" "Industrial 2 of 5"
由于公司一个地方需要用到图片转换ZPL格式去打印;这里的ZPL格式是打印斑马打印机,这里面有一些小的地方是需要注意的. 由于斑马打印机的型号不一样,设置不一样,外加自身的图片格式(.jpg,.png的不一样),图片的高度和宽度也不一样,就会直接导致打印出来的东西和你理想中的效果不一样,所以这里就需要设置图片的参数和斑马打印机自身的参数等设置。 然后下面贴出来图片转换为ZPL格式的代码,也可以当...
该篇介绍了Zebra打印机打印中文+英文+图片的方法,如果是单单打印英文的话,可使用Zebra自带指令打印Zebra利用指令绘制出图像打印。还有一篇博客是介绍Zebra三种打印方式的利弊Zebra斑马打印机三种打印方式的利弊 打印机专栏:打印机程序开发(Zebra、TSC、Toshiba) 源码地址:https://download.csdn.net/download/horseroll/10...