热敏打印单色位图

EPSON热敏打印机通过POSDLL调用POS_PreDownloadBmpToRAM、POS_S_PrintBmpInRAM函数实现电影票等单色位图的二维码打印,而在转换单色位图后,需将图像信息头中的位图点阵图使用的调色板颜色数(10)及指定重要的颜色数(11)设置为0;同时,点阵图资料大小为(7)为(2)。

  1. size:4 bytes,0x28 = 40 bytes,表示Info Header的大长度总共 40 bytes
  2. width:4 bytes,0x10 = 16,图像宽度为16 pixel
  3. height:4 bytes,0x10 = 16,图像高度为16 pixel
  4. planes:2 bytes,0x01 = 1,位元面数为1
  5. bits:2 bytes,0x20 = 32,每個pixel需要32bits
  6. compression:4 bytes,0代表不压缩
  7. imagesize:4 bytes,0x400 = 1024 bytes,点阵图资料大小为1024 bytes
  8. xresolution:4 bytes,水平解析度
  9. yresolution:4 bytes,垂直解析度
  10. ncolours:4 bytes,点阵图使用的调色板颜色数
  11. importantcolours:4 bytes,重要的颜色数

图片引用自《http://blog.csdn.net/o_sun_o/article/details/8351037》。

具体操作方法为:

/// <summary>
/// 生成二维码代码
/// </summary>
/// <param name="txt_qr">需要生成二维码的信息</param>
/// <param name="txt_size">值越大生成的二维码图片像素越高</param>
/// <returns>二维码图片的信息</returns>
private static string generateQRCode(string txt_qr, string txt_size)
{
//生成二维码
string filepath = string.Empty;
string qrEncoding = "Byte";
string Level = "M";
string txt_ver = "0";

QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
String encoding = qrEncoding;
if (encoding == "Byte")
{
qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
}
else if (encoding == "AlphaNumeric")
{
qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.ALPHA_NUMERIC;
}
else if (encoding == "Numeric")
{
qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.NUMERIC;
}

string errorCorrect = Level;
if (errorCorrect == "L")
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.L;
else if (errorCorrect == "M")
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
else if (errorCorrect == "Q")
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.Q;
else if (errorCorrect == "H")
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H;

try
{
int scale = Convert.ToInt16(txt_size);
qrCodeEncoder.QRCodeScale = scale;///大小(值越大生成的二维码图片像素越高)
int version = Convert.ToInt16(txt_ver);
qrCodeEncoder.QRCodeVersion = version;

String data = txt_qr;
Bitmap image = qrCodeEncoder.Encode(data);
int image_Width = image.Width;
int image_Height = image.Height;
Bitmap resizedBmp = new Bitmap(image_Width + 4, image_Height + 4);
Graphics g = Graphics.FromImage(resizedBmp);
g.Clear(Color.White);//用背景色刷新
// Create rectangle for displaying image.
Rectangle destRect = new Rectangle(2, 2, image_Width, image_Height);
// Create rectangle for source image.
Rectangle srcRect = new Rectangle(0, 0, image_Width, image_Height);
// Draw image to screen.
g.DrawImage((Image)image, destRect, srcRect, GraphicsUnit.Pixel); g.Dispose();
filepath = ConvertToBpp(resizedBmp);

resizedBmp.Dispose();
image.Dispose();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "信息提示");
}
return filepath;
}

/// <summary>
/// 转换单色位图的方法
/// </summary>
/// <param name="img"></param>
private static Bitmap xxx(Bitmap img)
{
int w = img.Width;
int h = img.Height;
Bitmap bmp = new Bitmap(w, h, PixelFormat.Format1bppIndexed);

BitmapData data = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);
for (int y = 0; y < h; y++)
{
byte[] scan = new byte[(w + 7) / 8];
for (int x = 0; x < w; x++)
{
Color c = img.GetPixel(x, y);
if (c.GetBrightness() >= 0.5) scan[x / 8] |= (byte)(0x80 >> (x % 8));
}
Marshal.Copy(scan, 0, (IntPtr)((int)data.Scan0 + data.Stride * y), scan.Length);
}
bmp.Palette = CreateGrayscalePalette();
return bmp;
}

/// 创建图像格式对应的调色板
/// </summary>
/// <param name="pixelFormat">图像格式,只能是Format1bppIndexed,Format1bppIndexed,Format1bppIndexed</param>
/// <returns>返回调色板;如果创建失败或者图像格式不支持,返回null。</returns>
private static ColorPalette CreateColorPalette(PixelFormat pixelFormat)
{
ColorPalette palette = null;
if (pixelFormat == PixelFormat.Format1bppIndexed || pixelFormat == PixelFormat.Format4bppIndexed || pixelFormat == PixelFormat.Format8bppIndexed)
{
//因为ColorPalette类没有构造函数,所以这里创建一个1x1的位图,然后抓取该位图的调色板
Bitmap temp = new Bitmap(1, 1, pixelFormat);
palette = temp.Palette;
temp.Dispose();
}
return palette;
}

/// <summary>
/// 根据颜色深度,创建对应的调色板
/// </summary>
/// <param name="depth">颜色深度,即表示颜色所用的位数</param>
/// <returns>返回调色板</returns>
private static ColorPalette CreateColorPalette(int depth)
{
//根据颜色数,决定使用什么样的调色板
PixelFormat pixelFormat = PixelFormat.Format1bppIndexed;
if (depth > 2)
pixelFormat = PixelFormat.Format4bppIndexed;
if (depth > 16)
pixelFormat = PixelFormat.Format8bppIndexed;
return CreateColorPalette(pixelFormat);
}

/// <summary>
/// 创建单色灰度调色板
/// </summary>
/// <returns>返回调色板</returns>
private static ColorPalette CreateGrayscalePalette()
{
ColorPalette palette = CreateColorPalette(PixelFormat.Format1bppIndexed);
palette.Entries[0] = Color.FromArgb(0, 0, 0, 0);
palette.Entries[1] = Color.FromArgb(0, 255, 255, 255);
return palette;
}

/**
* byte数组中取int数值,本方法适用于(低位在前,高位在后)的顺序。
*
* @param ary
* byte数组
* @param offset
* 从数组的第offset位开始
* @return int数值
*/
private static int bytesToInt(byte[] ary, int offset)
{
int value;
value = (int)((ary[offset] & 0xFF)
| ((ary[offset + 1] << 8) & 0xFF00)
| ((ary[offset + 2] << 16) & 0xFF0000)
| ((ary[offset + 3] << 24) & 0xFF000000));
return value;
}

/// <summary>
/// 转换为单色位图后,图像信息头中的位图使用的颜色数及指定重要的颜色数设置为0
/// </summary>
/// <param name="img"></param>
/// <returns></returns>
private static string ConvertToBpp(Bitmap bitMap)
{
//打开任一索引色的或者非索引色的图像
Bitmap bm = xxx(bitMap);
MemoryStream ms = new MemoryStream();
bm.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] buffer = new byte[ms.Length];
//Image.Save()会改变MemoryStream的Position,需要重新Seek到Begin
ms.Seek(0, SeekOrigin.Begin);
ms.Read(buffer, 0, buffer.Length);

byte[] bitLenght = new byte[4];
Array.Copy(buffer, 2, bitLenght, 0, 4);
int ibitlen = bytesToInt(bitLenght, 0);

//byte[] bitBuffer = new byte[2];
//bitBuffer[0] = 0x2C;
//bitBuffer[1] = 0x04;
//Array.Copy(bitBuffer, 0, buffer, 34, 2);
Array.Copy(bitLenght, 0, buffer, 34, 4);

byte[] bitmapBuffer = new byte[1];
bitmapBuffer[0] = 0;
Array.Copy(bitmapBuffer, 0, buffer, 46, 1);
Array.Copy(bitmapBuffer, 0, buffer, 50, 1);

FileStream fs = null;
string file = Guid.NewGuid().ToString().Replace("-","").ToString() + ".bmp";
//将待写的入数据从字符串转换为字节数组
fs = File.OpenWrite(file);
//设定书写的开始位置为文件的末尾
fs.Position = 0;//fs.Length
//将待写入内容追加到文件末尾
fs.Write(buffer, 0, ibitlen);
fs.Close();
bm.Dispose();
return file;
}

时间: 2024-08-30 00:58:42

热敏打印单色位图的相关文章

Android TSC热敏标签打印机打印

不知道大家有没有遇到这种情况,有些东西想整理但却不知道怎么去整理.在做之前一头雾水,百度上也找不到答案,然后搞出来又发现没什么内容,所以好像也没什么可整理. 但是更多,我想说的是,我们还是要学会去总结,为什么我花了那么长时间,以及下次遇到这种情况,我如何下手?也希望对和我这样的菜菜有点帮助. 需求 Android蓝牙连接TSC标签打印机打印.(热敏打印机要用热敏纸) 说明 有关打印机,一般都会提供 有关开发的 SDK ,开发文档.Android可以参考,其实这可能对很多人来说都是很简单的一件事,

关于单色位图生成点阵数组

要把单色位图做成点阵数组,数组中0xff代表白点,0x00代表黑点,没有找到直接可以转成这种格式的工具,所以自己了解了一下: 在这里需要注意一下单色位图的特点:每一扫描行的字节数必需是4的整倍数,当不够4的整数倍时,需要加0补齐.例如:你使用的图片是40x60的,点阵的大小不是40x60而是64*60(40/8=5,不是4的整数倍,需要补3个字节的0). 头数据: 42 4D    3E 04 00 00    00 00 00 00   3E 00 00 00  .... 这是一个单色位图的头

转:C#并口热敏小票打印机打印位图

最近一直在研究并口小票打印机打印图片问题,这也是第一次和硬件打交道,不过还好,最终成功了. 这是DEMO的窗体: 下面是打印所需要调用的代码: [html] view plaincopy class LptControl { private string LptStr = "lpt1"; public LptControl(string l_LPT_Str) { LptStr = l_LPT_Str; } [StructLayout(LayoutKind.Sequential)] pr

C#并口热敏小票打印机打印位图包括芯片的写入

下面是打印所需要调用的代码: class LptControl { private string LptStr = "lpt1"; public LptControl(string l_LPT_Str) { LptStr = l_LPT_Str; } [StructLayout(LayoutKind.Sequential)] private struct OVERLAPPED { int Internal; int InternalHigh; int Offset; int OffSe

【Arduino】66种传感器系列实验(5)---热敏温度传感器模块

37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器模块,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里准备逐一做做实验,不管能否成功,都会记录下来---小小的进步或是搞不掂的问题,希望能够抛砖引玉. 实验五:热敏电阻温度传感器模块 手头这模块的实物照片 热敏电阻器是敏感元件的一类,按照温度系数不同分为正温度系数热敏电阻器(PTC)和负温度系数热敏电阻器(NTC).热敏电阻器的典型特点是对温度敏感,不同的温

NF5501扫描与打印二次开发记要

2020-02-03 关键字:热敏打印设备二次开发 NF5501 是一款便携式的打印扫描一体式设备. 这篇博文记录一下笔者针对这款设备的条码扫描与热敏打印功能的二次开发. 首先这款设备官方是有给出扫码与热敏打印的示例程序及源码的,它的下载地址为: http://www.nanfang001.com/Support/473918/ 不过官方提供的示例源码稍稍有些零乱,需要花点时间才能明白控制扫描与打印的流程.笔者这边已经大致梳理过一次了,将关键步骤在此记录下来,以期能帮助到有需要的同学. NF55

手持PDA智能条码扫描RFID打印POS机

手持PDA智能条码扫描RFID打印POS机   一.系统稳定性: 1.硬件稳定性: 采用了华为海思(国内唯一可以媲美全球顶级的CPU+射频方案厂商,可以和英伟达等一决高下)手机方案,CPU+射频浑然一体,经过数千万手机出货验证,性能稳定可靠.常规的WINCE+GSM模组组装出来的产品,不能拨打电话,仅能传输数据,而且稳定性很差. 2.系统稳定 Mobile6.5操作系统是wince系统的完美.最终升级版.注重人性化和交互界面(类似于win98和Win XP的区别).再次基础上面有经过华为数百人团

C# winform打印总结 z

http://blog.csdn.net/jing_xin/article/details/41444063 针对BEIYANG收据打印机 BTP-R580测试通过. 操作说明:http://www.docin.com/p-395110672.html 1.一般的打印 static Font printFont; //打印使用的字体         public static void PrintEventPage(object sender, PrintPageEventArgs e)    

PDA打印扫描出入库开单系统介绍

款功能强大的热敏打印终端,填补了手持打印的市场空白,采用支持联通/移动GPRS,采用4.5英寸高清液晶屏,android系统,标配2英寸热敏打印机芯,一维激光扫描模组.wifi.蓝牙.GPS等常见功能.强悍之处在于可以同时搭载一维扫描.热敏打印.HF等功能,真正实现了一机多用,真正的做到了行业首创. android打印终端.出色的性能能有效保证工作流程的快捷以及稳定.4.5英寸高清液晶屏,保证作业信息在多种复杂情况下的准确获取.采用android系统,标配2英寸热敏打印机芯,一维条码扫描模组.w