zoukankan      html  css  js  c++  java
  • LibTiff.NET: 从tiff文件中复制指定的页面到一个新的tiff文件

    LibTiff.NET是libtiff library的.net实现,代码地址为:https://github.com/BitMiracle/libtiff.net

    本示例所用的版本为

    <?xml version="1.0" encoding="utf-8"?>
    <packages>
      <package id="BitMiracle.LibTiff.NET" version="2.4.639" targetFramework="net48" />
    </packages>
    

    示例代码如下(使用的测试文件为 https://github.com/BitMiracle/libtiff.net/blob/master/Samples/Sample Data/multipage.tif ):

    using BitMiracle.LibTiff.Classic;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    
    namespace ConsoleAppLibTiff
    {
        class Program
        {
            static void Main(string[] args)
            {
                // read bytes of an image
                byte[] buffer = File.ReadAllBytes(@"C:Datamultipage.tif");
                List<int> pageNumbers = new List<int>() { 3, 1 };
                var fileBytes = CopySpecifyPagesToNewTiffFile(buffer, pageNumbers);
    
                FileStream destFileStream = new FileStream(@"C:DatamultipageNew.tif", FileMode.Create, FileAccess.ReadWrite);
                destFileStream.Write(fileBytes, 0, fileBytes.Length);
                destFileStream.Flush();
                destFileStream.Close();
            }
    
            //https://github.com/BitMiracle/libtiff.net/blob/master/Samples/ConvertToSingleStripInMemory/C%23/ConvertToSingleStripInMemory.cs
            private static byte[] CopySpecifyPagesToNewTiffFile(byte[] sourceTiffImage, List<int> pageNumbers)
            {
                if (pageNumbers == null || !pageNumbers.Any())
                    throw new ArgumentNullException("pageNumbers is null or empty");
                pageNumbers.Sort();
                if (pageNumbers.First() < 1)
                    throw new ArgumentException("the minum pageNumbers can't less than 0.");
    
                // create a memory stream out of them
                MemoryStream ms = new MemoryStream(sourceTiffImage);
    
                // open a Tiff stored in the memory stream
                using (Tiff image = Tiff.ClientOpen("in-memory", "r", ms, new TiffStream()))
                {
                    var numberOfPages = image.NumberOfDirectories();
                    if (pageNumbers.Last() - 1 > numberOfPages)
                        throw new ArgumentException("the maxium pageNumbers can't great than max pageNumber");
    
                    using (MemoryStream msOutput = new MemoryStream())
                    {
                        using (Tiff output = Tiff.ClientOpen("in-memory", "w", msOutput, new TiffStream()))
                        {
                            int index = 0;
                            foreach (int pageNumber in pageNumbers)
                            {
                                var pageIndex = Convert.ToInt16(pageNumber - 1);
                                image.SetDirectory(pageIndex);
    
                                copyTags(image, output);
                                // specify that it's a page within the multipage file
                                output.SetField(TiffTag.SUBFILETYPE, FileType.PAGE);
                                // specify the page number
                                output.SetField(TiffTag.PAGENUMBER, index++, numberOfPages);
                                copyStrips(image, output);
    
                                output.WriteDirectory();
                            }
                        }
                        var bytes = msOutput.ToArray();
                        return bytes;
                    }
                }
            }
            private static void copyTags(Tiff input, Tiff output)
            {
                for (ushort t = ushort.MinValue; t < ushort.MaxValue; ++t)
                {
                    TiffTag tag = (TiffTag)t;
                    FieldValue[] tagValue = input.GetField(tag);
                    if (tagValue != null)
                        output.GetTagMethods().SetField(output, tag, tagValue);
                }
    
                int height = input.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
                output.SetField(TiffTag.ROWSPERSTRIP, height);
            }
    
            private static void copyStrips(Tiff input, Tiff output)
            {
                bool encoded = false;
                FieldValue[] compressionTagValue = input.GetField(TiffTag.COMPRESSION);
                if (compressionTagValue != null)
                    encoded = (compressionTagValue[0].ToInt() != (int)Compression.NONE);
    
                int numberOfStrips = input.NumberOfStrips();
    
                int offset = 0;
                byte[] stripsData = new byte[numberOfStrips * input.StripSize()];
                for (int i = 0; i < numberOfStrips; ++i)
                {
                    int bytesRead = readStrip(input, i, stripsData, offset, encoded);
                    offset += bytesRead;
                }
    
                writeStrip(output, stripsData, offset, encoded);
            }
    
            private static int readStrip(Tiff image, int stripNumber, byte[] buffer, int offset, bool encoded)
            {
                if (encoded)
                    return image.ReadEncodedStrip(stripNumber, buffer, offset, buffer.Length - offset);
                else
                    return image.ReadRawStrip(stripNumber, buffer, offset, buffer.Length - offset);
            }
    
            private static void writeStrip(Tiff image, byte[] stripsData, int count, bool encoded)
            {
                if (encoded)
                    image.WriteEncodedStrip(0, stripsData, count);
                else
                    image.WriteRawStrip(0, stripsData, count);
            }
        }
    }
    
    
  • 相关阅读:
    Ubuntu 网络代理配置
    WSL2 环境配置
    两台笔记本电脑实现同一wifi下虚拟主机网络实现互通
    Linux /dev/loop0文件详解
    Excel两张表查重,返回True
    计算机网络基础/进制转换/企业级子网IP划分
    leetcode 2030. 含特定字母的最小子序列
    nginx https
    kubernetes(二十四)ingress https
    求两个向量的旋转矩阵 E
  • 原文地址:https://www.cnblogs.com/grj1046/p/14248181.html
Copyright © 2011-2022 走看看