none
Increasing Print Quality of Images

    Question

  • Hi.

    I'm writing a program that needs to print off high resolution .tiff images. The problem I'm having is that I can't print the .tiff's in good quality. Due to the large size of the .tiff (8700x7200 for instance) It will not fit on any standard sized sheet. I tried increasing the DPI but that didn't seem to have any effect. The only way i can get the .tiff to fit the page is to scale it down. but then the image has horrendous quality. (I scale it down to fit on a 11x17, but that only has an indicated resolution of 1100x1700). I tried changing the resolutions ettings on the printer, tried manually and programatically setting the printer quality/resolution but to no success. Basically I want to be able to fit more pixels of the .tiff onto the 11x17 page so I don't have to scale as much. I thought increasing the print dpi would increase the amount of pixels on an 11x17 inches, but it had no effect I could see. Maybe I'm doing something wrong. Any help would be greatly appreciated. thanks.

    The code below is what I'm attempting to do right now when pd.Print() is invoked.

    private void pd_PrintPage(object sender, PrintPageEventArgs ev)
            {
                float x = ev.MarginBounds.Left;
                float y = ev.MarginBounds.Top;
                try
                {
                    //ResizeImage(@"H:\21RR-G0K-30140-0220-0002.tiff", @"H:\21RR-G0K-30140-0220-0002-new.tiff", 500, 900, false);
                    Image tempImage = Image.FromFile(@"H:\21RR-G0K-30140-0220-0002.tiff");
                    Bitmap bMap = new Bitmap(tempImage);
                    bMap.SetResolution(1200, 1200);
                    string l = "";
                    tempImage = bMap;
                    /*if (tempImage.Width > tempImage.Height)  //if poster is longer then it is tall, rotate the image. Done to match standard printing aspect ratios
                    {
                        Bitmap tempBitmap = new Bitmap(tempImage); //Need to convert to Bitmap type to do rotation
                        RotateBicubic rotationFilter = new RotateBicubic(90, true);
                        tempImage = rotationFilter.Apply(tempBitmap);
                    }*/
                    float ImageAspectRatio = (float)tempImage.Height / (float)tempImage.Width;
                    float PageSizeAspectRatio = (float)_pSize.Height / (float)_pSize.Width;
                    if (ImageAspectRatio < 1 && PageSizeAspectRatio > 1) //Need to rotate Image. Can't attempt to rotate tempImage due to size. Scale then rotate.
                    {
                        double x_scale = (double)_pSize.Width / (double)tempImage.Height;
                        double y_scale = (double)_pSize.Height / (double)tempImage.Width;
                        int percent = 0;
                        if (y_scale < x_scale)
                        {
                            percent = Convert.ToInt32(y_scale * 100);
                        }
                        else
                        {
                            percent = Convert.ToInt32(x_scale * 100);
                        }
                        Image myImage = ImageManipulation.ScaleByPercent(tempImage, percent);
                        Bitmap tempMap = new Bitmap(myImage);
                        tempMap.SetResolution(1200, 1200);
                        RotateBicubic rotateBC = new RotateBicubic(90);
                        Image finalImage = rotateBC.Apply(tempMap);
                        ev.Graphics.DrawImage(finalImage, 0, 0);
                    }
                    else if (ImageAspectRatio >= 1 && PageSizeAspectRatio >= 1) //No Need for rotation 
                    {
                        double x_scale = (double)_pSize.Width / (double)tempImage.Width;
                        double y_scale = (double)_pSize.Height / (double)tempImage.Height;
                        int percent = 0;
                        if (y_scale < x_scale)
                        {
                            percent = Convert.ToInt32(y_scale * 100);
                        }
                        else
                        {
                            percent = Convert.ToInt32(x_scale * 100);
                        }
    
                        Image myImage = ImageManipulation.ScaleByPercent(tempImage, percent);
                        ev.Graphics.DrawImage(myImage, 0, 0);
    
                    }
                    
                    else
                    {
    
                    }              
                }
                catch(Exception ex)
                {
                    string breakpoint = "pause";
                }
            }
    • Edited by Gary Oak Friday, July 03, 2009 2:12 PM mistakes
    Friday, July 03, 2009 1:59 PM

Answers

  • Forget the DPI.  Load the Image into a bitmap and draw it onto your paper using the graphics supplied in the print page event.  You're overthinking it.
    • Marked as answer by Harry Zhu Thursday, July 09, 2009 4:00 AM
    Friday, July 03, 2009 6:53 PM
  • Try this code:

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.Drawing.Printing;
    namespace WindowsFormsApplication1
    {
      public partial class Form1 : Form
      {
        public Form1()
        {
          InitializeComponent();
        }
        private Bitmap PrintBmp;
        private void button1_Click(object sender, EventArgs e)
        {
    	    PrintPreviewDialog PPD = new PrintPreviewDialog();
    	    PrintDocument PD = new PrintDocument();
    	    OpenFileDialog OFD = new OpenFileDialog();
    	    OFD.Title = "Select an image file for printing";
    	    OFD.ShowDialog();
    	    PrintBmp = new Bitmap(OFD.FileName);
    	    PD.DefaultPageSettings.Margins = new Margins(50, 50, 50, 50);
    	    PD.OriginAtMargins = true;
    	    PPD.Document = PD;
    	    if (PrintBmp.Width > PrintBmp.Height)
    	    {
    		    PD.DefaultPageSettings.Landscape = true;
    	    }
    	    PD.PrintPage += PD_PrintPage;
    	    PPD.ShowDialog();
        }
        public void PD_PrintPage(object sender, PrintPageEventArgs e)
        {
    	    double WidthRatio = e.MarginBounds.Width / (double)PrintBmp.Width;
    	    double HeightRatio = e.MarginBounds.Height / (double)PrintBmp.Height;
    	    if (WidthRatio > HeightRatio)
    	    {
    	      e.Graphics.DrawImage(PrintBmp, 0, 0, Convert.ToInt32(HeightRatio * e.MarginBounds.Width), e.MarginBounds.Height);
    	    }
    	    else
    	    {
    	      e.Graphics.DrawImage(PrintBmp, 0, 0, e.MarginBounds.Width, Convert.ToInt32(WidthRatio * e.MarginBounds.Height));
    	    }
        }
      }
    }
    

     

    You can play with the InterpolationMode, SmoothingMode and CompositingQuality of e.Graphics.

    • Marked as answer by Harry Zhu Thursday, July 09, 2009 4:00 AM
    Friday, July 03, 2009 8:03 PM

All replies

  • I don't have much experience with printing in C# but DPI basically = Pixels Per Inch, so increasing the DPI should work. Unless of course your printer can't handle it.
    Friday, July 03, 2009 3:02 PM
  • yea, that's why i figured increasing the dpi would allow me to fit more pixels onto the sheet. But it didn't change the size of the reported printing sheet (1100x1700) at all
    • Edited by Gary Oak Friday, July 03, 2009 6:48 PM
    Friday, July 03, 2009 6:47 PM
  • Forget the DPI.  Load the Image into a bitmap and draw it onto your paper using the graphics supplied in the print page event.  You're overthinking it.
    • Marked as answer by Harry Zhu Thursday, July 09, 2009 4:00 AM
    Friday, July 03, 2009 6:53 PM
  • wow you're right... I was way overthinking it, that works using rctangles to define areas, then this command. Haha thanks for that. 

    ev.Graphics.DrawImage(tempImage, destRect, srcRect,

    GraphicsUnit.Pixel);

    Friday, July 03, 2009 7:35 PM
  • Try this code:

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.Drawing.Printing;
    namespace WindowsFormsApplication1
    {
      public partial class Form1 : Form
      {
        public Form1()
        {
          InitializeComponent();
        }
        private Bitmap PrintBmp;
        private void button1_Click(object sender, EventArgs e)
        {
    	    PrintPreviewDialog PPD = new PrintPreviewDialog();
    	    PrintDocument PD = new PrintDocument();
    	    OpenFileDialog OFD = new OpenFileDialog();
    	    OFD.Title = "Select an image file for printing";
    	    OFD.ShowDialog();
    	    PrintBmp = new Bitmap(OFD.FileName);
    	    PD.DefaultPageSettings.Margins = new Margins(50, 50, 50, 50);
    	    PD.OriginAtMargins = true;
    	    PPD.Document = PD;
    	    if (PrintBmp.Width > PrintBmp.Height)
    	    {
    		    PD.DefaultPageSettings.Landscape = true;
    	    }
    	    PD.PrintPage += PD_PrintPage;
    	    PPD.ShowDialog();
        }
        public void PD_PrintPage(object sender, PrintPageEventArgs e)
        {
    	    double WidthRatio = e.MarginBounds.Width / (double)PrintBmp.Width;
    	    double HeightRatio = e.MarginBounds.Height / (double)PrintBmp.Height;
    	    if (WidthRatio > HeightRatio)
    	    {
    	      e.Graphics.DrawImage(PrintBmp, 0, 0, Convert.ToInt32(HeightRatio * e.MarginBounds.Width), e.MarginBounds.Height);
    	    }
    	    else
    	    {
    	      e.Graphics.DrawImage(PrintBmp, 0, 0, e.MarginBounds.Width, Convert.ToInt32(WidthRatio * e.MarginBounds.Height));
    	    }
        }
      }
    }
    

     

    You can play with the InterpolationMode, SmoothingMode and CompositingQuality of e.Graphics.

    • Marked as answer by Harry Zhu Thursday, July 09, 2009 4:00 AM
    Friday, July 03, 2009 8:03 PM