Read multi-page TIFF

TIFF is not really an image but sometimes can be just a container of images.

If it's a container of bmp, jpeg, etc. common formats it can be easily read through Python or C# libraries.

However, occationally it is used by Fax and contains fax encoding images with various types, CCITT T3 T4 etc. which are not supported in Python well.

So here is a piece of .Net C# program for reading that type of TIFF files and convert it to bmp image.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Media.Imaging; //add reference to PresentationCore.dll if needed

using System.IO;

using System.Drawing;  //add reference to System.Drawing.dll if needed

using System.Drawing.Imaging;

namespace ExtractTiff

{

    class Program

    {

        static void Main(string[] args)

        {

            String input_folder = @"C:\attachments";

            String save_folder = @"C:\images";

            new Program().convert_tiff(input_folder, save_folder);

            Console.WriteLine("done");

            Console.Read();

        }

        private void convert_tiff(String input_folder, String save_folder)

        {

            foreach (String dir in Directory.GetDirectories(input_folder))

            {

                convert_tiff(dir, save_folder);

            }

            foreach (String file in Directory.GetFiles(input_folder))

            {

                if (file.ToLower().EndsWith(".tiff") ||file.ToLower().EndsWith(".tif"))

                {

                    try

                    {

                        // Open a Stream and decode a TIFF image.

                        Stream imageStreamSource = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read);

                        TiffBitmapDecoder decoder = new TiffBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);

                        for (int page = 0; page < decoder.Frames.Count; page++)

                        {

                            BitmapSource bitmapSource = decoder.Frames[page];

                            int pixel_w = bitmapSource.PixelWidth;

                            int pixel_h = bitmapSource.PixelHeight;

                            double scale_x_to_y = bitmapSource.DpiX / bitmapSource.DpiY;

                            // Draw the Image.

                            BitmapEncoder encoder = new BmpBitmapEncoder();

                            BitmapFrame frame = BitmapFrame.Create(bitmapSource);

                            encoder.Frames.Add(frame);

                            MemoryStream memory = new MemoryStream();

                            encoder.Save(memory);

                            Bitmap bitmap = new Bitmap(memory);

                            Bitmap scaled = new Bitmap(bitmap, new Size((int)(pixel_w / scale_x_to_y), pixel_h));

                            String file_name = Path.GetFileNameWithoutExtension(file);

                            if (page > 0)

                            {

                                file_name += "_page" + (page + 1);

                            }

                            file_name += ".bmp";

                            Console.WriteLine(file_name);

                            scaled.Save(Path.Combine(save_folder, file_name), ImageFormat.Bmp);

                            scaled.Dispose();

                            bitmap.Dispose();

                            memory.Dispose();

                        }

                    }

                    catch (Exception e)

                    {

                        Console.WriteLine("======= " + file + " | " + e.Message);

                    }

                }

            }

        }

    }

}