C# 以高于屏幕分辨率的dpi打印表单

C# 以高于屏幕分辨率的dpi打印表单,c#,winforms,printing,screen-resolution,dpi,C#,Winforms,Printing,Screen Resolution,Dpi,问题: 我们需要有关如何使用WinForms自动缩放到不同DPI的功能的帮助,以允许我们以600dpi打印表单,而不是以屏幕DPI打印表单 因为你看到的就是你打印出来的东西,我们只是简单地把我们布置得很好的窗口打印出来,关闭滚动条和按钮等等。除了一件事外,它的分辨率是96dpi或120dpi,不管屏幕分辨率是多少,这两种分辨率都很高,而且我们的客户都在抱怨这两种分辨率都不专业。尽管它的可读性与屏幕上的一样,但您希望打印的文档比屏幕上的文档更可读……您希望能够看到更多的细节,能够阅读更小的文本,等

问题:

我们需要有关如何使用WinForms自动缩放到不同DPI的功能的帮助,以允许我们以600dpi打印表单,而不是以屏幕DPI打印表单

因为你看到的就是你打印出来的东西,我们只是简单地把我们布置得很好的窗口打印出来,关闭滚动条和按钮等等。除了一件事外,它的分辨率是96dpi或120dpi,不管屏幕分辨率是多少,这两种分辨率都很高,而且我们的客户都在抱怨这两种分辨率都不专业。尽管它的可读性与屏幕上的一样,但您希望打印的文档比屏幕上的文档更可读……您希望能够看到更多的细节,能够阅读更小的文本,等等

考虑的备选方案:

考虑到我们的自动缩放功能非常好,所以我们的窗口在96dpi、120dpi、144 dpi等情况下看起来都很好,我们希望我们可以在600dpi下绘制窗口,然后打印出来

或者,我们在屏幕上画一个比正常值大5-6倍的窗口,这样我们的像素数与600dpi相同,但是是96或120dpi……但是,不管打印机是什么,我们都会在打印页面上以300dpi或600dpi的速度画一个巨大的窗口

如果你能告诉我们如何做这些选择,或者如果你能给我们一个不同的方式来实现我们的目标,那么我们将不胜感激

当前代码:

如果有必要,我们的表单由一个FlowLayoutPanel组成,它将其他较小的FlowLayoutPanel放入列中,这些较小的FlowLayoutPanel将文本框、RichTextBox、第三方RichTextEditor、PictureBoxs和DataGridView组成一列。我们使用从PrintDocument派生的类实现OnBeginPrint、OnPrintPage和OnEndPrint。在OnPrintPage中,它在实际屏幕的下方和右侧操纵正常的屏幕外窗口以适应页面大小,然后要求主面板顶部的FlowLayoutPanel绘制到位图,然后使用传递到PrintEventArgs的图形对象绘制位图。我们还使用Graphics.DrawString为每页应用页脚。主要代码:

                    using (Bitmap bm = new Bitmap(sz.Width, sz.Height))
                    {
                        Rectangle rect = new Rectangle(0, 0, sz.Width, sz.Height);
                        mp.DrawToBitmap(bm, rect);
                        e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; // so footer is anti-aliased
                        e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;  // so when we scale up, we smooth out the jaggies somewhat
                        e.Graphics.DrawImage(bm, this.MarginBounds, rect, GraphicsUnit.Pixel);
                        if (this.Footer != null)
                            e.Graphics.DrawImage(this.Footer, this.FooterLocation);
                        if (!string.IsNullOrEmpty(pageNumber))
                        {
                            e.Graphics.DrawString(pageNumber, KBStyle.Normal.Font, Brushes.Black,
                                                  this.MarginBounds.X, this.FooterLocation.Y + FooterOffset);
                        }
                    }
我们应该如何做到这一点以使打印页面达到600dpi?甚至300 dpi也不错

当我们打印这张照片时,从120dpi机器上打印出来的效果要比从96dpi机器上打印出来的效果好得多,因此我们知道它是以屏幕分辨率打印的。但也让我们想知道是否有简单的方法告诉它“这个表单应该以600 dpi的速度绘制”,然后上面所有的代码就可以正常工作了

注意:如果我们获取一个EMF增强的元文件,并按照上面的代码将其打印到打印机上,则EMF的输出速度为600dpi。不幸的是,我们还没有找到可以在FlowLayoutPanel而不是DrawToBitmap上调用的DrawToEMF方法。将位图更改为600dpi没有帮助…DrawToBitmap方法似乎仍然以屏幕分辨率绘制位图


谢谢

这里完全是猜测,但是使用CSS呢?我在猜测你要缩放多少,不知道你怎么知道打印机的缩放比例。 使用“打印介质查询”可以进行打印,但不使用屏幕视图

@media print {
  * {
    transform: scale(2000px,2000px);
  }
}

好吧,我已经弄明白了。。。而且效果很好

我仍然不知道如何创建300dpi的表单并使用自动缩放功能

但是

我已经证明,如果在96 dpi下创建比需要大3.125倍的窗口,并将字体放大3.125倍,以此类推,使所有内容都是300 dpi下需要的像素数,即使屏幕是96 dpi,也可以使用普通控件。DrawToBitmap功能将其转换为位图,然后你可以使用GDI Graphics.DrawImagethatGiantBitmap,giantSrcRect,PageSizedStrect到打印机图形对象,它会将这些巨大的96dpi像素映射到页面大小300dpi的像素,给你一个300dpi的打印。太好了

对于任何支持调整大小并允许用户任意缩放内容的窗口,打印所见即所得都很容易:

在打印文档的OnBeginPrint中,执行以下操作:

1可选地复制表单,以免弄乱用户正在查看的内容

2将要打印的表单从所有屏幕的下方和右侧移出屏幕

3设置窗体,以便允许其增长大于屏幕大小。默认情况下,WinForms不会增长大于屏幕大小

4将300 dpi除以屏幕dpi得到增长因子

5通过生长因子让你的身体成长

6如果内容不随窗体大小自动缩放,则按增长因子缩放内容

在打印文档的OnPrintPage中,执行以下操作:

7在窗体中要打印的任何控件上,都要将DrawToBitmap映射到该控件大小的位图

8.在e.Graphics上绘制GiantBitmap、giantSrcRect、PageSizedStrect的图像

那个电话会
如果你的巨型位图中有那么多像素,请以打印机的分辨率绘制。在本例中,我计算了位图以给出300 dpi所需的像素数,因此即使打印机为600 dpi,我也将得到300 dpi的打印输出。如果需要完整的600 dpi,只需在步骤4的计算中使用600 dpi。

OP要求使用winforms解决方案,该解决方案不使用CSSY您无法将FlowLayoutPanel屏幕视图转换为可打印视图。您必须使用DrawString方法在PrintPage事件中创建自己的绘图例程。没有免费午餐。@LarsTech,我不确定我是否理解你的评论。。。DrawToBitmap在FlowLayoutPanel上运行良好。。。这么多钱可以说是免费午餐。。。这是很容易使其可打印,我们现在使用它,成功。在上面的代码中,mp是一个FlowLayoutPanel。唯一的问题是,它是在屏幕分辨率这样做。而且,即使窗口的大小与页面上的像素相匹配,我们似乎仍然只能得到屏幕分辨率。打印机的分辨率要高得多。如果您想让它在打印机分辨率上看起来更漂亮,您必须在涉及文本的地方删除DrawToBitmap例程,并开始使用打印机DrawString例程。