将多个多页tiff图像合并为一个tiff C#



在我的场景中,我有3个或多个多页tiff图像,需要将它们合并为一个tiff图像。

下面是我尝试过的代码。它合并到单个tiff图像中,但仅与所有tiff图像的第一页合并。

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_WarehouseSVNRepositoryCD.BNS.W5555.LT45555C.D180306.T113850.Z0101", s)));
pages = (Bitmap)Image.FromStream(ms);
var appDataPath = @"C:Data_WarehouseSVNRepositoryTiffiles";
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_WarehouseSVNRepositoryCD.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++;
}
}

我需要将多个tiff图像与每个tiff图像的所有页面连接起来。请告知!

感谢

编辑:根据以下答案更新

if (frame == 0)
{
MemoryStream ms = new MemoryStream(File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, @"C:OMTestWorking", s)));
pages = (Bitmap)Image.FromStream(ms);
var appDataPath = @"C:Data_WarehouseSVNRepositoryTiffiles";
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:OMTestWorking", 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);
}
}

您需要选择活动帧以确保在TIFF上获得所有页面。在您的代码中,您需要获得帧数并循环这些帧数。

其他块中的代码可能看起来像这样:

MemoryStream mss = new MemoryStream(File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, @"C:Data_WarehouseSVNRepositoryCD.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);
}

你可能需要调整它,因为我还没有测试过

给定的代码可以很好地将单页TIFF文件合并为一个多页TIFF,但是,如果有多页TIFF文件作为源,它只会将它们的第一页合并到生成的TIFF文件中:其他文件将被丢弃。

由于我们找不到任何可以解决这个问题的工作示例,我们最终编写了一个小的C#助手类,该类后来成为了一个用.NET Core 2和C#编写的完整的多平台控制台应用程序。我们将该项目称为MergeTIFF,并在GNUv3许可证下在GitHub上发布了整个源代码,以便其他人也可以使用它;我们还发布了Windows和Linux的二进制文件(32位和64位)。

以下是C#代码的相关摘录:

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;
}
}
}

有关更多信息和/或下载,您可以查看我们发布的以下资源,以便更好地记录整个项目:

  • GitHub上的MergeTIFF
  • 规范、依赖项和其他信息

最新更新