Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / multimedia / image-processing

Yet another Windows printing tip

4.00/5 (2 votes)
7 Oct 2013CPOL1 min read 8.1K  
How to print an image to a printer within a proper size

Introduction 

This piece of code prepare an image from image box to a print by using an instance of PrintDocument. This snippet has been written after I try to find a solution to print pictures on Windows printer without distortion twice per year. So I position it as a memo sticker.

Background 

You should be smart enough to: 

  • Create and design a Windows form with PictureBox 
  • Place a PrintDocument and optional PrintPreview dialog on this form 
  • Set an event handler that intercepts PrintPage event of PrintDocument

Using the code 

I need to print images on some legacy media. So I've got three issues: 

  • I've got only Windows driver for the printer 
  • I have to use print area precisely
  • I've got two phase printing (because of the colored ribbon)

This code has been written as a C# implementation. You can be smarter, of course, and try to use this code in the other places.

So the printing code looks like this:

C#
Graphics gPrn = e.Graphics; // I think this makes my code easier to understand
PageSettings pageSettings = e.PageSettings; // and shorter :-)
float px = 0;
float py = 0;
float scaleFactorX, scaleFactorY;
RectangleF r;
RectangleF rs;
// DPI divider, because of my printer reports print area in 0.01 inch units
float dpi_div = 100.0F; 

// compute value to convert printer's horisontal cordinates and width in pixels
px = pageSettings.PrinterResolution.X / dpi_div;
// scale factor for picture's horisontal cordinates and width
scaleFactorX = pageSettings.PrinterResolution.X / pictureBox1.Image.HorizontalResolution;
// compute value to convert printer's vertical cordinates and height in pixels
py = pageSettings.PrinterResolution.Y / dpi_div;
// scale factor for picture's vertical cordinates and height in pixels
scaleFactorY = pageSettings.PrinterResolution.Y / pictureBox1.Image.VerticalResolution;
// please remember: horisontal resolution not alvays equal to a vertical resolution

// compute image rectangle with printer's margins
r = new RectangleF(pageSettings.PrintableArea.Left * px,
    pageSettings.PrintableArea.Top * py,
    ((float)pictureBox1.Width), ((float)pictureBox1.Height));
// compute printer's (destionation) area 
rs = new RectangleF(pageSettings.PrintableArea.Left * px,
    pageSettings.PrintableArea.Top * py,
    r.Width * scaleFactorX, // use print width of the image
    r.Height * scaleFactorY);   // use print height of the image
// try to reset printer's margins (hardware margins can not be bypassed)
pageSettings.Margins.Top = 0;
pageSettings.Margins.Left = 0;
// print our image to a printer or preview dialog
gPrn.DrawImage(pictureBox1.Image, r, rs, GraphicsUnit.Pixel);

After I can to win autosave I will try to mark variable names. For now it prevents me to mark them (reset my weak attempts).

Points of Interest 

The most important point from, that I've learned from this code: Screen's resolution for now is less detailed than printer's one. And this must be remembered.

History 

  • The article created at 17:30 (MSK) October 7 in the year of 2013.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)