Printing a multi page tiff

Started by dadinos, February 07, 2017, 10:05:40 PM

Previous topic - Next topic

dadinos

I using the cyotek .net dll for a c# program that can view multipage tif images.
The view is no problem with the provided sample with the Newtonscradle multi page tif.

But I cannot get it to work with the printdocument control.

This is my code for now:

        private void printToolStripMenuItem_Click(object sender, EventArgs e)
        {
            printPreviewDialog1.ShowDialog();
        }

        private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {

            imageBox.Image.SelectActiveFrame(FrameDimension.Page, _currentPage);

            e.Graphics.DrawImage(imageBox.Image, 0,0);
            _currentPage += 1;

            if (_pageCount != _currentPage) e.HasMorePages = true;
            else e.HasMorePages = false;

        }

It prints the correct amount of pages but it is repeating the same first page in all page views.

Is there a way to solve this. How can I address a page from the multi page tif to the printdocument?

Any remrk or tip is welcome!

Thanks in advance

Richard Moss

#1
Hello,

Welcome to the forums, and thanks for the question. I don't often add printing support to my applications so I'm a little rusty on the built in controls. I opened up the sample project and updated it to support print and print preview. I had a PrintDocument control which was then bound to a PrintDialog and PrintPreviewDialog controls.

As you mentioned, the print preview control didn't seem to work correctly and displayed the first frame of the image always.

However, I tested printing the document to a PDF file. When I checked the PDF, it had "printed" correctly - each frame was represented.

I think therefore, that there's actually nothing at all wrong with your code. To me, it suggests a bug in the PrintPreviewDialog control or our understanding of how the preview stuff works - but I don't know for sure.

I did another test where I created a new Bitmap based on the source image, then drew that - that approach worked fine for both printing and previewing, although it's a weird solution.

Here's my final code if it helps

    private void printDocument_BeginPrint(object sender, PrintEventArgs e)
    {
      _currentPage = 0;
    }

    private void printDocument_EndPrint(object sender, PrintEventArgs e)
    {
      _currentPage = 0;
    }

    private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
    {
      _openImage.SelectActiveFrame(FrameDimension.Page, _currentPage++);

      using (Bitmap copy = new Bitmap(_openImage))
      {
        e.Graphics.DrawImage(copy, 0, 0);
      }

      e.HasMorePages = _currentPage < _pageCount;
    }


Regards;
Richard Moss

Edit: I added BeginPrint and EndPrint handlers to reset the current page otherwise you can get a crash.
Read "Before You Post" before posting. Do not send me private messages. Do not expect instant replies.

All responses are hand crafted. No AI involved. Possibly no I either.

dadinos

Hi Richard,

Thanks for your workaround. I builded your logic in and I have now the different pages displayed in the printpreview dialog. But the scaling is completely off. I have only a small top - left corner of each page.

Maybe there is still something to add in the copy bitmap based on the original page size and resolution?


Kind regards,

Aren

Richard Moss

Hello,

The DrawImage method lets you specify a size, so in the snippet below I calculate a size that will fill as much of the page with the image, whilst keeping the proportions intact.

Note that this example assumes the printer information is in pixels, it probably won't work properly if they aren't. As I said, I don't do much printer work so I'm not sure if these values are always in pixels.

You can always adjust the sample code below to center the image on the page or whatever you need to do with it.

    private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
    {
      int width;
      int height;
      float scaleWidth;
      float scaleHeight;
      float scale;
      Rectangle margin;

      margin = e.MarginBounds;

      width = _openImage.Width;
      height = _openImage.Height;
      scaleWidth = margin.Width / (float)width;
      scaleHeight = margin.Height / (float)height;
      scale = Math.Min(scaleHeight, scaleWidth);

      _openImage.SelectActiveFrame(FrameDimension.Page, _currentPage++);

      using (Bitmap copy = new Bitmap(_openImage))
      {
        e.Graphics.DrawImage(copy, new Rectangle(margin.Left, margin.Y, (int)(width * scale), (int)(height * scale)), new Rectangle(0, 0, width, height), GraphicsUnit.Pixel);
      }

      e.HasMorePages = _currentPage < _pageCount;
    }


Regards;
Richard Moss
Read "Before You Post" before posting. Do not send me private messages. Do not expect instant replies.

All responses are hand crafted. No AI involved. Possibly no I either.

dadinos

This is great and very usefull.
Thank you Richard!