【问题标题】:Merge multiple multi-page tiff images to a single tiff C#将多个多页 tiff 图像合并到单个 tiff C#
【发布时间】:2019-06-14 12:19:26
【问题描述】:

在我的场景中,我需要将 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_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++;
    }

}

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

谢谢

编辑:从下面的答案更新

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

【问题讨论】:

    标签: c# .net image-processing drawing tiff


    【解决方案1】:

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

    由于我们找不到任何可以解决此问题的工作示例,我们最终编写了一个小型 C# 帮助程序类,该类后来成为使用 .NET Core 2 和 C# 编写的成熟的多平台控制台应用程序。我们将该项目命名为 MergeTIFF,我们在 GitHub 上发布了 GNU v3 许可下的整个源代码,以便其他人也可以使用它;我们还发布了适用于 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;
            }
        }
    }
    

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

    【讨论】:

      【解决方案2】:

      您需要select the active frame 以确保您获得 TIFF 上的所有页面。在您的代码中,您需要 get the count of frames 并遍历这些代码。

      else 块中的代码可能如下所示:

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

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

      【讨论】:

      • 非常感谢。尽管我不得不稍作调整,但您的代码运行良好。在编辑部分添加了更改代码供任何人参考。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-02
      • 1970-01-01
      • 1970-01-01
      • 2011-07-30
      • 2020-05-16
      相关资源
      最近更新 更多