通过C#中的comport将位图图像打印到pos打印机

时间:2012-12-31 08:19:42

标签: c#

我是按照以下方式通过串口直接将收据打印到POS打印机上,

        SerialPort port = new SerialPort("com6", 9100, Parity.None, 8, StopBits.One);
        port.Open();
        port.Write("Some Text");
        port.Close();

我的问题是如何使用上述方法打印位图图像?任何帮助都会很感激。

我还没决定使用Microsoft POS for.net,因为它很慢并且需要时间来初始化打印机,客户不喜欢等待。

感谢。

3 个答案:

答案 0 :(得分:21)

这应该会从位图中获取一个您可以发送到打印机的字符串:

    public string GetLogo()
    {
        string logo = "";
        if (!File.Exists(@"C:\bitmap.bmp"))
            return null;
         BitmapData data = GetBitmapData(@"C:\bitmap.bmp");
         BitArray dots = data.Dots;
         byte[] width = BitConverter.GetBytes(data.Width);

         int offset = 0;
         MemoryStream stream = new MemoryStream();
         BinaryWriter bw = new BinaryWriter(stream);

         bw.Write((char)0x1B);
         bw.Write('@');

         bw.Write((char)0x1B);
         bw.Write('3');
         bw.Write((byte)24);

         while (offset < data.Height)
         {
             bw.Write((char)0x1B);
             bw.Write('*');         // bit-image mode
             bw.Write((byte)33);    // 24-dot double-density
             bw.Write(width[0]);  // width low byte
             bw.Write(width[1]);  // width high byte

             for (int x = 0; x < data.Width; ++x)
             {
                 for (int k = 0; k < 3; ++k)
                 {
                     byte slice = 0;
                     for (int b = 0; b < 8; ++b)
                     {
                         int y = (((offset / 8) + k) * 8) + b;
                         // Calculate the location of the pixel we want in the bit array.
                         // It'll be at (y * width) + x.
                         int i = (y * data.Width) + x;

                         // If the image is shorter than 24 dots, pad with zero.
                         bool v = false;
                         if (i < dots.Length)
                         {
                             v = dots[i];
                         }
                         slice |= (byte)((v ? 1 : 0) << (7 - b));
                     }

                     bw.Write(slice);
                 }
             }
             offset += 24;
             bw.Write((char)0x0A);
         }
         // Restore the line spacing to the default of 30 dots.
         bw.Write((char)0x1B);
         bw.Write('3');
         bw.Write((byte)30);

         bw.Flush();
         byte[] bytes = stream.ToArray();
         return logo + Encoding.Default.GetString(bytes);
    }

    public BitmapData GetBitmapData(string bmpFileName)
    {
        using (var bitmap = (Bitmap)Bitmap.FromFile(bmpFileName))
        {
            var threshold = 127;
            var index = 0;
            double multiplier = 570; // this depends on your printer model. for Beiyang you should use 1000
            double scale = (double)(multiplier/(double)bitmap.Width);
            int xheight = (int)(bitmap.Height * scale);
            int xwidth = (int)(bitmap.Width * scale);
            var dimensions = xwidth * xheight;
            var dots = new BitArray(dimensions);

            for (var y = 0; y < xheight; y++)
            {
                for (var x = 0; x < xwidth; x++)
                {
                    var _x = (int)(x / scale);
                    var _y = (int)(y / scale);
                    var color = bitmap.GetPixel(_x, _y);
                    var luminance = (int)(color.R * 0.3 + color.G * 0.59 + color.B * 0.11);
                    dots[index] = (luminance < threshold);
                    index++;
                }
            }

            return new BitmapData()
            {
                Dots = dots,
                Height = (int)(bitmap.Height*scale),
                Width = (int)(bitmap.Width*scale)
            };
        }
    }

    public class BitmapData
    {
        public BitArray Dots
        {
            get;
            set;
        }

        public int Height
        {
            get;
            set;
        }

        public int Width
        {
            get;
            set;
        }
    }

答案 1 :(得分:0)

此时可能没用,但我认为要直接打印到打印机,你必须找到编程手册并发送命令转义。

这种打印机有自己的命令集等,可以格式化,旋转文本,打印条形码,上传和打印图像等。

在您不了解语言并正确使用之前,打印机的行为可能无法预测

答案 2 :(得分:-7)

我找到了另一种方式,Guyz请传播这个词!

第1步:

下载NV图像软件(nv_image_tool_v3.1.6)并将图像设置为打印机VIA Comport 按照图像执行这些步骤 enter image description here

第2步:您喜欢的按钮的代码:

 private void button1_Click(object sender, EventArgs e)
{
 SerialPort port = new SerialPort("com6", 9100, Parity.None, 8, StopBits.One);
 port.Open();
 ASCIIEncoding ascii = new ASCIIEncoding();
 port.Write(ascii.GetString(new byte[] { 28, 112, 1, 0})); //Printing the Above uploaded Logo
 port.WriteLine("Your Text");
 port.Close();
}