2012-04-02 292 views
24

在C#中,我試圖用下面的代碼使用PrintDocument類打印圖像。圖像大小爲1200像素寬,1800像素高。我試圖使用小型zeebra打印機在4 * 6紙張上打印此圖像。但該程序僅打印4 * 6的大圖像。這意味着它不會將圖像調整爲紙張大小!使用PrintDocument打印圖像。如何調整圖像以適合紙張尺寸

 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打印打印相同的圖像(點擊右鍵並選擇打印,它會自動縮放到紙張大小和打印正確。這意味着所有的東西都在4 * 6紙。)我怎麼做的在我的C#程序中也一樣?

+3

如果你喜歡答案,接受它。它給予回答你的人信用,並幫助其他人尋找答案,以更快找到合適的人 – 2014-10-14 07:15:39

回答

31

傳遞到DrawImage方法的參數應該是紙張上圖像的大小而不是圖像本身的大小,然後DrawImage命令將爲您處理縮放。可能最簡單的方法是使用DrawImage命令的以下重寫。

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

注意:如果圖像的比例與矩形不一樣,這會使圖像傾斜。關於圖像大小和紙張大小的一些簡單數學運算將允許您創建一個適合紙張邊界的新矩形,而不會使圖像傾斜。

+2

這應該是答案!感謝您的解決方案,它按預期工作。 – Crushermike 2015-06-04 19:07:07

20

不要踐踏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(); 
+1

很好的答案,但我用args.PageBounds – 2017-12-31 10:33:29

2

你可以使用我的代碼在這裏

//Print Button Event Handeler 
private void btnPrint_Click(object sender, EventArgs e) 
{ 
    PrintDocument pd = new PrintDocument(); 
    pd.PrintPage += PrintPage; 
    //here to select the printer attached to user PC 
    PrintDialog printDialog1 = new PrintDialog(); 
    printDialog1.Document = pd; 
    DialogResult result = printDialog1.ShowDialog(); 
    if (result == DialogResult.OK) 
    { 
     pd.Print();//this will trigger the Print Event handeler PrintPage 
    } 
} 

//The Print Event handeler 
private void PrintPage(object o, PrintPageEventArgs e) 
{ 
    try 
    { 
     if (File.Exists(this.ImagePath)) 
     { 
      //Load the image from the file 
      System.Drawing.Image img = System.Drawing.Image.FromFile(@"C:\myimage.jpg"); 

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

      if ((double)img.Width/(double)img.Height > (double)m.Width/(double)m.Height) // image is wider 
      { 
       m.Height = (int)((double)img.Height/(double)img.Width * (double)m.Width); 
      } 
      else 
      { 
       m.Width = (int)((double)img.Width/(double)img.Height * (double)m.Height); 
      } 
      e.Graphics.DrawImage(img, m); 
     } 
    } 
    catch (Exception) 
    { 

    } 
} 
+0

'替換args.MarginBounds''e.Graphics.DrawImage(img,m);'解決了我的問題.. +1 – 2018-01-24 12:00:35

2

答:

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()); 
    } 
} 
+0

上面的代碼測試自己並在我的wpf kisok應用程序中正常工作。 – KhanSahib 2015-03-09 12:50:35

3

由BBOY提供的解決方案正常工作。但在我的情況下,我不得不使用

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

這將只打印表格。當我使用MarginBounds時,即使窗體小於監視器屏幕,它也會打印整個屏幕。 PageBounds解決了這個問題。感謝BBoy!

+0

完美,爲我工作! (@Boy答案也不錯) – iedmrc99 2017-11-05 14:01:33

4

同意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(); 
    } 
+0

'PageBounds'在我的工作中'MarginBounds'的打印方式太小。謝謝! – Goose 2017-11-10 17:49:08