请教:关于串口针式打印机图像打印的问题
各位,因项目需要,我需要通过连接串口的针式打印机输出图像,有关这方面的资料太少,现在我只能打印出文字,但是图像打印总是打出一些乱码,让我很苦恼,哪位做过这样的功能,能否指点一二?
目前我的代码如下:
/// <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的驱动,而且就算有驱动也不行,因为在打印机和计算机中间还有类似与“串易做图换机”的设备(转接盒),而这个盒子需要指令去切换各个端口,所以是行不通的。
--------------------编程问答-------------------- 感谢你的关注!
我已经把24位真彩位图(每个像素3个字节,代表R,G,B分量)转换成了色深为1位(全黑或者全白)的位图(8个像素一个字节)。
但是现在就是如何将位图的点阵数据发送给串口的问题(如何组织)。
--------------------编程问答-------------------- 问题还没有解决,我贴出代码,哪位帮忙看看错误在哪儿,谢谢了!
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#