当前位置:编程学习 > C#/ASP.NET >>

请教:关于串口针式打印机图像打印的问题

各位,因项目需要,我需要通过连接串口的针式打印机输出图像,
有关这方面的资料太少,现在我只能打印出文字,但是图像打印总是打出一些乱码,让我很苦恼,哪位做过这样的功能,能否指点一二?
目前我的代码如下:
        /// <summary>
        /// 打印位图数据
        /// </summary>
        /// <param name="imageData">位图数据(1位位图,每8个像素为一个字节)</param>
        /// <remarks>
        /// 测试位图宽度 1220 像素,高度 587 像素
        /// 位图数据长度计算: (1220/8 + 1)  = 153 , (153 / 4 +1)*4 = 156 , 156 * 587 = 91572字节
        /// </remarks>
        static void PrintOut(byte[] imageData)
        {
            byte[] cmdBuf = null;
            using (System.IO.Ports.SerialPort sp = new System.IO.Ports.SerialPort(SERIAL_PORT_NAME, 9600))
            {
                sp.Open();
               
                //查询命令状态
                Console.WriteLine("查询命令状态");
                cmdBuf = new byte[] { 0x1B, 0x6A };
                sp.Write(cmdBuf, 0, cmdBuf.Length);
                Thread.Sleep(200);
                if (sp.BytesToRead > 0)
                {
                    byte[] errBuf = new byte[sp.BytesToRead];
                    sp.Read(errBuf, 0, errBuf.Length);
                    Console.WriteLine(System.Text.Encoding.Default.GetString(errBuf));
                    //清错
                    Console.WriteLine("清错");
                    cmdBuf = new byte[] { 0x1B, 0x6C };
                    sp.Write(cmdBuf, 0, cmdBuf.Length);
                }
                

                Console.WriteLine("确定 Olivetti 控制的开始");
                cmdBuf = new byte[] {0x1B,0x6E };
                sp.Write(cmdBuf, 0, cmdBuf.Length);
                Thread.Sleep(200);

                Console.WriteLine("进纸到第2行");
                cmdBuf = new byte[] { 0x1B, 0x4C ,0x30 ,0x30 ,0x32 };
                sp.Write(cmdBuf, 0, cmdBuf.Length);
                Thread.Sleep(200);

                Console.WriteLine("选择24针打印模式");
                cmdBuf = new byte[] { 0x1B ,0x21 ,0x47 ,0x31 };
                sp.Write(cmdBuf, 0, cmdBuf.Length);
                Thread.Sleep(200);
                //
                Console.WriteLine("图形打印控制命令");
                cmdBuf = new byte[] {0x1B ,0x31 ,0x41 ,0x30 ,0x30 ,0x30 };
                sp.Write(cmdBuf, 0, cmdBuf.Length);
                Thread.Sleep(200);
                //
                using (MemoryStream ms = new MemoryStream())
                {
                    ms.Write(imageData, 0, imageData.Length);
                    ms.Position = 0;
                    byte[] buf = new byte[512];
                    while (true)
                    {
                        int read = ms.Read(buf, 0, buf.Length);
                        if (read == 0)
                        {
                            break;
                        }
                        Console.WriteLine(string.Format("已写入图像数据:{0} 字节", ms.Position));
                        sp.Write(buf, 0, read);
                        Thread.Sleep(100);
                    }
                }
                Console.WriteLine("结束图形控制方式并打印已经接收的图形数据");
                cmdBuf = new byte[] { 0x1B, 0x32 };
                sp.Write(cmdBuf, 0, cmdBuf.Length);
                Thread.Sleep(200);

                Console.WriteLine("回车换行,退纸");
                cmdBuf = new byte[] { 0x0D, 0x0A,0x1B,0x4F };
                sp.Write(cmdBuf, 0, cmdBuf.Length);
                Thread.Sleep(200);
                sp.Close();
            }
        }

打印机倒是动作,可是打印出来的东西就完全不是我想要的.
如能提供帮助,感激不尽!
--------------------编程问答-------------------- 都在忙啊? 我自己顶... --------------------编程问答-------------------- 针式打印机好像不支持图像打印 --------------------编程问答-------------------- 楼主看看我的博文吧,希望能帮到你。
http://blog.csdn.net/afeng124/archive/2010/05/20/5610614.aspx
我的不是直接使用esc/pos指令的,是使用北洋的sdk封装好开发包dll来完成的,打印图形调用下载位图再打印的方法。但是我没有全部试过。其实为了保持程序的能适应多种打印机建议使用gdi+来画和打印机使用什么端口无关了。 --------------------编程问答-------------------- 针式打印机每个像素没有浓淡之分

先要把图片进行"半调"处理,才能用针式打印机打出图案 --------------------编程问答-------------------- 感谢你的关注!
你说的GDI+在这个应用场景下是是完全不适用的,厂家不提供WINDOWS的驱动,而且就算有驱动也不行,因为在打印机和计算机中间还有类似与“串易做图换机”的设备(转接盒),而这个盒子需要指令去切换各个端口,所以是行不通的。

引用 3 楼 afeng124 的回复:
楼主看看我的博文吧,希望能帮到你。
http://blog.csdn.net/afeng124/archive/2010/05/20/5610614.aspx
我的不是直接使用esc/pos指令的,是使用北洋的sdk封装好开发包dll来完成的,打印图形调用下载位图再打印的方法。但是我没有全部试过。其实为了保持程序的能适应多种打印机建议使用gdi+来画和打印机使用什么端口无关了。
--------------------编程问答-------------------- 感谢你的关注!

我已经把24位真彩位图(每个像素3个字节,代表R,G,B分量)转换成了色深为1位(全黑或者全白)的位图(8个像素一个字节)。
但是现在就是如何将位图的点阵数据发送给串口的问题(如何组织)。

引用 4 楼 skep99 的回复:
针式打印机每个像素没有浓淡之分

先要把图片进行"半调"处理,才能用针式打印机打出图案
--------------------编程问答-------------------- 问题还没有解决,我贴出代码,哪位帮忙看看错误在哪儿,谢谢了!

        static void PrintOut(byte[] imageData,int stride)
        {
            byte[] cmdBuf = null;
            int lines = imageData.Length / stride; //总长度除列宽(扫描宽度)
            using (System.IO.Ports.SerialPort sp = new System.IO.Ports.SerialPort(SERIAL_PORT_NAME, 9600))
            {
                sp.Open();
                //bla bla bla
                //查询命令状态
                Console.WriteLine("查询命令状态");
                cmdBuf = new byte[] { 0x1B, 0x6A };
                sp.Write(cmdBuf, 0, cmdBuf.Length);
                Thread.Sleep(200);
                if (sp.BytesToRead > 0)
                {
                    byte[] errBuf = new byte[sp.BytesToRead];
                    sp.Read(errBuf, 0, errBuf.Length);
                    Console.WriteLine(System.Text.Encoding.Default.GetString(errBuf));
                    //清错
                    Console.WriteLine("清错");
                    cmdBuf = new byte[] { 0x1B, 0x6C };
                    sp.Write(cmdBuf, 0, cmdBuf.Length);
                }

                Console.WriteLine("复位");
                cmdBuf = new byte[] { 0x1B, 0x30};
                sp.Write(cmdBuf, 0, cmdBuf.Length);
                Thread.Sleep(100);

                Console.WriteLine("确定 Olivetti 控制的开始");
                cmdBuf = new byte[] {0x1B,0x6E };
                sp.Write(cmdBuf, 0, cmdBuf.Length);
                Thread.Sleep(100);

                Console.WriteLine("设定页长为687行");
                cmdBuf = new byte[] { 0x1B ,0x51 ,0x35 ,0x38 ,0x37 ,0x1B ,0x5A };
                sp.Write(cmdBuf, 0, cmdBuf.Length);
                Thread.Sleep(100);

                Console.WriteLine("进纸到第1行");
                cmdBuf = new byte[] { 0x1B, 0x4C ,0x30 ,0x30 ,0x31 };
                sp.Write(cmdBuf, 0, cmdBuf.Length);
                Thread.Sleep(200);

                
                for (int i = 0; i < lines; i++)
                {
                    cmdBuf = new byte[] { 0x1B, 0x31, 0x41, 0x30, 0x30, 0x30 };
                    sp.Write(cmdBuf, 0, cmdBuf.Length); //图形打印控制命令
                    Thread.Sleep(50);
                    byte[] lineData = new byte[stride];
                    Array.Copy(imageData, i * stride, lineData, 0, stride);

                    Console.WriteLine("选择24针打印模式");
                    cmdBuf = new byte[] { 0x1B, 0x21, 0x47, 0x31 };
                    sp.Write(cmdBuf, 0, cmdBuf.Length);
                    Thread.Sleep(100);

                    //图形数据
                    sp.Write(lineData, 0, lineData.Length);
                    Thread.Sleep(50);
                    //打印输出
                    cmdBuf = new byte[] { 0x1B, 0x32 };
                    sp.Write(cmdBuf, 0, cmdBuf.Length);
                    Thread.Sleep(50);
                    //换行
                    cmdBuf = new byte[] { 0x0D, 0x0A};
                    sp.Write(cmdBuf, 0, cmdBuf.Length);
                    Thread.Sleep(50);
                }
                Console.WriteLine("退纸");
                cmdBuf = new byte[] { 0x1B, 0x4F };
                sp.Write(cmdBuf, 0, cmdBuf.Length); 
                Thread.Sleep(200);
                sp.Close();
            }
        } --------------------编程问答-------------------- 不知道你解决了没有。图像数据的传输是这样的,你把点图看成一个屏幕,这个屏幕的高是确定的,8位或者24。然后你的图像从上往下,数8位数据,搞成一个byte,一个byte的每一位,对应这8个数据,有点,为1.按8位,一行一行的这样扫描,然后打印。

如果是24,还是8位,再下8位,再下8位,然后上来,第二列的,8位,下8位,再下8位。

不过这样打印,速度太慢了。怎么提高打印速度,是我现在很想解决的问题。
补充:.NET技术 ,  C#
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,