This project has moved. For the latest updates, please go here.

Combining two multi-page TIFF images

Apr 28, 2014 at 5:50 PM
Edited Apr 28, 2014 at 7:11 PM
Hello,

I am trying to get Magick.NET to merge two multi-page tiff files into one multi-page tiff file. I am creating a MagickImageCollection variable for both of the tiff files I want to merge. Then, I create another MagickImageCollection that I will add them to. Unfortunately, I do not know how to put a collection inside of another collection. The Add function does not accept a Collection, and the Read function gets rid of the first one that is read in when I go to read the second in.

If someone could help, I would appreciate it. Thank you

Edit: I can get it to work using an enum to iterate through each page in a tiff, and adding it to a Collection. I do this for both images that I am trying to merge together. It works, but it is super slow. Is there a better way to do this?

Corbin
Apr 28, 2014 at 6:43 PM
Edited Apr 28, 2014 at 7:29 PM
Oh forget it. I just read your post again and I realize that you want to stack two multi-paged image together. Sorry, I have had a long day...

This approach is working for me but I don't know the "multiImage" collection is disposed correctly:
public static void stackImages(string[] multiImagePaths, string resultImagePath)
        {
            using (MagickImageCollection resultImage = new MagickImageCollection())
            {
                MagickImageCollection multiImage;

                foreach (string multiImagePath in multiImagePaths)
                {
                    multiImage = new MagickImageCollection(multiImagePath);
                    
                    foreach (MagickImage imagePage in multiImage)
                    {
                        resultImage.Add(imagePage);
                    }
                }                
                resultImage.Write(resultImagePath);
            }
        }
Apr 28, 2014 at 7:09 PM
No problem at all, I appreciate your reply anyway.
Coordinator
Apr 28, 2014 at 7:21 PM
Edited Apr 28, 2014 at 7:21 PM
Can you post a link to both your images? And what do you consider super slow?
Apr 28, 2014 at 7:52 PM
Edited Apr 28, 2014 at 8:02 PM
I cannot post the images due to them containing confidential information. They are both 2480 by 3475. One file has 5 pages, the other has 40. When I iterate through both files, it runs in about 4 minutes. If I just use the command line to do this merge, it runs in a little over 1 minute.

mchris, thanks for your post. It does work, but it runs at the speed as iterating through the enum the Collection returns.
Coordinator
Apr 28, 2014 at 8:28 PM
Edited Apr 29, 2014 at 12:55 PM
You are probably using the Q16 version of Magick.NET The Q16 version uses HDRI and requires a lot of memory 2480 * 3475 * 16 bytes per pixel = 131MB per page. This is a total of 45 * 131MB = 5.9 GB. When there is not enough memory available Magick.NET will use the hard disk to store the images. And this will make the conversion much slower. If you switch to the Q8 version you will only need 1.5 GB (2480 * 3475 * 4 bytes per pixel).

I will add new methods to the MagickImageCollection class that will make it easier for you to add a set of images.
using (MagickImageCollection images = new MagickImageCollection())
{
  foreach(string fileName in GetFileNames())
  {
     images.AddRange(fileName);
  }
}

// And:

using (MagickImageCollection images = new MagickImageCollection())
{
  foreach(string fileName in GetFileNames())
  {
    using (MagickImageCollection other = new MagickImageCollection(fileName))
    {
      images.RemoveAt(1);
      images.AddRange(other);
  }
}
Coordinator
Apr 28, 2014 at 8:28 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Apr 29, 2014 at 12:02 PM
dlemstra,

Thank you for mentioning the Q8 version. Using this drastically cut down run time (only took 20 seconds with it!). While I appreciate you adding new methods, please do not do it just for me. I am able to do what I need to do using what is currently available.

I do have one more question though. Is there a way to compress a MagickImageCollection before writing it? Currently, I am writing the collection using Magick.NET, and then using a Process to open the command line and send "convert outputfile.tiff -compress Group4 outputfile.tiff" as an argument. Just wondered if there is a way to do this in Magick.NET.

Thank you again for all your help.

Corbin
Coordinator
Apr 29, 2014 at 1:03 PM
You don't need to use the convert.exe program anymore. Almost all the functionality from ImageMagick is available in Magick.NET. And if it is not please tell me so I can try to add it.

You can set the compression method like this:
using (MagickImageCollection images = new MagickImageCollection())
{
  images.Read("first.tiff");
  images.AddRange("second.tiff");
  // You only need to set this for the first image in your collection.
  images[0].CompressionMethod = CompressionMethod.Group4;
  images.Write("outputfile.tiff");
}
Adding those two new methods is not much work and you are probably not the only one that could use it. With your help Magick.NET will become a better product for everybody.
Apr 29, 2014 at 1:11 PM
dlemstra,

Thank you for showing me how to set the compression method. I didn't realize you only needed to set it for the first image in the set.

I have Magick.NET currently doing everything I need from it. I really appreciate your help.

Thanks again.

Corbin