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

时间:2016-02-29 04:18:02

标签: c# winforms printing screen-resolution dpi

问题:

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

对于你所看到的是什么 - 你得到的打印,我们只是简单地采用我们精心布置的窗口并打印它(关闭滚动条和按钮等)。除了一件事之外,它的效果非常好:它出现在96dpi或120dpi(无论屏幕分辨率如何)......其中任何一个都看起来有颗粒感和不专业(我们的客户都在抱怨)。虽然它与屏幕上的内容一样可读,但您希望打印的文档比屏幕上更易读...您希望能够看到更多细节,能够阅读较小的文本等。

考虑的替代方案:

鉴于我们的自动缩放效果很好,我们的窗口看起来很好,分别是96dpi,120dpi,144 dpi等,我们希望能够以600dpi的速度绘制窗口,然后打印出来。

或者,我们在屏幕外绘制比正常大5-6倍的窗口,这样我们的像素数与600dpi相同,但是在96或120 dpi ...但是然后将那个巨大的窗口绘制到打印的页面上300或600 dpi(无论打印机是什么)。

如果你能告诉我们如何做其中任何一种选择,或者如果你能给我们一个不同的方法来实现我们的目标,那么我们将非常感激。

当前代码:

如果它很重要,我们的Form包含一个FlowLayoutPanel,将其他较小的FlowLayoutPanel放入列中,那些较小的FlowLayoutPanels放置一列TextBoxes,RichTextBoxes,第三方RichTextEditor,PictureBoxes和DataGridViews。我们使用从PrintDocument派生的类实现OnBeginPrint,OnPrintPage和OnEndPrint。在OnPrintPage中,它在屏幕外(实际屏幕的右下方)操作我们的普通窗口以适合页面大小,然后将我们的主面板(顶部FlowLayoutPanel)请求DrawToBitmap,然后使用传递给PrintEventArgs的Graphics对象来绘制DrawImage那个位图。我们还使用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方法似乎仍然以屏幕分辨率绘制位图。

谢谢!

2 个答案:

答案 0 :(得分:1)

好的,我已经想到了......而且效果很好!

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

但是...

我已经证明,如果你创建比96 dpi所需大3.125倍的窗口,并将字体缩放到3.125x,依此类推,这样一切都是像素数,你需要达到300dpi,甚至虽然您的屏幕是96dpi,那么您可以使用普通的Control.DrawToBitmap()功能将其转换为Bitmap,然后您可以将GDI Graphics.DrawImage(thatGiantBitmap,giantSrcRect,pageSizeDestRect)用于打印机Graphics对象,以及它会将这些巨大的96dpi像素映射到页面大小为300dpi的像素,为您提供300dpi的打印效果。完美。

对于任何支持调整大小的窗口,让我们的用户随意缩放内容,然后打印你看得出的内容很简单:

在PrintDocument的 OnBeginPrint 中,执行:

(1)可选择复制表格,以免弄乱用户正在查看的内容

(2)将要打印的表格移出屏幕(所有屏幕的下方和右侧)

(3)设置表单,使其大小超过屏幕大小(默认情况下WinForms不会比屏幕大)

(4)按屏幕dpi划分300 dpi以获得增长因子

(5)按生长因子增长你的形式

(6)按增长因子缩放其内容(如果它们没有使用表格大小自动缩放/自动缩放)

在PrintDocument的 OnPrintPage 中,执行:

(7)在要打印的表单中的任何控件上,将DrawToBitmap()设置为该控件大小的位图

(8)关于e.Graphics do DrawImage(thatGiantBitmap,giantSrcRect,pageSizeDestRect)

如果你的thatGiantBitmap中有那么多像素,那么DrawImage调用将以打印机的分辨率绘制。在这种情况下,我计算了位图以给出300 dpi所需的像素数,因此即使打印机是600 dpi,我也会得到300 dpi的打印输出。如果您需要完整的600 dpi,请在步骤4的计算中使用600 dpi。

答案 1 :(得分:-3)

总猜这里,但是使用CSS怎么样?我猜你想要扩展多少,并且不知道你怎么知道打印机的规模。 使用打印介质查询使此功能可用于打印,但仅保留屏幕视图。

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