EPSON熱敏打印機通過POSDLL調用POS_PReDownloadBmpToRAM、POS_S_PrintBmpInRAM函數實現電影票等單色位圖的二維碼打印,而在轉換單色位圖后,需將圖像信息頭中的位圖點陣圖使用的調色板顏色數(10)及指定重要的顏色數(11)設置為0;同時,點陣圖資料大小為(7)為(2)。
圖片引用自《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;
}
新聞熱點
疑難解答