Fast loading / reading TIFF files in C #

I am writing a C # application that processes TIFF images (basically displays files, reorders pages, deletes pages, splits multi-page images, merges individual images into one multi-page image, etc.).

Most of the images we deal with are smaller (both in file size and page numbers), but there are odd large ones.

When displaying an image, we need to split any multi-page TIFF files into a list in order for the thumbnails to be displayed in the ListView. The problem we are facing is that it takes too long for large files to split. For example. I just tested a 304 page image (10MB total) and paginated all the pages into a list, taking 137.145ms (137.14 seconds or 2m 17s) which is too slow.

The code I use is:

private void GetAllPages(string file)
{
    System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
    watch.Start();
    List<Image> images = new List<Image>();
    Bitmap bitmap = (Bitmap)Image.FromFile(file);
    int count = bitmap.GetFrameCount(FrameDimension.Page);
    for (int idx = 0; idx < count; idx++)
    {
        // save each frame to a bytestream
        bitmap.SelectActiveFrame(FrameDimension.Page, idx);
        System.IO.MemoryStream byteStream = new System.IO.MemoryStream();
        bitmap.Save(byteStream, ImageFormat.Tiff);

        // and then create a new Image from it
        images.Add(Image.FromStream(byteStream));
    }
    watch.Stop();
    MessageBox.Show(images.Count.ToString() + "\nTime taken: " + watch.ElapsedMilliseconds.ToString());
}

      

Any hints or pointers on what I can do or what should I look out for to speed up this process? I KNOW that this can be done much faster - I just don't know how.

Thank!

+3


source to share


1 answer


If I use a class TiffBitmapDecoder

from PresentationCore.dll (WPF) and then use it to instantiate Bitmap

, I get much faster frame loading (10s versus 70s for 150MB TIFF with 360 frames).



 List<Image> images = new List<Image>();
 Stream imageStreamSource = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read);
 TiffBitmapDecoder decoder = new TiffBitmapDecoder(imageStreamSource, BitmapCreateOptions.None, BitmapCacheOption.Default);
 foreach (BitmapSource bitmapSource in decoder.Frames)
 {
     Bitmap bmp = new Bitmap(bitmapSource.PixelWidth, bitmapSource.PixelHeight, PixelFormat.Format32bppPArgb);
     BitmapData data = bmp.LockBits(new Rectangle(System.Drawing.Point.Empty, bmp.Size), ImageLockMode.WriteOnly, PixelFormat.Format32bppPArgb);
     bitmapSource.CopyPixels(Int32Rect.Empty,  data.Scan0,  data.Height * data.Stride, data.Stride);
     bmp.UnlockBits(data);
     images.Add(bmp);
 }

      

+1


source







All Articles