0

I want to print an image on Windows Forms, but I want to print the image as big as possible on the page without breaking its aspect ratio. Like when I want to print a simple square to A4 paper it becomes rectangle with this script:

private void Page(object sender, PrintPageEventArgs e)
{
    Bitmap i = image;
    if(e.PageBounds.Height > e.PageBounds.Width)
    {
        if (i.Width > i.Height)
            i.RotateFlip(RotateFlipType.Rotate90FlipNone);
    }
    else if(e.PageBounds.Width > e.PageBounds.Height)
    {
        if (i.Height > i.Width)
            i.RotateFlip(RotateFlipType.Rotate90FlipNone);
    }
    e.Graphics.DrawImage(i, new Rectangle(0, 0, e.PageBounds.Width, e.PageBounds.Height));
    i.Dispose();
}

Original: 500x500 square

What I got (as pdf): A rectangle on the A4 paper

Another example:

Original:Original image(313x234)

Print:Print image

I don't want to break the aspect ratio of the image

Mr. Deniz
  • 11
  • 1
  • 2
    I take it you mean the aspect ratio, not the resolution or "solution"? – NetMage Sep 17 '18 at 16:44
  • @NetMage Thanks for the information! I edited my post by replacing (re)solution with aspect ratio. Thanks again for your help by making my post cleaner – Mr. Deniz Sep 17 '18 at 16:55
  • 1
    And now if you search for resize while preserving aspect ratio, you should find [this answer](https://stackoverflow.com/a/2001692/2557128) – NetMage Sep 17 '18 at 16:57

1 Answers1

1

Try this:

private void Page(object sender, PrintPageEventArgs e)
{
    using (Bitmap i = image)  //are you *really sure* you want to dispose this after printing? 
    {
        var pageRatio = e.PageBounds.Width / (double)e.PageBounds.Height;
        var imageRatio = i.Width / (double)i.Height;

        //do we need to rotate?
        if ( (pageRatio < 1 && imageRatio > 1) || (pageRatio < 1 && imageRatio > 1))
        {
            i.RotateFlip(RotateFlipType.Rotate90FlipNone);
            imageRatio = i.Width / (double)i.Height; //ratio will have changed after rotation
        }         

        var scale = 1.0D;
        //do we need to scale?
        if (pageRatio > imageRatio)
        { //the page is wider than the image, so scale to the height
             scale = e.PageBounds.Height / (double)i.Height;
        }
        else if (pageRatio < imageRatio)
        { //the page is narrower than the image, so scale to width
            scale = e.PageBounds.Width / (double)i.Width;
        }

        var W = (int)(scale * i.Width);
        var H = (int)(scale * i.Height);

        e.Graphics.DrawImage(i, new Rectangle(0, 0, W, H));
    }
}

This will always draw from the top left corner. If you want it centered, you need to make additional adjustments:

private void Page(object sender, PrintPageEventArgs e)
{
    using (Bitmap i = image)  //are you *really sure* you want to dispose this after printing? 
    {
        var pageRatio = e.PageBounds.Width / (double)e.PageBounds.Height;
        var imageRatio = i.Width / (double)i.Height;

        //do we need to rotate?
        if ( (pageRatio < 1 && imageRatio > 1) || (pageRatio < 1 && imageRatio > 1))
        {
            i.RotateFlip(RotateFlipType.Rotate90FlipNone);
            imageRatio = i.Width / (double)i.Height; //ratio will have changed after rotation
        }         

        int T = 0, L = 0; //top, left
        var scale = 1.0D;
        int W = i.Width, H = i.Height;

        //do we need to scale?
        if (pageRatio > imageRatio)
        { //the page is wider than the image, so scale to the height
             scale = e.PageBounds.Height / (double)i.Height;
             W = (int)(scale * i.Width); 
             H = (int)(scale * i.Height);
             L = (e.PageBounds.Width - W)/2;
        }
        else if (pageRatio < imageRatio)
        { //the page is narrower than the image, so scale to width
            scale = e.PageBounds.Width / (double)i.Width;
            W = (int)(scale * i.Width); 
            H = (int)(scale * i.Height);
            T = (e.PageBounds.Height - H)/2;
        }

        e.Graphics.DrawImage(i, new Rectangle(L, T, W+L, H+T));
    }
}

The important thing is both the width and height are adjusted to the same scale... that is, multiplied by the same number.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794