Search code examples
c#winformsprintingprintdocumentblurry

How do I print clear text from a windows form?


I have successfully printed a windows form, but all the text is slightly blurry. I have concluded that this is a result of the resolution of the screen being much less than the resolution the printer uses. Is there a fundamental flaw in my approach or is there a way to reformat the text prior to printing so that it comes out crisp?

void PrintImage(object o, PrintPageEventArgs e)
{
    int x = SystemInformation.WorkingArea.X;
    int y = SystemInformation.WorkingArea.Y;
    int width = panel1.Width;
    int height = panel1.Height;

    Rectangle bounds = new Rectangle(x, y, width, height);

    Bitmap img = new Bitmap(width, height);

    this.DrawToBitmap(img, bounds);
    Point p = new Point(100, 100);
    e.Graphics.DrawImage(img, p);
}

private void BtnPrint_Click(object sender, EventArgs e)
{
    btnPrint.Visible = false;
    btnCancel.Visible = false;
    if(txtNotes.Text == "Notes:" || txtNotes.Text == "")
    {
        txtNotes.Visible = false;
    }
    PrintDocument pd = new PrintDocument();
    pd.PrintPage += new PrintPageEventHandler(PrintImage);
    pd.Print();
}

Solution

  • Is there a fundamental flaw in my approach [...] ?

    Yes.

    1. You take the size of panel1 to calculate the size of the image. Later, you let this draw to the image, but this is the form, not the panel.

    2. What makes you think that SystemInformation.WorkingArea is related to the window you want to print?

    3. You should take a bit more care of disposable objects.

    [...] is there a way to reformat the text prior to printing so that it comes out crisp?

    There's not a general way which would allow you to scale all other controls as well.

    However, instead of blurry text, you can get crisp pixelated text by scaling the bitmap up by a certain factor using the NearestNeighbor mechanism.

    Here's the difference in a PDF generated without scaling (left) and a factor of 3 scaling (right) at the same zoom level in Acrobat Reader (click to enlarge):

    Image in result.

    Here's the scaling code, also without fixing any disposable issues:

            this.DrawToBitmap(img, bounds);
            Point p = new Point(100, 100);
            img = ResizeBitmap(img, 3);
            e.Graphics.DrawImage(img, p);
        }
    
        private static Bitmap ResizeBitmap(Bitmap source, int factor)
        {
            Bitmap result = new Bitmap(source.Width*factor, source.Height*factor);
            result.SetResolution(source.HorizontalResolution*factor, source.VerticalResolution*factor);
            using (Graphics g = Graphics.FromImage(result))
            {
                g.InterpolationMode = InterpolationMode.NearestNeighbor;
                g.DrawImage(source, 0, 0, source.Width*factor, source.Height*factor);
            }
            return result;
        }