Объединить несколько многостраничных изображений TIFF в один TIFF C # - PullRequest
0 голосов
/ 21 января 2019

В моем сценарии у меня есть 3 или более многостраничных изображения в формате 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);
                }
            }

Ответы [ 2 ]

0 голосов
/ 31 июля 2019

Данный код прекрасно работает для объединения одностраничных файлов 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;
        }
    }
}

Для получения дополнительной информации и / или ее загрузки вы можете посмотреть следующие ресурсы, которые мы опубликовали, чтобы лучше документировать весь проект:

0 голосов
/ 21 января 2019

Вам необходимо выбрать активный кадр , чтобы убедиться, что вы получаете все страницы в формате TIFF. В вашем коде вам нужно получить количество кадров и просмотреть их.

Код в вашем блоке 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);
}

Возможно, вам придется настроить его, поскольку я его не проверял.

...