Click here to Skip to main content
15,893,644 members
Articles / Desktop Programming / Windows Forms
Article

Multipage TIF Viewer

Rate me:
Please Sign up or sign in to vote.
4.79/5 (18 votes)
26 Nov 2008CPOL2 min read 141.2K   15.3K   46   25
A simple and useful viewer of multipage TIF/TIFF images

Introduction

Hi. This is my first article, so it's not so well written, but I hope you'll get the point.

I'll try to show you how to create a simple multipage TIFF, TIF document. It's a sample, so you can edit it by your own wishes and it's functionality can be upgraded endlessly. To give this code a tryout - download the example application and use the example TIFF that's in the folder (it's a US Patent *.tiff file).

So, let's get to the point. You have multipage TIFFs and you can't afford expensive, but useful libraries. Well, this might be just the thing for you. In this sample, you'll meet a few lines of code from GUI+ on how to open and navigate through pages of a multipage TIFF document. And I should not forget to add - the sample includes opening the file, showing it in a picturebox and it has two buttons for navigation (next page, previous page) - but this can be changed on a textbox for realtime change.

Image 1

Using the Code

The code is quite simple to understand. You use System.Drawing and two Image objects. The code in the sample is well commented so I think you'll understand what's meant by what.

Here is the most important part of the code which operates the whole thing. Everything else is in the sample.

C#
// going to the selected page
myImg.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page,int); 

// setting the new page as an image	
myBmp = new Bitmap(myImg,pictureBox1.Width,pictureBox1.Height); 	

Points of Interest

You can check the page navigation buttons, on how they change the current page integer. The loaded document starts with 0. The GUI+ is great.

Conclusion

As this is my first article, I think I shouldn't be judged that much on the spelling, the explanations and the help I'll give as feedback to your questions/remarks/..., which are more than welcome. And please, if you have created any great applications, based on this article - post them here and let us have a look. The last thing I'd like to add is - I'm more a rookie with C# than a senior or an expert which means I've got a lot to learn. I hope you enjoyed this sample and this article.

History

Nothing new, but I think a lot of things should be added in the future... but like I said - it's just a sample to get started.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Slovenia Slovenia
Work in progress...

Comments and Discussions

 
QuestionVery Useful Pin
Suganya Soundararajan13-Sep-16 6:09
Suganya Soundararajan13-Sep-16 6:09 
QuestionCan't read a tif file generated by Win2008 server 64bit Pin
gaowangzhong11-Mar-15 17:43
gaowangzhong11-Mar-15 17:43 
QuestionReg the Multipage TIFF Viewer Pin
Member 1133601726-Dec-14 0:44
Member 1133601726-Dec-14 0:44 
GeneralMy vote of 4 Pin
cws2_na22-Feb-13 2:56
cws2_na22-Feb-13 2:56 
GeneralMy vote of 5 Pin
aalhanane7-Nov-12 5:47
aalhanane7-Nov-12 5:47 
SuggestionAn Alternative Pin
DadajiIn30-May-12 18:00
DadajiIn30-May-12 18:00 
GeneralRe: An Alternative Pin
Matjaz-xyz7-Jan-14 3:49
Matjaz-xyz7-Jan-14 3:49 
GeneralMy vote of 5 Pin
jonathan_i_smith6-Mar-12 23:37
jonathan_i_smith6-Mar-12 23:37 
QuestionThanks Pin
Johnson.Sebastian/35377198-Oct-11 0:47
Johnson.Sebastian/35377198-Oct-11 0:47 
Questionabout code redistribution Pin
edinson Zuñiga Lourido9-May-11 5:24
edinson Zuñiga Lourido9-May-11 5:24 
AnswerRe: about code redistribution Pin
Matjaz-xyz9-May-11 7:45
Matjaz-xyz9-May-11 7:45 
GeneralKeep up the good work Pin
Nueman9-Feb-11 16:50
Nueman9-Feb-11 16:50 
GeneralMy vote of 5 Pin
Member 406920523-Jul-10 5:30
Member 406920523-Jul-10 5:30 
GeneralI like this. This is what i'm looking for. Thanks Pin
DAT HAN23-Apr-10 9:26
DAT HAN23-Apr-10 9:26 
GeneralHere's some optimized code for ya.... Pin
MacSpudster6-Jul-09 12:01
professionalMacSpudster6-Jul-09 12:01 
I've changed your original code to use a fileStream instead of opening the file each time.

As well, you were using Convert.Int() where intVarName.ToString() works fine.

Finally, I ditched the "fileOpen" variable and included "UpdateButtonStatus()" to manage the button(s) being enabled/disabled depending upon the number of pages available, and page being viewed.

With a fileStream, you can manage the fileStream and open it when needed, and close it when not needed. The fileStream remains open until closed for the next file.

We open the fileStream with System.IO.FileAccess.Read and also with System.IO.FileShare.Read. Both of these prevents an exception if other processes try to access and/or use the file. Specifically, merely opening file without using a fileStream can and does lock the file, and opening file #2, #3, etc, doesn't close the previously opened file(s).

To ensure effective code use, map the FormClosed function to the Form's FormClosed.

 Image currentImage = null;
 private int intCurrPage = 1, intPages = 1; // defining the current page (its some sort of a counter)
 System.IO.FileStream ImageFS = null;

 private void frmMain_Load(object sender, EventArgs e)
 {
   this.CloseImageFS();
   this.UpdateButtonStatus();
 }


 private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
 {
   this.CloseImageFS();
 }



public void RefreshImage()
 {
   Image myBmp; // a new occurance of Image for viewing

   intPages = currentImage.GetFrameCount(System.Drawing.Imaging.FrameDimension.Page); // getting the frameCount of the tiff
   // frameCount is Base.1, yet frames are accessed by Base.0, so we must correct the number of pages to FrameCount - 1
   lblNumPages.Text = intPages.ToString(); // showing the number of pages
   lblCurrPage.Text = intCurrPage.ToString() ; // showing the number of page on which we're on

   //frames are accessed by Base.0, so we need to subtract 1 from intCurrPage (Base.1) to reference the correct frame
   currentImage.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, intCurrPage - 1); // going to the selected page

   myBmp = new Bitmap(currentImage, pictureBox1.Width, pictureBox1.Height); // setting the new page as an image
   // Description on Bitmap(SOURCE, X,Y)

   pictureBox1.Image = myBmp; // showing the page in the pictureBox1
   this.UpdateButtonStatus();

 }

  private void UpdateButtonStatus()
  {
    this.btnPageNext.Enabled = this.btnPageNext.Enabled = false;
    if (this.intPages == 1)
    {
       this.btnPagePrev.Enabled = this.btnPageNext.Enabled = false;
       return;
    }
    if (intCurrPage == 1)
    {
      this.btnPagePrev.Enabled = false;
      this.btnPageNext.Enabled = true;
    }

    if (intCurrPage >=2)
    {
      this.btnPagePrev.Enabled = true;
      this.btnPageNext.Enabled = true;
      return;
    }

    if (intCurrPage == intPages)
    {
      this.btnPagePrev.Enabled = true;
      this.btnPageNext.Enabled = false;
      return;
    }
  }

   private void button1_Click(object sender, EventArgs e)
   {
     if (this.intCurrPage < 1) // it stops here if you reached the bottom, the first page of the tiff
       { this.intCurrPage = 1; }
       else
       {
         this.intCurrPage--; // if its not the first page, then go to the previous page
         if (this.intCurrPage == 1)
         {
           this.btnPageNext.Enabled = this.btnPageNext.Enabled = false;
         }
          this.RefreshImage(); // refresh the image on the selected page
       }
   }


   private void button2_Click(object sender, EventArgs e)
   {
       if (this.intCurrPage == intPages) // if you have reached the last page it ends here
         // the "-1" should be there for normalizing the number of pages
       {
         this.intCurrPage = intPages;
       }
       else
       {
         this.intCurrPage++;
         this.RefreshImage();
       }
   }


   private void btnOpen_Click(object sender, EventArgs e)
   {
     if (openFileDialog1.ShowDialog() == DialogResult.OK)
     {
       intCurrPage = 1; // reseting the counter
       lblFile.Text = openFileDialog1.FileName; // showing the file name in the lblFile
       currentImage = this.ImageLoadActual(@lblFile.Text);
       this.RefreshImage(); // refreshing and showing the new file
     }
   }


 private Image ImageLoadActual(string sFilePath)
 {
   Image tImage = null;

   try //try #a
   {
     this.CloseImageFS();

     ImageFS = new System.IO.FileStream(sFilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);
     tImage = Image.FromStream(ImageFS);

   }// try #a
   catch (Exception ex)
   {
     string m = ex.Message;
   }// try #a
   finally
   {
   }// try #a
   return tImage;
 }//ImageLoadActual(string sFilePath)


 private void CloseImageFS()
 {
   if (ImageFS != null)
   {
     ImageFS.Close();
     ImageFS.Dispose();
   }//if (ImageFS != null)
 }//ClearImageFS()


Enjoy.

ASPX ~ Apple Simply Performs eXcellently

GeneralRe: Here's some optimized code for ya.... Pin
Matjaz-xyz6-Jul-09 19:44
Matjaz-xyz6-Jul-09 19:44 
NewsMultipage Tiff Viewer Control ASP.NET Pin
tiffviewer16-Mar-09 6:27
tiffviewer16-Mar-09 6:27 
QuestionHow to use it with SQL image Pin
Almatrodi18-Jan-09 17:56
Almatrodi18-Jan-09 17:56 
AnswerRe: How to use it with SQL image Pin
Matjaz-xyz18-Jan-09 19:37
Matjaz-xyz18-Jan-09 19:37 
GeneralRe: How to use it with SQL image Pin
Almatrodi22-Jan-09 19:35
Almatrodi22-Jan-09 19:35 
GeneralASP.NET Pin
PChott26-Nov-08 1:59
PChott26-Nov-08 1:59 
GeneralRe: ASP.NET Pin
Matjaz-xyz26-Nov-08 3:04
Matjaz-xyz26-Nov-08 3:04 
GeneralRe: ASP.NET Pin
UstesGreenridge23-Jan-09 1:23
UstesGreenridge23-Jan-09 1:23 
GeneralRe: ASP.NET Pin
Matjaz-xyz23-Jan-09 3:24
Matjaz-xyz23-Jan-09 3:24 
GeneralRe: ASP.NET Pin
diepkv8-May-09 20:55
diepkv8-May-09 20:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.