zoukankan      html  css  js  c++  java
  • [条码打印]使用斑马语言(ZPL)打印汉字

    默认情况下条码打印机是不能打印汉字的, 不过条码打印机是支持上传自定义字体的, 但是这个字体库跟windows里面的字体库肯定不是一回事, 起初我觉得最好能通过上传字体来实现打印汉字, 但是大概研究了一下, 发现这个太复杂, 而且字体库文件也无从搞到, 所以换了方向, 考虑将汉字画成图片, 通过打印图片的方式来实现打印汉字.

    所以总的过程为: 将需要打印的汉字在服务器上通过GDI画成图片, 然后将图片按照条码打印机的要求序列化成字符串上传到打印机, 最后通过打印图片命令将其打印出来.

    具体的实现方式为:

    1. 绘图.

    protected Bitmap CreateImage(string data, Font f) 
    { 
        if (string.IsNullOrEmpty(data)) 
            return null; 
        var txt = new TextBox(); 
        txt.Text = data; 
        txt.Font = f; 
        //txt.PreferredSize.Height只能取到一行的高度(连边距) 
        //所以需要乘以行数, 但是必须先减掉边距, 乘了以后,再把边距加上. 
        //5是目测的边距 
        var image = new Bitmap(txt.PreferredSize.Width, (txt.PreferredSize.Height - 5) * txt.Lines.Length + 5); 
        var g = Graphics.FromImage(image); 
        var b = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Black, Color.Black, 1.2f, true); 
        g.Clear(System.Drawing.Color.White); 
        g.DrawString(data, f, b, 1, 1); 
        return image; 
    } 

    将需要打印的汉字和字体作为参数传入, 即可得到一副图片.

    2. 转换并序列化图片.

    protected string ConvertImageToCode(Bitmap img) 
    { 
        var sb = new StringBuilder(); 
        long clr = 0, n = 0; 
        int b = 0; 
        for (int i = 0; i < img.Size.Height; i++) 
        { 
            for (int j = 0; j < img.Size.Width; j++) 
            { 
                b = b * 2; 
                clr = img.GetPixel(j, i).ToArgb(); 
                string s = clr.ToString("X");
    
                if (s.Substring(s.Length - 6, 6).CompareTo("BBBBBB") < 0) 
                { 
                    b++; 
                } 
                n++; 
                if (j == (img.Size.Width - 1)) 
                { 
                    if (n < 8) 
                    { 
                        b = b * (2 ^ (8 - (int)n));
    
                        sb.Append(b.ToString("X").PadLeft(2, '0')); 
                        b = 0; 
                        n = 0; 
                    } 
                } 
                if (n >= 8) 
                { 
                    sb.Append(b.ToString("X").PadLeft(2, '0')); 
                    b = 0; 
                    n = 0; 
                } 
            } 
            sb.Append(System.Environment.NewLine); 
        } 
        return sb.ToString();
    
    } 
    
    

    这是将图片转换为条码打印机能够支持的点阵图.

    3. 通过ZPL将图片上传:

    var t = ((img.Size.Width / 8 + ((img.Size.Width % 8 == 0) ? 0 : 1)) * img.Size.Height).ToString(); 
    var w = (img.Size.Width / 8 + ((img.Size.Width % 8 == 0) ? 0 : 1)).ToString(); 
    string zpl = string.Format("~DGR:imgName.GRF,{0},{1},{2}", t, w, imgCode);

    其中, img是上述CreateImage函数的返回结果. imgCode是ConvertImageToCode函数的返回结果. imgName是随便起的图片名字.

    这样, 就可以通过继续向zpl添加绘图命令来打印汉字了.

    例如, 以下一段示例代码:

    ^XA
    ^FO10,10
    ^XGR:imgName.GRF,1,1^FS
    ^XZ

    具体如何将zpl指令发送到打印机, 请参考我以前的一篇文章:

    http://www.cnblogs.com/Moosdau/archive/2009/10/16/1584627.html

    ---------------------------------------------

    作者:夏狼哉
    博客:http://www.cnblogs.com/Moosdau

    如需引用,敬请保留作者信息,谢谢

  • 相关阅读:
    多项式多点求值和插值
    Java Dao设计模式
    (转)HTTP长连接和短连接
    JavaScript——this关键字
    JavaScript——Prototype详探
    JavaScript——特殊点总结
    JavaScript——正则表达式
    JavaScript——Window对象
    JavaScript——this、constructor、prototype
    JavaScript——事件模型
  • 原文地址:https://www.cnblogs.com/Moosdau/p/2001404.html
Copyright © 2011-2022 走看看