C#实现无物理边距 可打印区域的绘图打印 z

经常在开发实际的应用程序中,需要用到图形绘制和打印程序。如何实现完整的精确打印和绘图是需要注意许多细节地方的。最近在遇到打印问题的时候,仔细研究一阵,总结这篇博文,写得有点杂乱,看文要还请费点神。

基本功能:窗体绘图与鼠标交互

打印预览与打印输出

开发平台:VisualStudio 2010 (C#)

1 绘图坐标系统

1.1 绘图系统坐标转换(屏幕窗口/打印机)

绘图程序涉及到多种坐标系统,总体上可分为三个坐标系:世界坐标系、页面坐标系以及设备坐标系。想要将图形图像会知道最终的设备上,中间需要做各种坐标转换,下面将详细介绍绘图系统中的坐标转换关系

1 、世界坐标

实际的绘图区域,如港口码头的2000 米长度的范围、测井3000 米的测量深度等。通常的实际应用中如果用到有打印这样的精确绘制功能,则还需要注意由世界坐标映射到逻辑坐标的比例,有两种方式:

(1 )根据绘图窗口大小动态的计算映射比例,一般绘图都是这样,这种方式可以让用户更加方便的阅览全局绘图;

(2 )设定映射比例为一个定值,计算出相应的转换坐标,如测井中绘图的MD 1:200 这样的参数,这样绘图区域大小是不变的,超出窗口位置要设定滚动条拖动显示。

通常还需要根据需要,把以上两种方式都实现出来,供选择使用,如Adobe PDF 浏览器既具有整页缩放功能,也有按比例缩放这样的功能。

2 、页面坐标

绘图页面总体设计大小,如默认选择A4 的纸张(210mm * 297mm ),此时系统建立基于所选纸张大小区域作为逻辑坐标范围。

3 、设备坐标

(1 )屏幕窗口:根据具体绘图区域获取,如屏幕窗口绘图的客户区ClientRectangle 等,单位是pixel 。

(2 )打印机:绘图区域也可以是打印机的实际绘制区域,但此时要注意单位,VS.NET 默认的是单位1/100 inch ,即VC++编程用到映射模式中的的MM_LOENGLISH 映射方式,逻辑单位为0.01 inch (如下表中颜色标识项所示)。

Windows 定义了的8 种映射方式

注:MM_TWIPS 经常在打印机上,单位是1/20 磅(1 磅=1/72 英寸)。

三个坐标系转换关系如下图所示:

由于打印机的分辨率参数经常是600Dpi 或者更高的1200Dpi 等数值,远比屏幕的96Dpi 或者120Dpi 数值大得多,为了保证能有效的实现所见即所得效果,即屏幕窗口绘图跟实际打印结果一致,需要处理不同分辨率问题。此处有两种解决方案:一种是计算打印机和屏幕的分辨率比例,然后屏幕绘图的结果,在向打印机上绘图时候进行比例缩放计算,这种方法是又世界坐标直接映射到像素在做计算;另一种则是基于页面坐标绘图,所有绘图坐标单位设置映射到页面坐标(mm 单位),随后进行的绘图就直接计算LPtoDP 转换即可。两种方法都是主动计算转换的像素,也可换成简便的开发平台自带的绘图系统,即设置Graphics 的PageUnit 属性为毫米即可。

设置Graphics.PageUnit 为默认的Pixel 单位,此后所有绘图单位都是基于像素单位,此处设备坐标大小,即多少像素是程序计算。为了方便计算页面坐标同设备坐标之间的转换,可以建立函数处理,类似MFC 中的逻辑坐标与设备坐标之间的转换函数LPtoDP ,如上图所示的②坐标转换过程。

设定窗口到视口的绘图单位为像素单位,两种坐标系设定如下:

(1 )屏幕绘图:

Graphics g = panel1.CreateGraphics();

g.PageUnit= GraphicsUnit.Pixel;

(2 )打印机绘图:

PrintPageEventArgse

Graphics g = e.Graphics;

g.PageUnit= GraphicsUnit.Pixel;

4 、坐标转换差异测试2013/11/17

坐标轴绘图测试代码(注:边框线是用m_WPtoDP_X 绘制的,而坐标轴是用两种方法进行绘制,由此看出两种绘图方式存在的差异)

for (float fX = 0; fX

(1 )测试由世界坐标到页面坐标转换,再由页面坐标到设备坐标转换,并加上缩放系数最后得到窗口范围内的坐标值绘图如下所示。

v_f_TempX = m_WPtoLP_X(fX);

v_f_TempX = m_LPtoDP_X(v_f_TempX);

v_f_TempX *= v_f_ScaleZoomX;

左边为小窗体时的首尾绘图,存在明显误差;右边为窗体放大后的首尾绘图,误差明显减小,但仍然存在一定误差。

2 )测试直接由世界坐标转换到设备坐标窗口绘图,结果如下:

v_f_TempX = m_WPtoDP_X(fX);

实际效果证明窗体缩放对误差大小基本没有影响,基本没有误差。

结论:直接由世界坐标到设备坐标映射减少了坐标转换的计算次数,有效避免了转换将计算过程中的误差累积,效果较好。其余的坐标转换则可以在需要的时候,直接使用,避免多次叠加使用。但是在实际使用过程中,还是使用了第一种方法(所有绘图都用相同方法,保证了绘图的一致性,不存在差异),这样避免了总是设定设备坐标(DP )的区域参数,在窗体缩放大小等变化的时候,减少计算量。

5 、绘图显示缩放问题

进一步采用(1 )的绘制方法注意的问题,即采用页面坐标到设备坐标映射比例绘图,此时基于页面坐标的区域进行绘图,会造成与设备坐标之间的绘图区域部匹配问题,例如A3 纸张大小的区间需要的设备区域是20003000, 而实际的绘图窗口大小事800600 ,因此会出现绘图显示不完全的情况,所以再次引进缩放系数v_f_ScaleZoomX 和v_f_ScaleZoomY 。此时存在四种屏幕显示方式,如下表所示。

1.2 屏幕坐标系

在屏幕窗体上绘图的坐标系原点在左上角位置:

Origin = ( 0, 0)(Pixel)

逻辑坐标和设别坐标都基于该Origin 点进行计算,具体的绘制转换计算关系如下图所示:

其中需要注意设置的是逻辑坐标,根据打印机选择的纸张,设定页面坐标系,同时考虑了打印机物理边距和打印纸页面边距,真正用于坐标转换的,只有PlotArea 区域的尺寸大小。

1.3 打印坐标系

在实际的物理打印中,经常出现以前问题:

Problem :由于实际的物理打印机可能存在物理边距问题,使得实际的物理打印坐标存在偏移(PrintOffset),因此在获取页面边距后,需要进一步考虑物理边距,才能更好的计算实际的打印区域。

Analysis :分析打印系统的坐标系统成为必要,上述问题中明显出现的坐标平移情况,同时导致右边和下边出现了打印不完全的情况。最后得出C#的提供的平台中,打印的坐标原点是需要设定的,由于存在打印机的物理边距问题,实际物理打印坐标原点分两种情况:

(1 )原点在物理边距线上,Origin = (HardMaeginX, HardMarginY )(1/100inch)

(2 )原点在页面边距线上,Origin = (MaeginLeft, MarginTop )(1/100inch)

打印文档类关于打印坐标原点位置属性的MSDN 解释:

public bool OriginAtMargins { get; set; }

具体坐标如下图所示:打印纸的总体尺寸为黑色坐标系(827*1169 )0.01 inch ,而真正可打印的区域为v_PrintDocument.DefaultPageSettings.PrintableArea 提供的绿色坐标系区域,此时应该把PrintableArea 作为真正的打印计算坐标系。

Solution :知道物理边距影响因素后,打印问题的处理通常有两种方案:

方案一:普遍采用的讲绘图内容进行位移

通常的做法是将可打印区域进行Offset 平移,平移量为打印机物理边距(HardMarginX / HardMarginY ),这样结合默认的打印纸张的页面边距(MarginLeft /MarginRight / MarginTop / MarginBottom)也能按照预览时的绘图一模一样的打印出来。

这种做法比较简单,只需要进行位移一下Graphics 即可。但是注意,此时的页面边距不能为0 ,否则任然会出现打印绘图缺失现象,物理边距是不可避免的。要避免这种情况就需要判断页面边距的值,不能小于物理边距的值才行。

方案二:可以重新定义页面坐标,对页面尺寸进行裁剪

方案一在计算了左边和上边的不可打印区域,但是没有计算右边和下边的不可打印区域。这样位移和绘图的时候,就需要考虑是否打印出来的图正好在正中等问题。要精确控制就是将可打印区域裁剪到实际物理可打印的区域,如上图所示的绿色区域。

设定OriginAtMargins = false 使得打印机的绘图Graphics 的坐标原点在有效打印区域的边界上,即坐标原点为物理边距上,而不是在页面边距上。于是,我们绘制的时候,X 坐标0 到100 ,实际上是从HardMarginX+0 到HardMarginX+100 ,在计算页面坐标的时候,考虑物理边距进行排除后,就能实现在可打印区域内(排除了物理不可打印区域)进行精确的绘图。

但是也要注意,在屏幕绘图和打印预览的时候,需要将坐标进行向下向右平移物理尺寸,使得绘图效果与打印效果一致。同时,针对不同的Dpi 造成的误差,避免的办法是定义单位是mm ,然后采用LPtoDP 进行转换,在转换的过程中,会用到Graphics 的Dpi 属性进行计算,屏幕Dpi 和打印机Dpi 不同,但是得到最后的绘图效果将会统一,实现所见所得。

物理边距的误差

至于物理边距问题,有可能打印出来的实际纸张上的物理边距跟程序获取的边距有误差,原因可能是打印机自身有关,也可能跟纸张在纸盒中放置有偏移有关。但这都算是不可避免的误差了,也不知道如何校正,我们只需要实现实际绘图内容打印完整,且绘制内容的精确定位绘制即可!

其他关于物理边距讨论的一部分链接

(1) How to Find the ActualPrintable area

(2) I am Loss in Printing Margins

(3)How to print in full page withoutmargins

(4)使用.Net 下的打印控件进行预览和打印时的模型初探

1.4 绘图操作流程

绘图工作开始后,需要进行一系列的绘图参数设定,其中绘图坐标系的设定最为重要。大概可分为以下几个步骤:

Step 1 :设定世界坐标系。给定需要绘制的世界坐标区域大小,相当于绘图的视野范围;

Step 2 :设定页面坐标系。即纸张大小,相当于逻辑坐标系。这点在打印机的绘制程序中尤为重要,同时为了实现所见即所得的绘图思路,此处的窗体绘图跟打印绘图应该有良好的对应关系,所以设定的纸张应该一致。

Step 3 :设定绘图对象Graphics ,可以是打印机绘图,也可以是屏幕窗口绘图。

Step 4 :设定设备坐标系。给定绘图设备的实际区域,如屏幕窗口大小、打印机的实际可打印区域等。

Step 5 :输入绘图数据。

Step 6 :绘图输出

简单的绘制流程图如下:

1.5 交互操作中屏幕坐标系与打印坐标系的转换

(1 )鼠标屏幕拾取转换,讲鼠标坐标值(Pixel )转换为页面坐标值(mm ),需要考虑滚动条位置、物理边距和屏幕显示缩放系数等,页面坐标(mm )转换为世界坐标(M )直接调用函数即可。伪代码如下:

// 需要考虑滚动条位置

Graphics g = panel1.CreateGraphics();

int i_PosHor = panel1.HorizontalScroll.Value;

int i_PosVer =panel1.VerticalScroll.Value;

int i_OffsetX = (int)(m_LPtoDP_X(v_f_LogicHardMarginX, g) /v_f_ScaleZoomX) – i_PosHor;

int i_OffsetY = (int)(m_LPtoDP_Y(v_f_LogicHardMarginY, g) /v_f_ScaleZoomY) – i_PosVer;

float v_f_LogicMousePosDownX =m_DPtoLP_X(e.X + i_PosHor, g) * v_f_ScaleZoomX – v_f_LogicHardMarginX;

float v_f_LogicMousePosDownY =m_DPtoLP_Y(e.Y + i_PosVer, g) * v_f_ScaleZoomY – v_f_LogicHardMarginY;

转换为世界坐标:

float v_f_WorldMousePosDownX= m_LPtoWP_X(v_f_LogicMousePosDownX);

(2 )世界坐标转换为页面坐标和设备坐标伪代码:

Graphics g = panel1.CreateGraphics();

float v_f_WorldX = 2000;

float v_f_LogicTempX = m_WPtoLP_X(fX);

float v_f_DeviceTempX =m_LPtoDP_X(v_f_TempX, g) / v_f_ScaleZoomX;

1.6 提高绘图效率

现在一般的GDI 和GDI+绘图都没有问题,关键是提高绘图的效率,防止绘图刷新时的闪烁问题,在此参考了两篇高质量的网文如下:

(1 )使用bitblt 提高GDI+绘图的效率(转)

引用(略)

(2 )绘图效率完整解决方案——三种手段提高GDI/GDI+绘图效率

1.7 异或作图法响应鼠标实时绘制

异或作图法不同于普通的绘图方法中的刷新需要按照Invalidate 的区域全部重新绘制,它只是采用覆盖绘制的方式,实现了擦除原有轨迹来达到刷新绘制,这样就极大的提高了绘图效率,避免不必要的区域性重绘耗费资源成本,也能十分有效的避免因为小区域或线型实时绘制等任务造成的整个绘图窗体闪烁问题。需要注意的是,异或作图法跟普通的画法感觉最大的别扭就是需要”连续”的两次绘图,然后这两次绘图结果根据用户设定的异或方式,进行异或计算,得出擦除、反色或覆盖等结果。

其实现方式很简单,直接调用GDI 的相关函数进行设定即可,下图为已实现异或填充绘图。

文章已经很长了,不想一一列举,以下是一些有用的参考链接:

(1)<基础的异或作图方法>VC橡皮筋绘图技术的实现(异或模式绘图)

(2)

(3 )

校正:这篇文章中公布了一个异或法绘制直线的方法,但是其中关于MoveToEx的GDI库调用函数存在问题,需要增加ref关键字引用,

[DllImport(“gdi32.dll”)]
private static extern bool MoveToEx(IntPtr hDC, int x, int y, ref POINTAPI lpPoint);

调用函数:MoveToEx(hDC, 10, 10, ref ptsOld);

具体参考地址:

GDI32.DLL API 函数MoveToEx 在C#2.0 中的调用问题

(4 )

(5 )C#Color 和 VC++COLORREF 转化

如果使用MFC 与.NET 混合编程,就会遇到这个问题,通过MFC 编写的控件,由.NET 调用,则控件中背景色的设置,需要颜色的转换。

COLORREF 类型颜色的值COLORREFcr=RGB(123,200,12);

其中的R 、G 、B 三个分量的排列顺序是BGR 。

.NET 中通过数据类型Color 表示颜色,该类有一个函数FromArgb(int,int,int),可以通过输入RGB 三个值得到一个Color 类型的颜色。同时也有一个ToArgb()函数,得到一个32 位的整数值,

32 位ARGB 值的字节顺序为AARRGGBB 。由AA 表示的最高有效字节(MSB)是alpha 分量值。分别由RR 、GG 和BB 表示的第二、第三和第四个字节分别为红色、绿色和蓝色颜色分量

(6 )异或绘图模式设置的Index 值

绘图模式(drawing mode)指前景色的混合方式,它决定新画图的笔和刷的颜色(pbCol)如何与原有图的颜色(scCol)相结合而得到结果像素色(pixel)。

可使用CDC 类的成员函数SetROP2 (ROP = Raster OPeration 光栅操作)来设置绘图模式:

其中,R2_COPYPEN (覆盖)为缺省绘图模式,R2_XORPEN (异或)较常用。

CDC::SetROP2

int SetROP2(int nDrawMode);

返回值:绘图模式的前一次取值。可以取联机文档”Windows SDK “中提供的任意值。

参数:nDrawMode 指定新的绘制模式,可以为下列值之一:

说明:
设置绘图模式。绘图模式指出笔与被填充对象的颜色是怎样同显示表面的颜色组合的。绘图模式只用于光栅设备,不用于矢量设备。绘图模式是双重的光栅操作代码,代表了两个变量所有可能的布尔组合,分别使用AND 、OR 、XOR (异或)和NOT 运算符。

(7 )字符串绘制,能否异或?(答曰:不能)

字符串输出绘制不能采用异或的方式进行擦除更新,那么需要实时的动态位置显示信息的时候如何解决?目前看到三种方案:

方案一:利用局部更新文字形成的位图方法(参考CSDN 论坛,忘了地址)

方案二:利用文字的点阵图输出

方案三:直接用Label 控件显示信息,让Label 跟随鼠标移动显示文字内容

直接修改Label 控件的Left 和Top 属性,更新其Text 属性内容,然后改变控件位置,实现实时显示。默认情况下,控件不支持透明背景色。在属性框里设置background 属性为transparent 。同时修改Visible 属性进行显示和隐藏。

2 数据管理

绘图内容数据管理按照数据库方式的拓扑结构进行管理,而单个对象则采用面向对象方式进行存储和管理操作。

3 窗体绘图显示设计

工具栏主要操作项:

4 绘图打印

4.1 公制与英制单位的换算问题

利用PageSetupDialog 对话框设置纸张的类型、页边距等信息后,再次进入页面设置的对话框,发现里面的页边距全部改变了,再进入又改变了,这是为什么呢?

其实原因很简单,单位的不同造成了这个现象。我们可以再看看上图中”页边距”一项明确的注明了单位采用的是”毫米”,说明在页面设置对话框中使用的是公制长度计量单位,而在.net 中采用的是英制的计量单位。英制中长度的基本计量单位是英寸,公制中长度的基本计量单位是厘米,打印时默认的长度单位为1/100 英寸。因此假设我们在页面设置对话框中设置上部边距为10mm (如下左图),但.net 把它转换成了英制单位,数值是1/2.54 * 100=39 个1/100 英寸,(1 英寸约等于2.54 厘米,1 厘米=10 毫米)所以,这时上部页边距的数值变成了39 ,当你再次打开页面设置对话框时,系统将认为上部页边距是39 个1/100 厘米,也就是3.9 毫米(如下右图),按下”确定”按钮后,.net 将再次对页边距进行转换,这时上部边距就约为15 个1/100 英寸,这样结果当然与我们设置的相差甚远。

知道了原因,解决问题就很好办了。其实微软也考虑到了这个问题,提供了一个用于单位转换的类PrinterUnitConvert ,如下所示:

If(System.Globalization.RegionInfo.CurrentRegion.IsMetric) Then

‘如果使用的是公制单位

‘将英制单位的数据转换成公制单位的数据

psd.PageSettings.Margins= PrinterUnitConvert.Convert (psd.PageSettings.Margins, PrinterUnit.Display,PrinterUnit.TenthsOfAMillimeter)

EndIf

pap.DefaultPageSettings= psd.PageSettings

Margins 属性中保存的页面的上(Top )、下(Bottom)、左(Left)、右(Right)的页边距数值,利用PrinterUnitConvert 的Convert 方法都可以转换,在上例中,PrinterUnit.Display 是指1/100 英寸的单位,PrinterUnit.TenthsOfAMillimeter 是指1/100 毫米的单位,这样就可以将英制单位转换为公制单位。

当然我们也可以自己编写代码进行转换,但请注意,转换时英制的单位是1/100 英寸,转换后要以毫米为单位。

注意:转换时只须对纸张的页边距进行转换,纸张本身的宽度和高度在你选择一种纸张类型的时候,它已经自动帮你转换成英制单位了,千万不要画蛇添足。以上我们介绍了如何利用PageSetupDialog 对话框设置页面、公制与英制单位的换算,已经为打印程序的编写建立了一个良好的基础。接下来,我们就来介绍如何实现具体的特殊打印功能。

.NET 的升级版本也可以一句话就解决问题:

// 打印页面设置

public PageSetupDialogv_PrintPageSetDlg = new PageSetupDialog();

// 英制单位转换为公制单位

v_PrintPageSetDlg.EnableMetric = true;

结果如下:

但是注意:此时显示的25.4mm ,实际上获取Margins 属性的时候,仍然是100 个1/100 英寸,因此存在0.254 的系数关系。

4.2 绘图单位转换问题

这里需要统一打印时的度量单位,打印文档的DefaultPageSettings 中的参数都是以1/100 英寸为单位,而窗口界面绘图中的尺寸获取(width 和Height )是以像素为单位,而中文操作系统中以毫米为单位(如打印设置页面),在打印时如何统一单位是必须要进行的。

而程序设定的坐标转换是基于世界坐标(单位:m )、逻辑坐标(单位:mm )以及设备坐标(单位:pixel ),因此需要将C#提供的英制单位1/100 英寸转换为mm ,然后最终转换为像素绘图坐标。

// mm 转Pixel

public float m_LPtoDP_X(floatv_f_Logicmm_X)

floatd_X = (float)((v_f_Logicmm_X / 25.4) *v_Graphic.DpiX);

returnd_X;

NOTE :在绘图时基于像素的时候,Graphics 的绘图单位也必须要设定为Pixel ,尤其是打印机事件参数的e.Graphics 。

e.Graphics.PageUnit = GraphicsUnit.Pixel;

获取打印机相关信息后,将1/100 英寸转换为像素:

float f_DeviceMargin_Left =m_LPtoDP_X(v_PrintDocument.DefaultPageSettings.Margins.Left * 0.254f);

float f_DeviceMargin_Top =m_LPtoDP_Y(v_PrintDocument.DefaultPageSettings.Margins.Top *0.254f);

4.3 关于物理页边距

相同的打印绘图内容,如果是PDF 虚拟打印机,则是严格的根据页面边距打印出来;而物理打印机出现偏差。如前面所阐述的打印坐标系原点,如果设定为true,怎会出现以下问题:

// 打印文档

public PrintDocument v_PrintDocument = new PrintDocument();

// 边距

v_PrintDocument.OriginAtMargins = true;

利用Adobe PDF 虚拟打印机打印出来的PDF 文档,然后在PDF 文档中打印出来的页边距是准确的,标准的默认25.4mm 页面边距,如下图所示:

若选择实际的物理打印机,此时的打印机存在物理边距,错误打印结果如下:

考虑到物理边距以后,打印事件参数(PrintPageEventArgs e )的绘图区域e.MarginBounds 需要进行向左和向上的偏移处理。

NOTE :打印机绘图用MarginBounds ,而不是直接用PaperSize ,那样计算起来很麻烦

class PrinterBounds

[DllImport(“gdi32.dll”)]

private static extern Int32 GetDeviceCaps(IntPtrhdc, Int32 capindex);

private const intPHYSICALOFFSETX = 112;

private const intPHYSICALOFFSETY = 113;

public readonly RectangleBounds;

public readonly intHardMarginLeft;

public readonly intHardMarginTop;

publicPrinterBounds(PrintPageEventArgs e)

IntPtrhDC = e.Graphics.GetHdc();

HardMarginLeft =GetDeviceCaps(hDC, PHYSICALOFFSETX);

HardMarginTop = GetDeviceCaps(hDC,PHYSICALOFFSETY);

e.Graphics.ReleaseHdc(hDC);

HardMarginLeft = (int)(HardMarginLeft * 100.0 / e.Graphics.DpiX);

HardMarginTop = (int)(HardMarginTop * 100.0 / e.Graphics.DpiY);

Bounds = e.MarginBounds;

Bounds.Offset(-HardMarginLeft, -HardMarginTop);

在.NET 以后的版本中,也可以直接用打印文档类的获取物理边界属性

DefaultPageSettings.HardMarginX, DefaultPageSettings.HardMarginY

然后进行打印的时候,就基本不会存在边距相差太大的情况,不过还是存在1 点几个毫米的误差。

(1 )页面边距25.4mm 时预览结果:

打印结果:左图为打印图纸左侧,右图为打印图纸右侧。

(2 )边距为0mm 时预览,由于计算绘图区域的时候,有物理边界存在,导致得到的绘图区域是经过了Offset 向左向上平移的,所以有空白的地方出现在预览图像的右边和下边。

打印的时候出现物理边界的影响,导致绘图能完整打印出来,如下图所示:

4.4 误差?绘制问题

// 绘制0 边距位置

Graphics.DrawLine(Pens.Red, 0, 0, m_LPtoDP_X(v_PrintDocument.DefaultPageSettings.PaperSize.Width* 0.254f), 0);

Graphics.DrawLine(Pens.Blue, 0, 0, 0,m_LPtoDP_Y(v_PrintDocument.DefaultPageSettings.PaperSize.Height * 0.254f));

用Adobe PDF 虚拟打印结果如下:在设置页边距为0 的时候,可以准确的打印到0 位置(如左边距),但是如果存在页边距的情况,打印0 位置会出现偏差(如上边距),不知道为什么?

Solve :不是误差,而是打印机绘图原点坐标问题2013/11/24 ,已解决

4.5 打印结果

4.5.1 页面设置

测试采用普通的A4 纸张,并设置为横向,如下图所示:

4.5.2 打印预览

查看打印阅览,跟绘图内容是否相同,测试结果一致。

4.5.3 打印成果图

选用两种打印成果(虚拟打印+ 物理打印),如下图所示:

(1 )AdobePDF 虚拟打印机,无物理边距打印

(2 )实际物理打印机HP LaserJet P4515 打印机,物理边距(4.8, 4.1)mm ,以前两张图是不同时期打印,图纸上的物理边距线存在打印不完全现象,这就是经常出现的打印不完全现象,可以看出两张图纸的上和顶部边距不同,这是人工装载纸盒的时候,可能存在一定偏差,造成打印不完全等各种现象。但是两张图都保证了页面边距完全的效果,都是有25.4mm 的默认边距,实现真正的可打印区域的完全打印功能。

转载本文请联系原作者获取授权,同时请注明本文来自杨清科学网博客。

链接地址:

Original: https://www.cnblogs.com/zeroone/p/10360302.html
Author: 武胜-阿伟
Title: C#实现无物理边距 可打印区域的绘图打印 z

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/554402/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球