代码之家  ›  专栏  ›  技术社区  ›  Alex Gordon

C-如何打印纵横比/整页

c#
  •  4
  • Alex Gordon  · 技术社区  · 14 年前

    我正在打印图表控件,单击按钮:

    chart1.SaveImage(ms, ChartImageFormat.Bmp);
    Bitmap bm = new Bitmap(ms);
    
    PrintDocument doc = new PrintDocument();
    doc.PrintPage += (s, ev) =>
    {
        ev.Graphics.DrawImage(bm, Point.Empty); // adjust this to put the image elsewhere
        ev.HasMorePages = false;
    };
    doc.DefaultPageSettings.Landscape = true;
    
    doc.Print();
    

    如何强制它打印控件以使其适合页面大小(保留纵横比)?

    3 回复  |  直到 6 年前
        1
  •  9
  •   Peter Mortensen icecrime    12 年前

    至少有两种不同的方法可以做到这两个方面 包括缩放要打印的图像以适应页面大小 所选打印机的:

    1)使用 .NET 设施 post ):

        private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            Image i = pictureBox1.Image;
    
            float newWidth = i.Width * 100 / i.HorizontalResolution;
            float newHeight = i.Height * 100 / i.VerticalResolution;
    
            float widthFactor = newWidth / e.MarginBounds.Width;
            float heightFactor = newHeight / e.MarginBounds.Height;
    
            if(widthFactor>1 | heightFactor > 1)
            {
                if(widthFactor > heightFactor)
                {
                    newWidth = newWidth / widthFactor;
                    newHeight = newHeight / widthFactor;
                }
                else
                {
                    newWidth = newWidth / heightFactor;
                    newHeight = newHeight / heightFactor;
                }
            }
            e.Graphics.DrawImage(i, 0, 0, (int)newWidth, (int)newHeight);
        }
    }
    

    2) P/Invoke'ing Windows API 来自gdi和flat gdi的调用(这要复杂得多,但速度更快,您可以传递位图文件的纯字节数组(将文件读取为byte[]),如果需要此代码,请向我提供电子邮件):

      private static extern bool ClosePrinter(IntPtr hPrinter);
      private static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);
      private static extern int SetJob(IntPtr hPrinter, int JobId, int Level, ref byte pJob, int Command_Renamed);
      private static extern int GdiplusStartup(out IntPtr token, ref StartupInput input, out StartupOutput output);
      private static extern int GdiplusShutdown(IntPtr token);
      internal static extern int GdipLoadImageFromStream([In, MarshalAs(UnmanagedType.Interface)]IStream stream, out IntPtr image);
      internal static extern int GdipDisposeImage(IntPtr image);
      static internal extern int GdipCreateFromHDC2(IntPtr hDC, IntPtr hDevice, out IntPtr graphics);
      static internal extern int GdipDeleteGraphics(IntPtr graphics);
      static internal extern int GdipReleaseDC(IntPtr graphics, IntPtr hdc);
      internal static extern int GdipGetImageDimension(IntPtr image, out float width, out float height);
      internal static extern int GdipGetDpiX(IntPtr graphics, out float dpi);
      internal static extern int GdipGetDpiY(IntPtr graphics, out float dpi);
      static internal extern int GdipDrawImageRectI(IntPtr graphics, IntPtr image, int x, int y, int width, int height);
      private static extern IntPtr CreateDC([MarshalAs(UnmanagedType.LPStr)] string lpszDriver, [MarshalAs(UnmanagedType.LPStr)] string lpszDevice, [MarshalAs(UnmanagedType.LPStr)] string lpszOutput, IntPtr lpInitData);
      private static extern bool DeleteDC(IntPtr hdc);
      private static extern int StartDoc(IntPtr hdc, DOCINFO lpdi);
      private static extern int EndDoc(IntPtr hdc);
      private static extern int StartPage(IntPtr hdc);
      private static extern int EndPage(IntPtr hdc);
      private static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
    
        2
  •  0
  •   Dave Cousineau    9 年前

    我就是这么做的。令人恼火的是,图表控件将只绘制与屏幕上大小相同的内容。我发现解决这个问题的唯一方法是手动调整大小。然后,由于它可能不喜欢在窗体上调整大小,这也涉及到将其临时从窗体中删除。

    所有这些,我最终得到了这样的结果:

    Chart ChartBox { get; private set; }
    
    ...
    
    var oldParent = ChartBox.Parent;
    var oldSize = ChartBox.Size;
    
    ChartBox.Parent = null;
    ChartBox.Size = new Size(width, height);
    
    ChartBox.Printing.Print();
    
    ChartBox.Parent = oldParent;
    ChartBox.Size = oldSize;
    

    根据窗体的不同,您可能还需要保存和恢复图表控件的其他属性。

        3
  •  0
  •   Adeel Kamran    6 年前

    试试这个代码:

    e.Graphics.DrawImage(img, e.Graphics.VisibleClipBounds);