In my scenario I have 3 or more multi-page tiff images which I need to merge into a single tiff image.
Below is the the code I have tried. It merges in to a single tiff image but only with first page of all tiff images.
private static void MergeTiff(string[] sourceFiles)
{
string[] sa = sourceFiles;
//get the codec for tiff files
ImageCodecInfo info = null;
foreach (ImageCodecInfo ice in ImageCodecInfo.GetImageEncoders())
if (ice.MimeType == "image/tiff")
info = ice;
//use the save encoder
Encoder enc = Encoder.SaveFlag;
EncoderParameters ep = new EncoderParameters(1);
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.MultiFrame);
Bitmap pages = null;
int frame = 0;
foreach (string s in sa)
{
if (frame == 0)
{
MemoryStream ms = new MemoryStream(File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, @"C:\Data_Warehouse\SVNRepository\CD.BNS.W5555.LT45555C.D180306.T113850.Z0101\", s)));
pages = (Bitmap)Image.FromStream(ms);
var appDataPath = @"C:\Data_Warehouse\SVNRepository\Tiffiles\";
var filePath = Path.Combine(appDataPath, Path.GetRandomFileName() + ".tif");
//save the first frame
pages.Save(filePath, info, ep);
}
else
{
//save the intermediate frames
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.FrameDimensionPage);
try
{
MemoryStream mss = new MemoryStream(File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, @"C:\Data_Warehouse\SVNRepository\CD.BNS.W5555.LT45555C.D180306.T113850.Z0101\", s)));
Bitmap bm = (Bitmap)Image.FromStream(mss);
pages.SaveAdd(bm, ep);
}
catch (Exception e)
{
//LogError(e, s);
}
}
if (frame == sa.Length - 1)
{
//flush and close.
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.Flush);
pages.SaveAdd(ep);
}
frame++;
}
}
I need to join multiple tiff images with all pages from each tiff image. Please advise!
Thanks
EDIT: Updated from below answer
if (frame == 0)
{
MemoryStream ms = new MemoryStream(File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, @"C:\OMTest\Working\", s)));
pages = (Bitmap)Image.FromStream(ms);
var appDataPath = @"C:\Data_Warehouse\SVNRepository\Tiffiles\";
var filePath = Path.Combine(appDataPath, Path.GetRandomFileName() + ".tif");
//save the first frame
pages.Save(filePath, info, ep);
//Save the second frame if any
int frameCount1 = pages.GetFrameCount(FrameDimension.Page);
if (frameCount1 > 1)
{
for (int i = 1; i < frameCount1; i++)
{
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.FrameDimensionPage);
pages.SelectActiveFrame(FrameDimension.Page, i);
pages.SaveAdd(pages, ep);
}
}
}
else
{
//save the intermediate frames
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.FrameDimensionPage);
try
{
MemoryStream mss = new MemoryStream(File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, @"C:\OMTest\Working\", s)));
Bitmap bm = (Bitmap)Image.FromStream(mss);
int frameCount = bm.GetFrameCount(FrameDimension.Page);
for (int i = 0; i < frameCount; i++)
{
bm.SelectActiveFrame(FrameDimension.Page, i);
pages.SaveAdd(bm, ep);
}
}
catch (Exception e)
{
//LogError(e, s);
}
}
Combine TIFF images with TIFF-editing softwareClick File > Merge Files. Choose Add Files to choose the images to include within the multipage TIFF. Select a folder to save your files to. Click OK to combine the selected files.
Yes, a TIFF file can have multiple pages. A multipage TIFF file saves multiple pages as individual image frames. However, mostly the TIFF images are saved one page per file.
Combine up to 5 TIFF files to one multi-page TIFF for free! If you want to combine 6 or more TIFF files, please, use Desktop TIFF Combine . 1. Select the TIFF files to be combined: 2. Press Combine My Files button:
Method 1. On the File menu, click Merge Files. You'll see Merge Files dialog window. Click Add Files to add your TIFF or PDF files in the list. For every file in the list you can:
Open the JPEG image and click File->Print from the application menu. Choose TIFF Image Printer 11.0 from the list of printers and then click the Print button. Enter the same filename, choose TIFF Multipaged (*.tif) and check Append to file, then click Save. Now open the Excel spreadsheet and click File->Print from the application menu.
We can also append new images to existing single page or multi-page TIFF files. Many compressions like CCITT3, CCITT4, are also applied to TIFF files. Image related data like scanner name, compression type, bits per pixel, and host computer name are also stored in TIFF files using tags.
You need to select the active frame to ensure you are getting all pages on the TIFF. In your code you need to get the count of frames and loop through these.
The code in your else block might look something like this:
MemoryStream mss = new MemoryStream(File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, @"C:\Data_Warehouse\SVNRepository\CD.BNS.W5555.LT45555C.D180306.T113850.Z0101\", s)));
Bitmap bm = (Bitmap)Image.FromStream(mss);
int frameCount = bm.GetFrameCount(FrameDimension.Page);
for(int i=0;i<frameCount;i++){
bm.SelectActiveFrame(FrameDimension.Page, i);
pages.SaveAdd(bm, ep);
}
You may have to tweak it as I haven't tested it.
The given code works great to merge single-page TIFF files into a single multi-page TIFF, however, if there are multi-page TIFF files as sources, it will only merge their first page in the resulting TIFF file: the other ones will be discarded.
Since we couldn't find any working samples that could work around this issue, we ended up coding a small C# helper class, which later became a full-fledged multi-platform console application written in .NET Core 2 and C#. We called the project MergeTIFF and we released the whole source code on GitHub under GNU v3 license, so that everyone else can use it as well; we also released the binaries for Windows and Linux (32-bit and 64-bit).
Here's the relevant excerpt of the C# code:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace MergeTiff.NET
{
/// <summary>
/// A small helper class to handle TIFF files
/// </summary>
public static class TiffHelper
{
/// <summary>
/// Merges multiple TIFF files (including multipage TIFFs) into a single multipage TIFF file.
/// </summary>
public static byte[] MergeTiff(params byte[][] tiffFiles)
{
byte[] tiffMerge = null;
using (var msMerge = new MemoryStream())
{
//get the codec for tiff files
ImageCodecInfo ici = null;
foreach (ImageCodecInfo i in ImageCodecInfo.GetImageEncoders())
if (i.MimeType == "image/tiff")
ici = i;
Encoder enc = Encoder.SaveFlag;
EncoderParameters ep = new EncoderParameters(1);
Bitmap pages = null;
int frame = 0;
foreach (var tiffFile in tiffFiles)
{
using (var imageStream = new MemoryStream(tiffFile))
{
using (Image tiffImage = Image.FromStream(imageStream))
{
foreach (Guid guid in tiffImage.FrameDimensionsList)
{
//create the frame dimension
FrameDimension dimension = new FrameDimension(guid);
//Gets the total number of frames in the .tiff file
int noOfPages = tiffImage.GetFrameCount(dimension);
for (int index = 0; index < noOfPages; index++)
{
FrameDimension currentFrame = new FrameDimension(guid);
tiffImage.SelectActiveFrame(currentFrame, index);
using (MemoryStream tempImg = new MemoryStream())
{
tiffImage.Save(tempImg, ImageFormat.Tiff);
{
if (frame == 0)
{
//save the first frame
pages = (Bitmap)Image.FromStream(tempImg);
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.MultiFrame);
pages.Save(msMerge, ici, ep);
}
else
{
//save the intermediate frames
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.FrameDimensionPage);
pages.SaveAdd((Bitmap)Image.FromStream(tempImg), ep);
}
}
frame++;
}
}
}
}
}
}
if (frame >0)
{
//flush and close.
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.Flush);
pages.SaveAdd(ep);
}
msMerge.Position = 0;
tiffMerge = msMerge.ToArray();
}
return tiffMerge;
}
}
}
For additional info and/or to download it, you can take a look at the following resources that we published to better document the whole project:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With