C# 使用PrintDocument打印图像。如何调整图像以适应纸张大小

C# 使用PrintDocument打印图像。如何调整图像以适应纸张大小,c#,printing,printdocument,C#,Printing,Printdocument,在C#中,我尝试使用PrintDocument类打印图像,代码如下。图像大小为1200像素宽,1800像素高。我正在尝试使用小型zeebra打印机在4*6的纸张上打印此图像。但该程序只打印4*6的大图像。这意味着它没有将图像调整到纸张大小 PrintDocument pd = new PrintDocument(); pd.PrintPage += (sender, args) => { Image i = Image.FromFile(

在C#中,我尝试使用PrintDocument类打印图像,代码如下。图像大小为1200像素宽,1800像素高。我正在尝试使用小型zeebra打印机在4*6的纸张上打印此图像。但该程序只打印4*6的大图像。这意味着它没有将图像调整到纸张大小

     PrintDocument pd = new PrintDocument();
     pd.PrintPage += (sender, args) =>
     {
           Image i = Image.FromFile("C://tesimage.PNG");
           Point p = new Point(100, 100);
           args.Graphics.DrawImage(i, 10, 10, i.Width, i.Height);
     };
     pd.Print();

当我使用Window print打印相同的图像时(右键单击并选择打印,它会自动缩放到纸张大小并正确打印。这意味着所有内容都是4*6纸张。)如何在我的C#程序中执行相同的操作?

传递到DrawImage方法中的参数应该是希望图像在纸上的大小,而不是图像本身的大小,然后DrawImage命令将为您处理缩放。最简单的方法可能是使用以下DrawImage命令替代

args.Graphics.DrawImage(i, args.MarginBounds);

注意:如果图像的比例与矩形不同,则会使图像倾斜。通过对图像大小和纸张大小进行简单的数学计算,您可以创建一个新的矩形,该矩形适合纸张的边界,而不会使图像倾斜。

不要践踏BBoy已经不错的答案,但我已经完成了保持纵横比的代码。我接受了他的建议,所以他应该在这里获得部分荣誉

PrintDocument pd = new PrintDocument();
pd.DefaultPageSettings.PrinterSettings.PrinterName = "Printer Name";
pd.DefaultPageSettings.Landscape = true; //or false!
pd.PrintPage += (sender, args) =>
{
    Image i = Image.FromFile(@"C:\...\...\image.jpg");
    Rectangle m = args.MarginBounds;

    if ((double)i.Width / (double)i.Height > (double)m.Width / (double)m.Height) // image is wider
    {
        m.Height = (int)((double)i.Height / (double)i.Width * (double)m.Width);
    }
    else
    {
        m.Width = (int)((double)i.Width / (double)i.Height * (double)m.Height);
    }
    args.Graphics.DrawImage(i, m);
};
pd.Print();
你可以在这里使用我的代码

答复:

public void Print(string FileName)
{
    StringBuilder logMessage = new StringBuilder();
    logMessage.AppendLine(string.Format(CultureInfo.InvariantCulture, "-------------------[ START - {0} - {1} -------------------]", MethodBase.GetCurrentMethod(), DateTime.Now.ToShortDateString()));
    logMessage.AppendLine(string.Format(CultureInfo.InvariantCulture, "Parameter: 1: [Name - {0}, Value - {1}", "None]", Convert.ToString("")));

    try
    {
        if (string.IsNullOrWhiteSpace(FileName)) return; // Prevents execution of below statements if filename is not selected.

        PrintDocument pd = new PrintDocument();

        //Disable the printing document pop-up dialog shown during printing.
        PrintController printController = new StandardPrintController();
        pd.PrintController = printController;

        //For testing only: Hardcoded set paper size to particular paper.
        //pd.PrinterSettings.DefaultPageSettings.PaperSize = new PaperSize("Custom 6x4", 720, 478);
        //pd.DefaultPageSettings.PaperSize = new PaperSize("Custom 6x4", 720, 478);

        pd.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
        pd.PrinterSettings.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);

        pd.PrintPage += (sndr, args) =>
        {
            System.Drawing.Image i = System.Drawing.Image.FromFile(FileName);

            //Adjust the size of the image to the page to print the full image without loosing any part of the image.
            System.Drawing.Rectangle m = args.MarginBounds;

            //Logic below maintains Aspect Ratio.
            if ((double)i.Width / (double)i.Height > (double)m.Width / (double)m.Height) // image is wider
            {
                m.Height = (int)((double)i.Height / (double)i.Width * (double)m.Width);
            }
            else
            {
                m.Width = (int)((double)i.Width / (double)i.Height * (double)m.Height);
            }
            //Calculating optimal orientation.
            pd.DefaultPageSettings.Landscape = m.Width > m.Height;
            //Putting image in center of page.
            m.Y = (int)((((System.Drawing.Printing.PrintDocument)(sndr)).DefaultPageSettings.PaperSize.Height - m.Height) / 2);
            m.X = (int)((((System.Drawing.Printing.PrintDocument)(sndr)).DefaultPageSettings.PaperSize.Width - m.Width) / 2);
            args.Graphics.DrawImage(i, m);
        };
        pd.Print();
    }
    catch (Exception ex)
    {
        log.ErrorFormat("Error : {0}\n By : {1}-{2}", ex.ToString(), this.GetType(), MethodBase.GetCurrentMethod().Name);
    }
    finally
    {
        logMessage.AppendLine(string.Format(CultureInfo.InvariantCulture, "-------------------[ END  - {0} - {1} -------------------]", MethodBase.GetCurrentMethod().Name, DateTime.Now.ToShortDateString()));
        log.Info(logMessage.ToString());
    }
}

BBoy提供的解决方案效果良好。但在我的情况下,我不得不使用

e.Graphics.DrawImage(memoryImage, e.PageBounds);

这将只打印表单。当我使用MarginBounds时,即使表单小于监视器屏幕,它也会打印整个屏幕。他解决了这个问题。谢谢你

同意TonyM和BBoy-这是原始4*6标签打印的正确答案。(args.PageBounds)。这对我打印Endicia API服务装运标签很有用

private void SubmitResponseToPrinter(ILabelRequestResponse response)
    {
        PrintDocument pd = new PrintDocument();
        pd.PrintPage += (sender, args) =>
        {
            Image i = Image.FromFile(response.Labels[0].FullPathFileName.Trim());
            args.Graphics.DrawImage(i, args.PageBounds);
        };
        pd.Print();
    }

所有这些答案都有一个问题,那就是总是将图像拉伸到页面大小,并在尝试时切断一些内容。
找到了一个更简单的方法。

我自己的解决方案只有拉伸(这个词对吗?)如果图像太大,可以使用多份拷贝和页面方向

                PrintDialog dlg = new PrintDialog();

            if (dlg.ShowDialog() == true)
            {
                BitmapImage bmi = new BitmapImage(new Uri(strPath));

                Image img = new Image();
                img.Source = bmi;

                if (bmi.PixelWidth < dlg.PrintableAreaWidth ||
                           bmi.PixelHeight < dlg.PrintableAreaHeight)
                {
                    img.Stretch = Stretch.None;
                    img.Width = bmi.PixelWidth;
                    img.Height = bmi.PixelHeight;
                }


                if (dlg.PrintTicket.PageBorderless == PageBorderless.Borderless)
                {
                    img.Margin = new Thickness(0);
                }
                else
                {
                    img.Margin = new Thickness(48);
                }
                img.VerticalAlignment = VerticalAlignment.Top;
                img.HorizontalAlignment = HorizontalAlignment.Left;

                for (int i = 0; i < dlg.PrintTicket.CopyCount; i++)
                {
                    dlg.PrintVisual(img, "Print a Image");
                }
            }
PrintDialog dlg=新建PrintDialog();
if(dlg.ShowDialog()==true)
{
BitmapImage bmi=新的BitmapImage(新Uri(strPath));
图像img=新图像();
img.来源=体重指数;
如果(bmi.PixelWidth
如果您喜欢答案,请接受它。它为回答您的人提供了荣誉,并帮助其他搜索答案的人找到合适的答案,fasterAbove代码测试自己,并在我的wpf kisok应用程序中运行良好;尽管日志消息内容应该被删除,因为这依赖于其他不存在的代码。这应该是答案!感谢您提供的解决方案。args.Graphics.DrawImage(i,args.PageBounds)
PageBounds
MarginBounds
打印太小的地方工作。谢谢回答很好,但是我用args.PageBounds
e.Graphics.DrawImage(img,m)替换了args.MarginBounds解决了我的问题+1您能否在答案中包含代码而不是链接到代码?
                PrintDialog dlg = new PrintDialog();

            if (dlg.ShowDialog() == true)
            {
                BitmapImage bmi = new BitmapImage(new Uri(strPath));

                Image img = new Image();
                img.Source = bmi;

                if (bmi.PixelWidth < dlg.PrintableAreaWidth ||
                           bmi.PixelHeight < dlg.PrintableAreaHeight)
                {
                    img.Stretch = Stretch.None;
                    img.Width = bmi.PixelWidth;
                    img.Height = bmi.PixelHeight;
                }


                if (dlg.PrintTicket.PageBorderless == PageBorderless.Borderless)
                {
                    img.Margin = new Thickness(0);
                }
                else
                {
                    img.Margin = new Thickness(48);
                }
                img.VerticalAlignment = VerticalAlignment.Top;
                img.HorizontalAlignment = HorizontalAlignment.Left;

                for (int i = 0; i < dlg.PrintTicket.CopyCount; i++)
                {
                    dlg.PrintVisual(img, "Print a Image");
                }
            }