一,我的打印方案
我是使用的PrintDocument 这个控件来打印的,粘贴一下我的代码
private void btn_raw_Click(object sender, EventArgs e) { PrintDocument printDoc = new PrintDocument(); //自定义纸张类型 printDoc.DefaultPageSettings.PaperSize = new PaperSize("Custum", 300, 480); printDoc.PrintPage += PrintDoc_PrintPage; //打印的时候不要跳出窗口 printDoc.PrintController = new StandardPrintController(); printDoc.DefaultPageSettings.Landscape = false; //false 表示纵向 //打印预览 PrintPreviewDialog ppd = new PrintPreviewDialog(); ppd.Document = printDoc; try {//显示打印预览窗口 ppd.WindowState = FormWindowState.Maximized; ppd.ShowDialog(); } catch (Exception excep) { //显示打印出错消息 MessageBox.Show(excep.Message, "打印出错", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
打印事件
private void PrintDoc_PrintPage(object sender, PrintPageEventArgs e) { //获取打印机的DPI int widthDPI = (int)e.Graphics.DpiX; int heightDPI = (int)e.Graphics.DpiY; // 1.设置条形码规格 EncodingOptions encodeOption = new EncodingOptions(); //这样是将百分之一英寸转换为像素 //例如200实际表示的是2英寸, 60表示的是0.6英寸 int bmpwidth = 200; int bmpheight = 60; //将上面的英寸转换为图片需要的像素. 比如DPI为600 ,那么一英寸就需要600个像素, //所以计算公式为(百分之一英寸/100)*DPI=实际像素 encodeOption.Height = bmpheight *heightDPI / 100; encodeOption.Width = bmpwidth *widthDPI / 100; // 2.生成条形码图片并保存 ZXing.BarcodeWriter wr = new BarcodeWriter(); wr.Options = encodeOption; wr.Format = BarcodeFormat.CODE_128; // 这里可以设定条码的标准 var img = wr.Write("abcdefghijklmn"); // 生成图片 //下面这三行是用于提升图片打印质量的,如果是在是理解不了单位的转换,可以直接使用这三行代码, //打印的效果也不差 //e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; //e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; //e.Graphics.PixelOffsetMode = PixelOffsetMode.Half; e.Graphics.DrawImage(img, new Rectangle(25, 25, bmpwidth, bmpheight), new Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel); //再打印一个二维码 //这里的尺寸单位是百分之一英寸 bmpwidth = 100; bmpheight = 100; //转换为实际需要的像素 encodeOption.Height = bmpheight * heightDPI / 100; encodeOption.Width = bmpwidth * widthDPI / 100; wr.Options = encodeOption; wr.Format = BarcodeFormat.DATA_MATRIX; Bitmap img2 = wr.Write("11111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222233333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333344444444444444444444444444444444444444444444444444444444444444444444444444444444444444555555555555555555555555555555555555555555555555555555555555555555"); e.Graphics.DrawImage(img2, new Rectangle(100, 150, bmpwidth, bmpheight), new Rectangle(0, 0, img2.Width, img2.Height), GraphicsUnit.Pixel); //SizeF size= e.Graphics.MeasureString("Ivan Test", new Font("黑体", 11)); //e.Graphics.DrawString("123 Test", new Font("黑体", 11), System.Drawing.Brushes.Black, 450, 300); }
二,打印图片为什么会模糊呢?
这是因为单位的错误导致的.
图片的宽度和高度实际的单位是像素, 但是打印时候的宽度和高度确实百分之一英寸为单位.
举个例子,一个图片是600px宽 600px 高, 有一台打印机的DPI 高和宽都是600 , 那么用DrawImage打印图片的时候, 就会把图片600像素的宽,理解为了600百分之一英寸(6英寸),数值没变,只是单位的理解不一样,
于是打印6英寸宽,需要跨度6*600DPI=3600像素, 但是图片本身只有600像素,于是就把图片的宽放大到3600像素,同理高也是这样,需要放大.
放大以后的位图就会出现锯齿,如果是一般的打印机还能打印出灰度, 图片还能看,模糊的不是很明显,如果是是标签打印机,只有黑色一种颜色, 那些灰度值就要丢弃,导致打印的标签非常模糊.
所以如果要打印6英寸的一条线,DPI为600的情况下, 需要准备6*600=3600像素的线条,然后告诉打印机 我要打印的宽度是600(百分之一英寸) , 打印图像的3600像素, 元素图像的单位是像素.
具体的语句就是
e.Graphics.DrawImage(img, new Rectangle(25, 25, bmpwidth, bmpheight), new Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel);
可以多看看这个方法的描述就懂了.
这个方法已经在zebra打印机上面测试过,效果非常好.
我上面的代码里面引用了一个创建条码的库, 大家可以使用Unget安装,就不会报错了.
Install-Package ZXing.Net -Version 0.16.6
可以下载我的测试程序
https://download.csdn.net/download/xiaoxiong3533521/20302893