最近在项目中接手了一个比较有挑战性的模块——用斑马打印机将需要打印的内容打印出来。苦苦折腾了两天,总算有所收获,就发到网上来骗骗分数-_-||

项目中使用的打印机型号为GX430t的打印机,接手的时候,自己对于打印机这块儿是眼前一抹黑,啥都不知道。没办法一步步来。

首先尝试使用WPF中的PrintDialog里面的PrintVisual和PrintDocument方法,打印机是一点反应都没有,最后得到的结论是:斑马打印机不支持MS的XPS文档格式,所以使用WPF来排版后进行驱动打印就不要想了,不可能!!!这条路到这里就断了。

然后就想到有没有SDK可以直接进行打印,就找到了斑马打印机的技术支持,还是个妹子,我提了一下,妹子说没有开发包可以用,然后就贴了一个网址给我,网址就是这条:http://blog.csdn.net/ldljlq/article/details/7338772。可能我的水平有限,反正我感觉啰啰嗦嗦一大堆,实际的东西没多少,不过关键点倒是提了出来使用图像或者指令进行打印。我首先想到的是使用指令进行打印,就去找妹子要了Zebra的技术手册,一打开就吓尿了,尼玛1000+页的东西,我只是用一下打印机又不是去帮你们打印机开发驱动,当时心里那个抵触啊。但是没办法,得看呐,就仔细看了一些,找到打印的指令试了试,有东西能打出来,当时感觉挺满足的。唯一比较纠结的就是打印机支持的字体和字体本身的一些设置,比如粗体、斜体等等,资料里面没找到,然后去问了下斑马的技术支持,得知斜体字可以打,但是不清楚有没有对应的指令。没办法,项目里面用的字体多,还有各种斜体神马的,玩WPF的都知道,那么多属性一个个设置下来,光字体类型斑马就搞不定。

既然直接使用指令打印行不通就考虑使用图像打印,图像又跟多媒体挂钩了,尼玛真是够了。因为玩过链接里面的仁兄提到的获取打印模板的命令的方法。就是在安装好打印机驱动后,手动创建一个新的本地端口并在打印机设置中将打印机端口设为新建的端口。使用Zebra的创建模板的软件创建好你想要的东西,然后打印,就能在你创建的端口文件中得到你想要的指令序列(其实,模板里面使用的就是图像打印)。指令序列有了,对照手册查询相应的指令就能得到你想要的东西。

这里说的图像打印并不是我们平时说的位图或者矢量图,手册里面说是叫GRF格式的图像,仔细研究了一下,其实就是缀着这么个名字而已,里面需要的数据其实就是图像矩阵。而且图像矩阵中的像素表示法是:一个字节表示8个像素,也就是一个bit位(0或1)表示一个像素的颜色(黑或白)。看到这里脑子里有了思路:将要打印的内容进行排版->将排版好的数据转换成位图->将位图中的数据,根据需要转换成指令中要求的格式->交给打印机打印。这样一来就没有什么打印机对字体本身的限制了。思路有了,剩下的就是方法。

排版比较简单,这个玩过自定义控件的人都知道,使用DrawingVisual可以构建自己想要的Visual。然而将Visual转换成位图就难住我了,纠结了一个下午终于从网上找到了一个东西----RenderTargetBitmap。这个类可以将你的Visual转换成位图。

下面就是将位图数据转换成指令中的图像数据,咳咳,数学不够好,在分析数据的时候搞错了一个地方让我纠结了好长时间,不过总体来说还是解决了。说一下思路:

  1. 通过RenderTargetBitmap类的CopyPixels方法将像素数据拷贝出来。因为这个位图创建的时候只是作为一个中间的过程,所以格式可以随便选,我是选择了PixelFormats.Pbgra32格式,比较简单。这个格式的图像像素是用4个字节表示,依次为:Blue、Green、Red、Alpha。拷贝的时候,作为缓冲区的数组需要将长度设为像素数的4倍。
  2. 像素拷贝的时候会有一个“跨距”的东西。这个表示的是图像中一行中数据的字节数,必须为4的倍数。也就是取大于或等于真实值的最小的能够被4整除的数值。
  3. 获取到数据就可以对数据进行整理了,遍历整个数组,如果当前像素的颜色值不为白色或者透明色就将目标数组中的bit位之一(目标数组中用bit位表示对应像素的值)
  4. 将获得的数组转换成string串,然后将该串插入到指令序列中相应的位置就得到对应的指令。

说到这里其实说的也差不多了,顺便说下,WPF里面的打印支持真的很强大,给打印机传递指令的操作也很简单,具体见下面的代码。

这里是源代码:

/// <summary> 
        /// 获取绘制Visual的命令 
        /// </summary> 
        /// <param name="visual">要获取的Visual</param> 
        /// <param name="pixelWidth">像素宽度</param> 
        /// <param name="pixelHeight">像素高度</param> 
        /// <param name="dpiX">横向dpi</param> 
        /// <param name="dpiY">纵向dpi</param> 
        /// <param name="offsetX">横坐标偏移量,单位为像素数</param> 
        /// <param name="offsetY">纵坐标偏移量,单位为像素数</param> 
        /// <returns></returns> 
        private string GetPrintZPL(Visual visual, int pixelWidth, int pixelHeight, double dpiX, double dpiY, int offsetX, int offsetY) 
        { 
            string ret = string.Empty; 
            //构建图片 
            RenderTargetBitmap bmp = new RenderTargetBitmap(pixelWidth, pixelHeight, dpiX, dpiY, PixelFormats.Pbgra32); 
#if TEST //test 
            DrawingVisual newVisual = new DrawingVisual(); 
            DrawingContext dc = newVisual.RenderOpen(); 
            dc.DrawEllipse(Brushes.Black, new Pen(), new Point(bmp.Width / 2, bmp.Height / 2), bmp.Width / 2, bmp.Height / 2); 
            dc.Close(); 
            visual = null; 
            bmp.Render(newVisual); 
#else 
            bmp.Render(visual); 
#endif 
            byte[] datas = new byte[bmp.PixelWidth * bmp.PixelHeight * 4]; 
            bmp.CopyPixels(datas, bmp.PixelWidth * 4, 0);//获取图像数据 
            int rowBytes = (pixelWidth + 7) / 8; 
            byte[] targetDatas = new byte[rowBytes * bmp.PixelHeight]; 
            for (int i = 0; i < bmp.PixelHeight; i++) //数据调整,并将数据 
            { 
                for (int j = 0; j < bmp.PixelWidth; j++) 
                { 
                    byte blue = datas[i * bmp.PixelWidth * 4 + j * 4 + 0]; 
                    byte green = datas[i * bmp.PixelWidth * 4 + j * 4 + 1]; 
                    byte red = datas[i * bmp.PixelWidth * 4 + j * 4 + 2]; 
                    byte alpha = datas[i * bmp.PixelWidth * 4 + j * 4 + 3]; 
                    if (blue == 0 && green == 0 && red == 0) 
                    { 
                        if (alpha == 255)//alpha也是0则为透明色 
                        { 
                            byte cur = 1; 
                            cur = (byte)(cur << (7 - j % 8)); 
                            targetDatas[i * rowBytes + j / 8] |= cur; 
                        } 
                    } 
                    else 
                    { 
                        if (!(blue == 255 && green == 255 && red == 255 && alpha == 255))//全为255则表示白色 
                        { 
                            byte cur = 1; 
                            cur = (byte)(cur << (7 - j % 8)); 
                            targetDatas[i * rowBytes + j / 8] |= cur; 
                        } 
                    } 
                } 
            } 
            ret = string.Format("^XA~TA000~JSN^LT0^MNW^MTT^PON^PMN^LH0,0^JMA^PR3,3~SD29^JUS^LRN^CI0^XZ~DG000.GRF,{0},{1},{2}^XA^MMT^PW260^LL0189^LS0^FT0,192^FO{3},{4},^XG000.GRF,1,1^FS^PQ1,0,1,Y^XZ^XA^ID000.GRF^FS^XZ", targetDatas.Length, rowBytes, BitConverter.ToString(targetDatas).Replace("-", string.Empty), offsetX, offsetY); 
            return ret; 
        }

基于C#在WPF中使用斑马打印机进行打印相关推荐

  1. 基于C#在WPF中使用斑马打印机进行打印【转】

    原文链接:http://ju.outofmemory.cn/entry/132476 最近在项目中接手了一个比较有挑战性的模块--用斑马打印机将需要打印的内容打印出来.苦苦折腾了两天,总算有所收获,就 ...

  2. ZPL指令打印 斑马打印机指令打印

    首先ZPL(Zebra Programming language)是斑马家搞的ZPL语言,用于和打印机通讯打印开发的指令.然后理解了这个只是个指令的东西后,我们接着就想想怎么弄,本着怎么简单怎么来的原 ...

  3. 斑马打印机怎么打印二维码_简单介绍斑马打印机---GX430t

    斑马条码打印机GX430t产品特点: 1.斑马高清打印头,打印更清晰 2.自动测纸,告别繁琐测纸步骤 3.防静电刷,有效保护打印头 4.外观大方,操作便捷易用 5.可移动式感应器,适用不同形状标签 6 ...

  4. 斑马打印机(zebraZT410R-203dpi)打印RFID标签流程

    1.首先连接到打印机 下面代码为连接打印机的代码,其中ip为打印机ip地址, "TcpConnection.DEFAULT_CPCL_TCP_PORT"的值为6101. publi ...

  5. Zebra 斑马打印机如何打印中文参数

    要实现ZPL打印中文,首先需要zebra打印机加载SIMSUN.TTF(宋体),然后在ZPL中编码使用UTF-8的encoding来打印,类似如下: ^XA #标签的开始 ^CW1,E:SIMSUN. ...

  6. MFC中获取指定打印机的打印队列的方法

    void CPrintListTestDlg::OnBnClickedButton1() {GetDlgItem(IDC_TxtList)->SetWindowText(L"" ...

  7. 斑马打印机怎么打印二维码_万能打印机厂家是怎么改良打印机的?

    一个好的万能打印机厂家是不断优化自己的产品,生产出性价比更高的UV平板打印机,本文就说说万能打印机厂家是怎么改良打印机的? 一.万能打印机厂家是怎么改良打印机的? 1.改良万能打印机精度 改装精度有两 ...

  8. 斑马打印机-中文打印

    中文打印 通常有两种方式  1.使用字体库,代价高,使用简单速度快  2.通过图片方式打印,免费使用,速度适中 官方有下载Fnthex32.dll    https://download.csdn.n ...

  9. 斑马打印机打印不出来字怎么解决

    在条码打印软件中制作标签的时候,有的时候标签内容比较多,可能不注意就在标签上或者数据源中添加了一个空对象,也没预览,就直接连接斑马打印机进行打印了.最后发现,点击打印之后,斑马打印机没反应,咨询是怎么 ...

最新文章

  1. Docker1.12让容器使用和宿主机同一个网段
  2. [Python爬虫] 之五:Selenium 处理滚动条
  3. 记一次validator jar冲突导致的启动异常
  4. MMDetection-简介
  5. win7系统怎样打开音频服务器,win7系统打开音频管理器的具体教程
  6. go mongodb排序查询_《MongoDB》day two
  7. Java多线程系列--“JUC锁”07之 LockSupport
  8. 设计Whats App
  9. gcd常见结论及gcd与斐波那契结合--hdu6363.
  10. bzoj 1202: [HNOI2005]狡猾的商人(带权并查集)
  11. 计算原矩阵Jaccard相似度和签名矩阵的Jaccard相似度
  12. 计算机二级12套excel操作题答案,计算机二级MSOffice操作题及答案
  13. 用cocos studio生成plist文件
  14. 如何测试计算机的运行速度,如何查看cpu运行速度
  15. linux系统文件夹
  16. 腾讯企业邮箱免费申请 mail-tencent.com
  17. 通过Teardrop学习网络通信编程
  18. PG数据库查看数据大小参考
  19. opencv传统分割算法总结(多边形拟合,水平投影,直线检测)
  20. 天线理论巴拉尼斯_天线理论与技术 - 心理学书籍 psychspace.com/钟顺时/

热门文章

  1. 虚拟服务器不能打字,光遇修理服务器,玩家无法打字聊天,如何用“光语”说我爱你?...
  2. cisco Switching-三层交换配置路由
  3. 高等数学——求解不定积分的经典换元法
  4. 常微分方程的解法 (四): Matlab 解法
  5. iOS 开发 : 14个技巧助你适配 iOS10
  6. 费雪耶兹(Fisher–Yates) 也被称作高纳德( Knuth)随机置乱算法
  7. 苹果分屏软件_苹果 | iOS13来了,老iPhone再战一年
  8. 相似度算法--莱文斯坦距离加入同义词逻辑
  9. linux下同一个tomcat部署多个项目
  10. JVM-04-运行时数据区-堆,方法区