使用BitMiracle.LibTiff.NET,将多个jpg合成tif文件

TIFF图像处理与转换
本文介绍了一个名为Tiffcp的类及其使用方法,该类能够实现多个图像文件的合成与转换,支持多种图像格式及参数配置。文章详细解释了如何通过命令行调用Tiffcp来完成图像文件的合成,并提供了丰富的选项说明,如压缩方式、颜色模式等。

两个类(Tiffcp和Copier),代码来自 https://github.com/BitMiracle/libtiff.net/tree/master/TiffCP

调用:Tiffcp.Main2(string数组);

其中string数组,存的是包含绝对路径的文件名列表,最后一行是 tif 的文件名,之上是要合成的jpg图片名。 如: ["c:\1.jpg", "c:\2.jpg", "c:\1.tif"]

    public class Tiffcp
    {
        static string[] m_stuff =
        {
            "usage: tiffcp [options] input... output",
            "where options are:",
            " -a		append to output instead of overwriting",
            " -o offset	set initial directory offset",
            " -p contig	pack samples contiguously (e.g. RGBRGB...)",
            " -p separate	store samples separately (e.g. RRR...GGG...BBB...)",
            " -s		write output in strips",
            " -t		write output in tiles",
            " -i		ignore read errors",
            " -b file[,#]	bias (dark) monochrome image to be subtracted from all others",
            " -,=%		use % rather than , to separate image #'s (per Note below)",
            "",
            " -r #		make each strip have no more than # rows",
            " -w #		set output tile width (pixels)",
            " -l #		set output tile length (pixels)",
            "",
            " -f lsb2msb	force lsb-to-msb FillOrder for output",
            " -f msb2lsb	force msb-to-lsb FillOrder for output",
            "",
            " -c lzw[:opts]	compress output with Lempel-Ziv & Welch encoding",
            " -c zip[:opts]	compress output with deflate encoding",
            " -c jpeg[:opts]	compress output with JPEG encoding",
            " -c packbits	compress output with packbits encoding",
            " -c g3[:opts]	compress output with CCITT Group 3 encoding",
            " -c g4		compress output with CCITT Group 4 encoding",
            " -c none	use no compression algorithm on output",
            "",
            "Group 3 options:",
            " 1d		use default CCITT Group 3 1D-encoding",
            " 2d		use optional CCITT Group 3 2D-encoding",
            " fill		byte-align EOL codes",
            "For example, -c g3:2d:fill to get G3-2D-encoded data with byte-aligned EOLs",
            "",
            "JPEG options:",
            " #		set compression quality level (0-100, default 75)",
            " r		output color image as RGB rather than YCbCr",
            "For example, -c jpeg:r:50 to get JPEG-encoded RGB data with 50% comp. quality",
            "",
            "LZW and deflate options:",
            " #		set predictor value",
            "For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
            "",
            "Note that input filenames may be of the form filename,x,y,z",
            "where x, y, and z specify image numbers in the filename to copy.",
            "example:  tiffcp -c none -b esp.tif,1 esp.tif,0 test.tif",
            "  subtract 2nd image in esp.tif from 1st yielding uncompressed result test.tif",
            null
        };

        public static void Main2(string[] args)
        {
            Copier c = new Copier();

            StringBuilder mode = new StringBuilder();
            mode.Append('w');

            char imageNumberSeparator = ','; // (default) comma separator character
            FillOrder defaultFillOrder = 0;
            int defaultTileLength = -1;
            int initialDirectoryOffset = 0;
            PlanarConfig defaultPlanarConfig = PlanarConfig.UNKNOWN;
            int defaultRowsPerStrip = 0;
            int defaultTileWidth = -1;

            int argn = 0;
            for (; argn < args.Length; argn++)
            {
                string option = args[argn];
                if (option[0] == '-')
                    option = option.Substring(1);
                else
                    break;

                string optionArg = null;
                if (argn < (args.Length - 1))
                    optionArg = args[argn + 1];

                switch (option[0])
                {
                    case ',':
                        if (option[1] != '=')
                        {
                            usage();
                            return;
                        }

                        imageNumberSeparator = option[2];
                        break;
                    case 'b':
                        // this file is bias image subtracted from others
                        if (c.m_bias != null)
                        {
                            Console.Error.Write("Only 1 bias image may be specified\n");
                            return;
                        }

                        string biasName = args[argn + 1];
                        c.m_bias = Tiff.Open(biasName, "r");
                        if (c.m_bias == null)
                        {
                            Console.Error.WriteLine("Failed to open '{0}' as input.", biasName);
                            return;
                        }

                        if (c.m_bias.IsTiled())
                        {
                            Console.Error.Write("Bias image must be organized in strips\n");
                            return;
                        }

                        FieldValue[] result = c.m_bias.GetField(TiffTag.SAMPLESPERPIXEL);
                        short samples = result[0].ToShort();
                        if (samples != 1)
                        {
                            Console.Error.Write("Bias image must be monochrome\n");
                            return;
                        }

                        argn++;
                        break;
                    case 'a':
                        // append to output
                        mode[0] = 'a';
                        break;
                    case 'c':
                        // compression scheme
                        if (!c.ProcessCompressOptions(optionArg))
                        {
                            usage();
                            return;
                        }

                        argn++;
                        break;
                    case 'f':
                        // fill order
                        if (optionArg == "lsb2msb")
                            defaultFillOrder = FillOrder.LSB2MSB;
                        else if (optionArg == "msb2lsb")
                            defaultFillOrder = FillOrder.MSB2LSB;
                        else
                        {
                            usage();
                            return;
                        }

                        argn++;
                        break;
                    case 'i':
                        // ignore errors
                        c.m_ignore = true;
                        break;
                    case 'l':
                        // tile length
                        c.m_outtiled = 1;
                        defaultTileLength = int.Parse(optionArg, CultureInfo.InvariantCulture);
                        argn++;
                        break;
                    case 'o':
                        // initial directory offset
                        initialDirectoryOffset = int.Parse(optionArg, CultureInfo.InvariantCulture);
                        break;
                    case 'p':
                        // planar configuration
                        if (optionArg == "separate")
                            defaultPlanarConfig = PlanarConfig.SEPARATE;
                        else if (optionArg == "contig")
                            defaultPlanarConfig = PlanarConfig.CONTIG;
                        else
                        {
                            usage();
                            return;
                        }

                        argn++;
                        break;
                    case 'r':
                        // rows/strip
                        defaultRowsPerStrip = int.Parse(optionArg, CultureInfo.InvariantCulture);
                        argn++;
                        break;
                    case 's':
                        // generate stripped output
                        c.m_outtiled = 0;
                        break;
                    case 't':
                        // generate tiled output
                        c.m_outtiled = 1;
                        break;
                    case 'w':
                        // tile width
                        c.m_outtiled = 1;
                        defaultTileWidth = int.Parse(optionArg, CultureInfo.InvariantCulture);
                        argn++;
                        break;
                    case 'B':
                        mode.Append('b');
                        break;
                    case 'L':
                        mode.Append('l');
                        break;
                    case 'M':
                        mode.Append('m');
                        break;
                    case 'C':
                        mode.Append('c');
                        break;
                    case 'x':
                        c.m_pageInSeq = 1;
                        break;
                    case '?':
                        usage();
                        return;
                }
            }

            if (args.Length - argn < 2)
            {
                // there must be at least one input and one output image names after options
                usage();
                return;
            }

            using (Tiff outImage = Tiff.Open(args[args.Length - 1], mode.ToString()))
            {
                if (outImage == null)
                {
                    Console.Error.WriteLine("Failed to open '{0}' as output.", args[args.Length - 1]);
                    return;
                }

                if ((args.Length - argn) == 2)
                    c.m_pageNum = -1;

                for (; argn < args.Length - 1; argn++)
                {
                    string[] fileAndPageNums = args[argn].Split(new char[] { imageNumberSeparator });

                    using (Tiff inImage = Tiff.Open(fileAndPageNums[0], "r"))
                    {
                        if (inImage == null)
                            return;

                        if (initialDirectoryOffset != 0 && !inImage.SetSubDirectory(initialDirectoryOffset))
                        {
                            Tiff.Error(inImage, inImage.FileName(), "Error, setting subdirectory at 0x{0:x}", initialDirectoryOffset);
                            break;
                        }

                        int initialPage = 0;
                        int pageNumPos = 1;

                        if (pageNumPos < fileAndPageNums.Length && !string.IsNullOrEmpty(fileAndPageNums[pageNumPos]))
                            initialPage = int.Parse(fileAndPageNums[pageNumPos]);

                        int totalPages = inImage.NumberOfDirectories();
                        for (int i = initialPage; i < totalPages;)
                        {
                            c.m_config = defaultPlanarConfig;
                            c.m_compression = c.m_defcompression;
                            c.m_predictor = c.m_defpredictor;
                            c.m_fillorder = defaultFillOrder;
                            c.m_rowsperstrip = defaultRowsPerStrip;
                            c.m_tilewidth = defaultTileWidth;
                            c.m_tilelength = defaultTileLength;
                            c.m_g3opts = c.m_defg3opts;

                            if (!inImage.SetDirectory((short)i))
                            {
                                Console.Error.Write("{0}{1}{2} not found!\n",
                                    inImage.FileName(), imageNumberSeparator, i);
                                return;
                            }

                            if (!c.Copy(inImage, outImage) || !outImage.WriteDirectory())
                                return;

                            // if we have at least one page specifier and current specifier is not empty.
                            // specifier is empty when trailing separator used like this: "file,num,"
                            if (pageNumPos < fileAndPageNums.Length && !string.IsNullOrEmpty(fileAndPageNums[pageNumPos]))
                            {
                                // move to next page specifier
                                pageNumPos++;

                                if (pageNumPos < fileAndPageNums.Length)
                                {
                                    // new page specifier position is valid

                                    if (!string.IsNullOrEmpty(fileAndPageNums[pageNumPos]))
                                    {
                                        // new page specifier is not empty. use specified page number
                                        i = int.Parse(fileAndPageNums[pageNumPos]);
                                    }
                                    else
                                    {
                                        // new page specifier is empty. just move to the next page
                                        i++;
                                    }
                                }
                                else
                                {
                                    // new page specifier position is invalid. done all pages.
                                    break;
                                }
                            }
                            else
                            {
                                // we have no page specifiers or current page specifier is empty
                                // just move to the next page
                                i++;
                            }
                        }
                    }
                }
            }
        }

        static void usage()
        {
            using (TextWriter stderr = Console.Error)
            {
                stderr.Write("{0}\n\n", Tiff.GetVersion());
                for (int i = 0; m_stuff[i] != null; i++)
                    stderr.Write("{0}\n", m_stuff[i]);
            }
        }
    }

 public class Copier
    {
        struct tagToCopy
        {
            public tagToCopy(TiffTag _tag, short _count, TiffType _type)
            {
                tag = _tag;
                count = _count;
                type = _type;
            }

            public TiffTag tag;
            public short count;
            public TiffType type;
        };

        static tagToCopy[] g_tags =
        {
            new tagToCopy(TiffTag.SUBFILETYPE, 1, TiffType.LONG),
            new tagToCopy(TiffTag.THRESHHOLDING, 1, TiffType.SHORT),
            new tagToCopy(TiffTag.DOCUMENTNAME, 1, TiffType.ASCII),
            new tagToCopy(TiffTag.IMAGEDE
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

orangapple

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值