locked
Print multi-page TIFF RRS feed

  • Pergunta

  • 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 ?

    segunda-feira, 4 de agosto de 2008 13:00

Respostas

  • 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.
    • Marcado como Resposta Nazza segunda-feira, 4 de agosto de 2008 15:03
    segunda-feira, 4 de agosto de 2008 14: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
    • Sugerido como Resposta Mreder segunda-feira, 8 de dezembro de 2008 13:08
    • Marcado como Resposta Nazza terça-feira, 3 de novembro de 2009 15:09
    quinta-feira, 4 de dezembro de 2008 11:04

Todas as Respostas

  • 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.
    segunda-feira, 4 de agosto de 2008 13: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 ?

    segunda-feira, 4 de agosto de 2008 14: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.
    • Marcado como Resposta Nazza segunda-feira, 4 de agosto de 2008 15:03
    segunda-feira, 4 de agosto de 2008 14:32
  • Hi Hans, you are right !
    I did as you said and it finally works !

    Thank you very much !
    segunda-feira, 4 de agosto de 2008 15: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.
    quarta-feira, 3 de dezembro de 2008 20: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
    • Sugerido como Resposta Mreder segunda-feira, 8 de dezembro de 2008 13:08
    • Marcado como Resposta Nazza terça-feira, 3 de novembro de 2009 15:09
    quinta-feira, 4 de dezembro de 2008 11:04
  • Nazza - 
     
    After a little tweaking in my code that worked for me.   THANK YOU SO MUCH!!!
    segunda-feira, 8 de dezembro de 2008 13:08
  • Have same issue, can you pls help what changes fixed.
    sexta-feira, 14 de agosto de 2020 14:05