​写在前面

今天的主题就是用Zebra斑马打印机打印一个贺卡标签。

Zebra介绍

既然是贺卡,应该是非常漂亮的,但是这个Zebra打印机好像只能打印黑白的,所以就简单制作了一下。

工业上在批量打印商品标签时,一般都要加上条码或图片,一般使用Zebra斑马打印机比较多。而C#调用斑马打印机的方式也有很多种,包括串口COM、以太网TCP、并口LPT以及USB等,对于设计标签的方式也有很多种方式,比如Zebra提供了一个设计软件Zebra Designer,还可以使用第三方软件如Bartender,当然我们还可以自己通过GDI+技术进行绘制。

本例采用的方式是利用GDI+进行绘制,然后将图像转换成字节,通过DG和XG指令发送给打印机,通信使用的是打印机自带的USB接口。

图像绘制

首先通过GDI+绘制一张图像,图像的大小要根据实际标签大小进行调试,绘制内容可以是图像、字符串等,或者是条形码、二维码都可以,其实条形码及二维码也是属于图像。

        private void btn_Paint_Click(object sender, EventArgs e){//开始绘制图片int imageWidth = 900;int imageHeight = 600;bitmap = new Bitmap(imageWidth, imageHeight);//创建GraphicsGraphics graphics = Graphics.FromImage(bitmap);//呈现质量graphics.SmoothingMode = SmoothingMode.AntiAlias;//背景色graphics.Clear(Color.White);//字体Font myFont = new Font("楷体", 32, FontStyle.Bold);//文字颜色Brush brush = new SolidBrush(Color.Black);//调整间距int start = 145;       int gap = 80;graphics.DrawString("祝全天下的母亲——母亲节快乐", myFont, brush, 50, 50);graphics.DrawString("《游子吟》【唐】孟郊", myFont, brush, 50, start);graphics.DrawString("慈母手中线,游子身上衣", myFont, brush, 50, start + gap);graphics.DrawString("临行密密缝,意恐迟迟归", myFont, brush, 50, start + gap * 2);graphics.DrawString("谁言寸草心,报得三春晖", myFont, brush, 50, start + gap * 3);graphics.DrawString("署名:" + this.txt_Name.Text.Trim(), myFont, brush, 50, start + gap * 4 + 20);//生成二维码Image codeImage = BarCodeHelper.GenerateQRCode("https://ke.qq.com/course/301616", 220, 220);Bitmap pbitmap = new Bitmap(codeImage);pbitmap.MakeTransparent(Color.Transparent);graphics.DrawImage(pbitmap, 630, 338, 220, 220);//显示图形this.mainPic.Image = bitmap;}

编写好代码之后,将图像用一个PictureBox控件显示出来,结果如下:

图像处理

生成图像之后,接着将图像转换成字节数组或者字符串,便于后续直接发送给打印机,这里的代码是在网上找的,

    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);BitmapData bmpData = grayBmp.LockBits(rect, 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;}}}// 将位图数据转换为16进制的ASCII字符          string zplString = BitConverter.ToString(ImgData);zplString = CompressLZ77(zplString.Replace("-", string.Empty));totalBytes = bitmapDataLength;rowBytes = stride;return zplString;}

调用打印机

调用打印机使用的是winspool.drv,这个库里提供了很多操作打印机的方法。

            [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool ClosePrinter(IntPtr hPrinter);[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool EndDocPrinter(IntPtr hPrinter);[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool StartPagePrinter(IntPtr hPrinter);[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool EndPagePrinter(IntPtr hPrinter);[DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);

基于这些方法,封装一个将字符串发送给打印机的方法:

            public  bool SendStringToPrinter(string szPrinterName, string szString){try{IntPtr pBytes;Int32 dwCount;// 获取字符串长度  dwCount = szString.Length;// 将字符串复制到非托管 COM 任务分配的内存非托管内存块,并转换为 ANSI 文本pBytes = Marshal.StringToCoTaskMemAnsi(szString);// 将已转换的 ANSI 字符串发送到打印机bool res = SendBytesToPrinter(szPrinterName, pBytes, dwCount);// 释放先前分配的非托管内存Marshal.FreeCoTaskMem(pBytes);return res;}catch (Win32Exception ex){WriteLog(ex.Message);return false;}}

最后在打印按钮下,组织相关命令,调用这个方法即可:

        private void btn_Print_Click(object sender, EventArgs e){int total = 0;int row = 0;string hex = ZebraUnity.BitmapToHex(bitmap, out total, out row);                    string modecmd = "~DGR:ZLOGO.GRF," + total.ToString() + "," + row.ToString() + "," + hex;//将图片生成模板指令ZebraGesigner.PrintCode.SendStringToPrinter("ZDesigner ZT210", modecmd);string cmd = "^XA^FO0,0^XGR:ZLOGO.GRF,1,1^FS^XZ";//调用该模板指令ZebraGesigner.PrintCode.SendStringToPrinter("ZDesigner ZT210", cmd);//发送调用模板指令}

最终结果

下面这个就是最终打印的结果:

小彩蛋:你们扫扫二维码看看是什么呢?

用Zebra打印机制作一个节日贺卡相关推荐

  1. 计算机设计贺卡教案,制作一个多媒体贺卡教案设计

    [课题]制作一个多媒体贺卡 [课时]1课时 [教法]任务驱动.小组合作 [教学环境]多媒体网络教室 [教材分析] 本课以任务驱动的形式介绍了制作多媒体贺卡的全过程.本课综合了第3单元和第4单元的内容, ...

  2. scratch优秀案例分享:母亲节制作一个动画贺卡

    母亲节(Mother's Day),是一个感谢母亲的节日.现代的母亲节起源于美国,是每年5月的第二个星期日.母亲们在这一天通常会收到礼物,康乃馨被视为献给母亲的花,而中国的母亲花是萱草花,又叫忘忧草. ...

  3. 微信小程序|使用小程序制作一个节日祝福生成器

    一.前言 不知不觉间还有几天就是新的一年了,值此佳节祝福语肯定也是必不可少,毕竟难得有机会能给ta发消息,ta会不会也在想终于又能给你回消息呢.跟随此文使用小程序制作一个祝福语生成器,让你的祝福脱颖而 ...

  4. vb 设置打印机 任意尺寸_【高训智造】原创专业课堂第307期——FDM桌面3D打印机制作笔筒...

    点击蓝字关注我们 欢迎来到[高训智造]原创专业课堂第307期,由钟观友老师给大家带来3D打印小课堂. FDM桌面3D打印机制作笔筒 钟观友 FDM桌面打印机及其材料都较为经济,是制作小生活用品和玩具模 ...

  5. 计算机制作节日贺卡教案,制作节日贺卡之教学设计

    <制作节日贺卡之教学设计>由会员分享,可在线阅读,更多相关<制作节日贺卡之教学设计(2页珍藏版)>请在人人文库网上搜索. 1.制作节日贺卡之教学设计 制作节日贺卡之教学设计 一 ...

  6. 计算机制作节日贺卡教案,节日贺卡教案

    贺 卡 教学目标:1.认知目标:通过欣赏各种有特色的贺卡,开阔学生的视野,培养审美意识. 2.操作目标:学生能选择身边的各种材料,大胆地设计.制作贺卡,体验绘制的乐趣. 3.情感目标:了解贺卡能丰富人 ...

  7. 用Coreldraw制作节日贺卡(转)

    用Coreldraw制作节日贺卡(转)[@more@] 当今通讯科技发展迅速,电话.E-MAIL的往来问候虽然更加迅速但却无法替代信笺间流露的亲情和爱意.如果能自己制作一张小小的贺卡,虽然只言片语,但 ...

  8. 计算机制作节日贺卡教案,《节日贺卡自己做》说课稿

    <节日贺卡自己做>说课稿 [一.紧扣特点说教材] 选用教材:初级中学信息技术教材华科大版一年级下. 教材特点:专题编排为主.强调集团性.趣味性. 本节教材整合了语文.美术等诸学科元素.在图 ...

  9. 快过年了,来分享一个个人制作的节日祝福软件

    扫下面二维码,即可下载使用: (马云巴巴发福利,支付宝搜索619015079领红包) 个人想着过年了,要发祝福短信之类的,于是想着想着,就自己动手随便弄了一个小小的祝福软件,功能很简单,供大家开心发祝 ...

最新文章

  1. 《漫画算法》源码整理-1 时间复杂度 空间复杂度
  2. 【性能】模糊查询性能提升
  3. Java手机忘了密码怎么办_手机开机密码忘记了怎么办
  4. Java基础—复制之深拷贝与浅拷贝
  5. 【BZOJ 4671】异或图 【斯特林反演】【线性基】【贝尔数复杂度】
  6. 操作系统上机题目(多线程2)
  7. 2018-2019-2 网络对抗技术 20165303 Exp4 恶意代码分析
  8. 如何利用全站加速,提升网站性能和用户体验?
  9. 雷军正式入驻B站,或为小米新品直播带货做准备
  10. 迪士尼正式收购21世纪福克斯!网友:原来米老鼠才是灭霸…
  11. 【驱动】linux设备驱动·字符设备驱动开发
  12. 14.bash(2) 与 环境变量
  13. 盛大谭群钊演讲:未来的中国游戏业
  14. 使用Python对比两个excel表格中的重复数据
  15. go.php外链跳转模板,给WordPress博客添加外链go跳转效果
  16. 如何在Windows11安装安卓子系统?
  17. 困境下的SEO,站长如何自渡?
  18. Pettitt突变点检测
  19. 通达OA工作流-流程设计
  20. python用表格中的数据画柱状图_[python]统计excel表格某列中每项出现的次数并画柱状图...

热门文章

  1. 【网络】IP、域名、端口号和DNS域名解析之间的联系简介(给服务器添加域名来验证)
  2. Could not GET 'http://jcenter.bintray.com/com/github/dcendents/android-maven-gradle-plugin/2.1/andro
  3. legacy引导gpt分区_legacy支持gpt吗
  4. 爱我,是不是因为怜悯
  5. rssi室内定位算法原理_RSSI的室内人员卡尔曼滤波定位算法
  6. 如何通过“云之讯”平台,完成短信的发送
  7. 创业者2012必看十大文章(6)
  8. 本地同城地方门户网这样运营轻轻松松拿到5W广告费
  9. 路由dns劫持,路由器DNS劫持简单实现和防范分析
  10. 18天精读掌握《费曼物理学讲义卷一》 第14天 2019/6/30