none
Print multi-page TIFF RRS feed

  • 질문

  • Hi,
    I have a Windows Form that should print a multi-page TIFF.

    My code:


    private System.Drawing.Printing.PrintDocument _PrintDocument;

    private System.Windows.Forms.PrintDialog _PrintDialog;

     

    public void Print()

            {

                _PrintDocument.PrintPage += new PrintPageEventHandler(_PrintDocument_PrintPage);

               

                if (_PrintDialog.ShowDialog() == DialogResult.OK)

                {

                   TiffToPrint = Image.FromFile(MyFilePath);

                    Guid objGuid = TiffToPrint.FrameDimensionsList[0];

                    FrameDimension objDimension = new FrameDimension(objGuid);

                   

                    // Cycle through each frame of the TIFF

                    for (int iFrame = 0; iFrame < TiffToPrint.GetFrameCount(objDimension); iFrame++)

                    {

                        TiffToPrint.SelectActiveFrame(objDimension, iFrame);

                     

                        // Call the PrintPage event 

      _PrintDocument.Print();   

                    }

                }

            }


    void _PrintDocument_PrintPage(object sender, PrintPageEventArgs e)

            {

                e.Graphics.DrawImage(TiffToPrint, e.MarginBounds);

    }


    In this way I'm able to print each page of the TIFF, but the Print dialog doesn't know how nuch pages I have (it is called before the cycle).

    Example, if I select "Current Page", all pages are print.

    I think a different work is sent for each page,  in fact, if I have 4 pages, I see 4 different windows telling "printing page 1 of document"


    Is there a way to "bufferize" the pages and print them togheter ?

    2008년 8월 4일 월요일 오후 1:00

답변

  • Yes, that code can't work.  When you set e.MorePages to true, your PrintPage event will run *again*, allowing you to print the next page.  Draw one image per PrintPage invocation.  You "iFrame" variable must be a class member, not a local variable, so you'll know how far you've progressed.  Set it to zero in the BeginPrint event.

    Hans Passant.
    • 답변으로 표시됨 Nazza 2008년 8월 4일 월요일 오후 3:03
    2008년 8월 4일 월요일 오후 2:32
  • Try something like this: 

      public void Print()
             {
                 _PrintDocument = new PrintDocument();
                 _PrintDocument.PrintPage += new PrintPageEventHandler(_PrintDocument_PrintPage);
              
                 _PrintDocument.Print();
             }



     void _PrintDocument_PrintPage(object sender, PrintPageEventArgs e)
            {
                    OriginalImage.SelectActiveFrame(objDimension, _iFrame);

                    RectangleF rSourceRectangle = new RectangleF(0, 0, OriginalImage..PhysicalDimension.Width, OriginalImage..PhysicalDimension.Height);
                    RectangleF rDestinationRectangle = new RectangleF();
                   
                    ////////////////////////////////////////////////////////////////////////////////////////////////
                    // rDestinationRectangle must be sized depending on your media type
                    // Example:
                    rDestinationRectangle.Width = 1700
                    rDestinationRectangle.Height = 1200
                    rDestinationRectangle.X = 0;
                    rDestinationRectangle.Y = 0;
                    ////////////////////////////////////////////////////////////////////////////////////////////////

                    ////////////////////////////////////////////////////////////////////////////////////////////////
                    // If the Source Rectangle is larger than Destination Rectangle, you have to resize it
                    // Try beginning with an image smaller than destination sheet
                    ////////////////////////////////////////////////////////////////////////////////////////////////

                    e.Graphics.DrawImage(OriginalImage., rDestinationRectangle, rSourceRectangle, GraphicsUnit.Pixel);

                    if (_iFrame == _iLastFrameToPrint)
                    {
                        e.HasMorePages = false;
                    }
                    else
                    {
                        e.HasMorePages = true;
                        _iFrame++;
                    }
             }

    _iFrame is the current page
    _iLastFrameToPrint is the last page to print
    • 답변으로 제안됨 Mreder 2008년 12월 8일 월요일 오후 1:08
    • 답변으로 표시됨 Nazza 2009년 11월 3일 화요일 오후 3:09
    2008년 12월 4일 목요일 오전 11:04

모든 응답

  • Yeah, you don't want to do it this way.  Use the BeginPrint event to reset the page counter.  Use the PrintPage event to step through the pages, setting e.MorePages to true if you're not done yet.  You'll now only need to call PrintDocument.Print() once.  Then add the code you need to control the page counter from the PrintDialog.
    Hans Passant.
    2008년 8월 4일 월요일 오후 1:33
  • In fact, this is what I did.
    I changed to the new code, because calling the old code:

    void _PrintDocument_PrintPage(object sender, PrintPageEventArgs e)

             {

                 TiffToPrint = Image.FromFile(MyFilePath);

                 Guid objGuid = TiffToPrint .FrameDimensionsList[0];

                 FrameDimension objDimension = new FrameDimension(objGuid);

     

                 for (int iFrame = 0; iFrame < TiffToPrint .GetFrameCount(objDimension); iFrame++)

                 {

                     _iPrintedPages++;

     

                     TiffToPrint.SelectActiveFrame(objDimension, iFrame);

     

                     e.Graphics.DrawImage(TiffToPrint , HERE ? ? ?);

                 }


                 if (_iPrintedPages < _iTotPages)

                 {

                     e.HasMorePages = true;

                 }

                 else

                 {

                     e.HasMorePages = false;

                 }


             }


    I'm not able to set the second parameter (as a Point or a Rectangle) to a new page calling DrawImage method..............and all frames will be printed in the same location (so I can see only the last page printed).

    How can I set that parameter ?

    2008년 8월 4일 월요일 오후 2:22
  • Yes, that code can't work.  When you set e.MorePages to true, your PrintPage event will run *again*, allowing you to print the next page.  Draw one image per PrintPage invocation.  You "iFrame" variable must be a class member, not a local variable, so you'll know how far you've progressed.  Set it to zero in the BeginPrint event.

    Hans Passant.
    • 답변으로 표시됨 Nazza 2008년 8월 4일 월요일 오후 3:03
    2008년 8월 4일 월요일 오후 2:32
  • Hi Hans, you are right !
    I did as you said and it finally works !

    Thank you very much !
    2008년 8월 4일 월요일 오후 3:02
  • I'm somewhat new to C# and having this same issue.  I have about 25-30 tiff pages that I would like to print as one job instead of each page equal to one print job.  Can you share the code that worked for you? 

    Thank you in advance.
    2008년 12월 3일 수요일 오후 8:45
  • Try something like this: 

      public void Print()
             {
                 _PrintDocument = new PrintDocument();
                 _PrintDocument.PrintPage += new PrintPageEventHandler(_PrintDocument_PrintPage);
              
                 _PrintDocument.Print();
             }



     void _PrintDocument_PrintPage(object sender, PrintPageEventArgs e)
            {
                    OriginalImage.SelectActiveFrame(objDimension, _iFrame);

                    RectangleF rSourceRectangle = new RectangleF(0, 0, OriginalImage..PhysicalDimension.Width, OriginalImage..PhysicalDimension.Height);
                    RectangleF rDestinationRectangle = new RectangleF();
                   
                    ////////////////////////////////////////////////////////////////////////////////////////////////
                    // rDestinationRectangle must be sized depending on your media type
                    // Example:
                    rDestinationRectangle.Width = 1700
                    rDestinationRectangle.Height = 1200
                    rDestinationRectangle.X = 0;
                    rDestinationRectangle.Y = 0;
                    ////////////////////////////////////////////////////////////////////////////////////////////////

                    ////////////////////////////////////////////////////////////////////////////////////////////////
                    // If the Source Rectangle is larger than Destination Rectangle, you have to resize it
                    // Try beginning with an image smaller than destination sheet
                    ////////////////////////////////////////////////////////////////////////////////////////////////

                    e.Graphics.DrawImage(OriginalImage., rDestinationRectangle, rSourceRectangle, GraphicsUnit.Pixel);

                    if (_iFrame == _iLastFrameToPrint)
                    {
                        e.HasMorePages = false;
                    }
                    else
                    {
                        e.HasMorePages = true;
                        _iFrame++;
                    }
             }

    _iFrame is the current page
    _iLastFrameToPrint is the last page to print
    • 답변으로 제안됨 Mreder 2008년 12월 8일 월요일 오후 1:08
    • 답변으로 표시됨 Nazza 2009년 11월 3일 화요일 오후 3:09
    2008년 12월 4일 목요일 오전 11:04
  • Nazza - 
     
    After a little tweaking in my code that worked for me.   THANK YOU SO MUCH!!!
    2008년 12월 8일 월요일 오후 1:08
  • Have same issue, can you pls help what changes fixed.
    2020년 8월 14일 금요일 오후 2:05