zoukankan      html  css  js  c++  java
  • C# 图片打印杂谈

    日常开头水一下,看了下上次博客,一年零八天了,啧啧,奢侈。

    最近这个工作挺满意的,是我想要的发展方向,后续要做机器学习,现在得先把公司之前堆积的问题解决了。

    谈人生到此结束,还是说正题吧。(感觉这标题吸引不了人啊)

     

     

    打印:PrintDocument

    环境:WPF and Winform

    要求:排版并打印图片

    之前一直不明白很多参数的问题,现在想清楚了,随手记录一下。

    WPF暂放一边,把winform先解决了,跟百度烂大街的一样是 PrintPage事件Graphics绘制来打印的。其它部分参考

    https://www.cnblogs.com/hsiang/p/6921817.html

    首先用Graphics绘制一直不明白的是该怎么绘制,纸张的大小是多少,怎么样才能按照指定尺寸打印。

    //我们先聊聊纸张大小,看纸张大小可以在开始文件打印
      PrintDocument.Print(); 
    并选好打印机后,在 PrintPage事件里绘制要打印的数据
    private void pdControl_PrintPage(object sender, PrintPageEventArgs e)
    {
        var printDocument = (PrintDocument)sender;
        //纸张的高和宽
        var paper_h = printDocument.DefaultPageSettings.PaperSize.Height;
        var paper_w = printDocument.DefaultPageSettings.PaperSize.Width;
    }

    然而知道高和宽但不知道单位啊,这高和宽到底是像素还是英寸还是其它的什么鬼。

    在实例化new PaperSize就看得到注释:

    百分之一英寸为单位

     这样第一个问题就解决了,纸张的大小是 printDocument.DefaultPageSettings.PaperSize,并且单位是百分之一英寸。

    不过不要太相信这个,比如我要打印的图片是6寸的(特地量了),但给出是尺寸宽多了0.15In,高多了0.13In。好歹win自带的PDF打印A4纸也就相差0.002以下好吧。这个为什么有误差待大神解释。

    那么第二个问题(第三个):该怎么绘制才能按照指定尺寸打印

    既然我们知道了打印的范围也就避免了绘制超出纸张。那么我们就要绘制内容了,咱这只讲图片,其它的也差不多。

    我做的是根据图片的大小铺满整个打印纸。 

       //我们先建个类,来记录要图片大小及纸张大小
    //这个类只是方便调试转换度量单位,实际应用只选一种计算单位就行了 class PrintUnit {
         //图片大小,这里图片其实是一寸的照片
    public int unit_w = 259; public int unit_h = 377;
         //纸张大小300dpi 6*300 4*300
    public PaperSize paperSize = new PaperSize("A6", 1800, 1200);
         //度量单位
    private GraphicsUnit unit = GraphicsUnit.Pixel; public GraphicsUnit Unit { get => unit; set { unit = value;
              //如果度量单位为毫米
    if (unit == GraphicsUnit.Millimeter) {
                //具体换算为 1200/300*25.4 约等于 102
      paperSize.Height
    = 102; paperSize.Width = 152 ;
    unit_w
    = 22; unit_h = 32; } } } }

    然后在 PrintPage事件里得到计算打印纸可以铺满多少图片

                PrintUnit printUnit = new PrintUnit();
           g.PageUnit = printUnit.Unit;
           column = printUnit.paperSize.Width / printUnit.unit_w; row = printUnit.paperSize.Height / printUnit.unit_h; for (int i = 0; i < row; i++) { for (int j = 0; j < column; j++) { //g.DrawImage( // Resources._1, // new Rectangle(j * printUnit.unit_w, i * printUnit.unit_h, printUnit.unit_w, printUnit.unit_h), // new Rectangle(0, 0, Resources._1.Width, Resources._1.Height), // g.PageUnit); g.DrawImage(Resources._1, j * printUnit.unit_w, i * printUnit.unit_h, printUnit.unit_w, printUnit.unit_h); } }

      有趣的是在DrawImage(Image image, Rectangle destRect, Rectangle srcRect, GraphicsUnit srcUnit);的重载方法里图片有误差,原因不明。

     有点乱了,来强行解释一波。

    在打印事件里PrintPageEventArgs.PageUnit 是设置度量单位,就是你要绘制的单位是按照像素还是毫米或其它,默认是百分之一英寸。

    //比如你要打印A4纸210mm×297mm ,打印PrintPage事件里设置度量单位为Millimeter
    g.PageUnit=GraphicsUnit.Millimeter;
    //铺满整个A4纸
    g.DrawImage(image, 0, 0, 210, 297);

     就是这么简单,不过不建议用毫米为单位,因为这样图片容易误差,这是因为绘制时会将毫米转换成像素。

    很明显用毫米来绘制时会有间隙

     懒得排版,事多,溜了溜了。

     

     

     前方高能提醒,代码很乱,不用谢。

     https://files.cnblogs.com/files/zlyxm/DemoPrint_zlyxm.rar

      

     

     

  • 相关阅读:
    《Android Studio有用指南》4.27 使用演示模式
    深度学习与计算机视觉系列(9)_串一串神经网络之动手实现小样例
    银行业务调度系统的实现
    高通平台读写nv总结【转】
    LTE-A 载波聚合(Carrier Aggregation)介绍【转】
    DSDS,双模,双卡,双待,单待,双通,单通,概念及相互关系?【转】
    【LTE基础知识】SGLTE, SVLTE, CSFB, VoLTE【转】
    SRLTE,SGLTE,SVLTE,CSFB,VoLTE的区别【转】
    高通计划停用MSM 以SDM为移动平台命名【转】
    高通平台文档下载【学习笔记】
  • 原文地址:https://www.cnblogs.com/zlyxm/p/10937940.html
Copyright © 2011-2022 走看看