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

原文连接:http://ju.outofmemory.cn/entry/132476数组

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

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

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

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

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

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

排版比较简单,这个玩过自定义控件的人都知道,使用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里面的打印支持真的很强大,给打印机传递指令的操做也很简单,具体见下面的代码。get

这里是源代码:

/// <summary>         /// 获取绘制Visual的命令         ///</summary>         /// <paramname=”visual”>要获取的Visual</param>         /// <paramname=”pixelWidth”>像素宽度</param>         /// <paramname=”pixelHeight”>像素高度</param>         /// <paramname=”dpiX”>横向dpi</param>         /// <paramname=”dpiY”>纵向dpi</param>         /// <paramname=”offsetX”>横坐标偏移量,单位为像素数</param>         /// <paramname=”offsetY”>纵坐标偏移量,单位为像素数</param>         ///<returns></returns>         private string GetPrintZPL(Visualvisual, int pixelWidth, int pixelHeight, double dpiX, double dpiY, int offsetX,int offsetY)         {             string ret = string.Empty;            //构建图片             RenderTargetBitmap bmp = newRenderTargetBitmap(pixelWidth, pixelHeight, dpiX, dpiY, PixelFormats.Pbgra32);#if TEST //test             DrawingVisual newVisual = newDrawingVisual();             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);//获取图像数据             introwBytes = (pixelWidth + 7) / 8;             byte[] targetDatas = newbyte[rowBytes * bmp.PixelHeight];             for (int i = 0; i <bmp.PixelHeight; i++) //数据调整,并将数据             {                 for (intj = 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;        }

相关文章
相关标签/搜索