简体   繁体   English

如何使用LibTiff.Net 2.3库删除tiff标签

[英]How can I delete tiff tags using the LibTiff.Net 2.3 library

I can't seem to find any documentation of how to delete a tiff tag using the LibTiff.Net library. 我似乎找不到有关如何使用LibTiff.Net库删除tiff标签的任何文档。 I love the library but this one method is important to what I need to do. 我喜欢图书馆,但是这种方法对我需要做的事情很重要。 At one point I was hoping that I could just set a tag and set it's value to nothing. 有一次,我希望我可以设置一个标签并将其值设置为空。 I had hoped that would work but that was a negative. 我曾希望这能奏效,但这是负面的。

Anyone know how to delete a tiff tag using the LibTiff.Net library? 有人知道如何使用LibTiff.Net库删除tiff标签吗?

Please have a look at TiffCP utility (and especially its source code) shipped with LibTiff.Net. 请查看LibTiff.Net附带的TiffCP实用程序(尤其是其源代码)。

LibTiff.Net doesn't offer methods for removing tags (the same is true for LibTiff). LibTiff.Net不提供删除标签的方法(LibTiff也是一样)。 You will need to implement part of TiffCP functionality in order to achieve that. 为此,您将需要实现TiffCP功能的一部分

Basically, you will need to copy all tags you wish to retain, and copy pixels data without decoding and re-encoding it. 基本上,您将需要复制所有想要保留的标签,并复制像素数据而无需对其进行解码和重新编码

Please also have a look at Convert a multi-strip TIFF image to a single-strip one sample. 另请参阅将多条纹TIFF图像转换为单条纹一个样本。 It shows how to copy tags and copy raw (undecoded data) from one image to another. 它显示了如何将标签复制以及将原始(未编码的数据)从一个图像复制到另一个图像。 The sample actually decodes data in some cases because it needs to change number of strips, but you won't need to decode data. 在某些情况下,该示例实际上会解码数据,因为它需要更改条带数,但是您无需解码数据。

I think you will have to basically copy the input file to a new TIFF image filtering out the tags you don't want in the process. 我认为您基本上必须将输入文件复制到新的TIFF图像中,以过滤掉过程中不需要的标签。 Take a look at the tiffcp utility which is part of the regular libtiff distribution. 看一下tiffcp实用程序,它是常规libtiff发行版的一部分。 It sort of does that, minus filtering. 这样做就减去了过滤。

Disclaimer: I've never used LibTiff.Net and am assuming that it is very similar to the LibTiff. 免责声明:我从未使用过LibTiff.Net,并假设它与LibTiff非常相似。

Take a look at tiffcp.c 看看tiffcp.c

First it manually copies/sets some known tags such as resolution, compression, colors etc. Then it copies all a set of tags that can be copied w/o preprocessing: 首先,它手动复制/设置一些已知的标签,例如分辨率,压缩率,颜色等。然后,它复制可以不进行预处理而复制的所有标签集:

for (p = tags; p < &tags[NTAGS]; p++)
    CopyTag(p->tag, p->count, p->type);

Then it copies the actual pixel data. 然后它复制实际的像素数据。 This will from what I recollect, drop any tags that are not known to tiffcp. 根据我的回忆,将删除tiffcp未知的所有标签。 If your tag that you want to drop is in the list, you can trivially drop it by removing it from that list. 如果要删除的标签在列表中,则可以通过从列表中删除标签来删除它。

Note: As first this might look like a big answer but I wanted to make sure that whoever was looking at this see's all the "proprietary classes I have created to keep everything boxed up for cleanness. In the interest of keeping the answer as sort as possible and to be informative I will only paste the code for the DeleteTiffTags method. The rest of the code can be downloaded via here . 注意:首先,这可能看起来像是一个很大的答案,但是我想确保无论是谁,看到的都是我创建的“专有类,以使所有内容装箱整洁。”为了提供更多信息,我将仅粘贴DeleteTiffTags方法的代码,其余代码可通过此处下载。

Now on to the good stuff... I ended up spending about a day on making this happen and it was possible thanks to various questions being answered by the great stackoverflow community. 现在介绍好东西...我最终花了大约一天的时间来实现这一目标,并且有可能由于伟大的stackoverflow社区回答了各种问题。 I wrote two little (very detailed) method in one of my classes to delete a tiff tag. 我在一个类中写了两个很少(非常详细)的方法来删除tiff标签。 The first one is meant to delete a list of given tags and the second one is to delete a single tag which works off the for mentioned method. 第一个是要删除给定标签的列表,第二个是要删除一个单独的标签,该标签无法使用上述方法。 Also in this example I added a few lines to support my custom tiff tags... They will all be preceded with the //ADDED comment. 同样在此示例中,我添加了几行来支持我的自定义tiff标签...它们都将以// ADDED注释开头。

Classes: 类:

public static class TIFFTAGS - This class is the main class that is simply called by doing something like TIFFTAGS.DeleteTiffTags(); 公共静态类TIFFTAGS-此类是通过执行类似TIFFTAGS.DeleteTiffTags()的操作而简单调用的主类。 Since it's a static class there is no need to create an object of it to use it's methods. 由于它是静态类,因此无需创建其对象即可使用其方法。

private class TIFFTAGS_PAGE - This class is a private class that resides inside the TIFFTAGS class. 私有类TIFFTAGS_PAGE-此类是驻留在TIFFTAGS类内部的私有类。 It's purpose is to contain all the single page info for all the pages that might be in the tiff. 目的是包含所有可能在tiff中的页面的所有单个页面信息。 It is private and only used for internal purposes. 它是私有的,仅用于内部目的。

public class TIFFTAGS_TAG - This is a class I made to wrap up the tags in something more to my liking. 公共课程TIFFTAGS_TAG-这是我制作的一类课程,用于按我的喜好包装标签。 Using the standard tag type names such as ASCII, SHORT, LONG, and RATIONAL. 使用标准标记类型名称,例如ASCII,SHORT,LONG和RATIONAL。

Methods/Functions: 方法/功能:

TagExtender() - This little gem is a callback function that allows you to actually keep your CUSTOM tags in the tiff. TagExtender()-这个小小的gem是一个回调函数,允许您将CUSTOM标签实际上保留在tiff中。 Without it ALL of your custom tags would disappear when you deleted any tag (even if you deleted just one). 如果没有它,则删除任何标签时,所有自定义标签都将消失(即使仅删除了一个)。

DeleteTiffTags() - This is the main method that deletes a list of tags. DeleteTiffTags()-这是删除标签列表的主要方法。 Simply pass in a list of ushort tag numbers and all will be deleted. 只需传递一个ushort标签号列表,所有标签都将被删除。 Keep in mind not using the TagExtender function will cause your custom tags to go poof ! 请记住,不使用TagExtender函数将使您的自定义标签变得糟糕

DeleteTiffTag() - This is simply used to delete a single tiff tag. DeleteTiffTag()-这仅用于删除单个tiff标签。 It calls upon DeleteTiffTags() to handle the grunt work. 它调用DeleteTiffTags()来处理繁琐的工作。

public static bool DeleteTiffTags(string sFileName, List<ushort> ushortTagNumbers)
{
    //Deletes a list of tiff tag from the given image
    //Returns true if successful or false if error occured
     //Define variables
    List<TIFFTAGS_PAGE> ttPage = new List<TIFFTAGS_PAGE>();
     //Check for empty list
    if (ushortTagNumbers.Count == 0) return false;
     try
    {
        //ADDED
        m_lTagsToWrite = new List<TIFFTAGS_TAG>();
        m_lTagsToWrite.Add(new TIFFTAGS_TAG("", 38001, Convert.ToString("")));
        m_lTagsToWrite.Add(new TIFFTAGS_TAG("", 38002, Convert.ToString("")));
        m_parentExtender = Tiff.SetTagExtender(TagExtender);
         //Open the file for reading
        using (Tiff input = Tiff.Open(sFileName, "r"))
        {
            if (input == null) return false;
             //Get page count
            int numberOfDirectories = input.NumberOfDirectories();
             //Go through all the pages
            for (short i = 0; i < numberOfDirectories; ++i)
            {
                //Set the page
                input.SetDirectory(i);
                 //Create a new tags dictionary to store all my tags
                Dictionary<ushort, FieldValue[]> dTags = new Dictionary<ushort, FieldValue[]>();
                 //Get all the tags for the page
                for (ushort t = ushort.MinValue; t < ushort.MaxValue; ++t)
                {
                    TiffTag tag = (TiffTag)t;
                    FieldValue[] tagValue = input.GetField(tag);
                    if (tagValue != null)
                    {
                        dTags.Add(t, tagValue);
                    }
                }
                 //Check if the page is encoded
                bool encoded = false;
                FieldValue[] compressionTagValue = input.GetField(TiffTag.COMPRESSION);
                if (compressionTagValue != null)
                    encoded = (compressionTagValue[0].ToInt() != (int)Compression.NONE);

                //Create a new byte array to store all my image data
                int numberOfStrips = input.NumberOfStrips();
                byte[] byteImageData = new byte[numberOfStrips * input.StripSize()];
                int offset = 0;
                 //Get all the image data for the page
                for (int n = 0; n < numberOfStrips; ++n)
                {
                    int bytesRead;
                    if (encoded)
                        bytesRead = input.ReadEncodedStrip(n, byteImageData, offset, byteImageData.Length - offset);
                    else
                        bytesRead = input.ReadRawStrip(n, byteImageData, offset, byteImageData.Length - offset);
                     //Add to the offset keeping up with where we are
                    offset += bytesRead;
                }
                 //Save all the tags, image data, and height, etc for the page
                TIFFTAGS_PAGE tiffPage = new TIFFTAGS_PAGE();
                tiffPage.Height = input.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
                tiffPage.Tags = dTags;
                tiffPage.PageData = byteImageData;
                tiffPage.Encoded = encoded;
                tiffPage.StripSize = input.StripSize();
                tiffPage.StripOffset = input.GetField(TiffTag.STRIPOFFSETS)[0].ToIntArray()[0];
                ttPage.Add(tiffPage);
            }
        }
         //Open the file for writing
        using (Tiff output = Tiff.Open(sFileName + "-new.tif", "w"))
        {
            if (output == null) return false;
             //Go through all the pages
            for (short i = 0; i < ttPage.Count(); ++i)
            {
                //Write all the tags for the page
                foreach (KeyValuePair<ushort, FieldValue[]> tagValue in ttPage[i].Tags)
                {
                    //Write all the tags except the one's needing to be deleted
                    if (!ushortTagNumbers.Contains(tagValue.Key))
                    {
                        TiffTag tag = (TiffTag)tagValue.Key;
                        output.GetTagMethods().SetField(output, tag, tagValue.Value);
                    }
                }
                 //Set the height for the page
                output.SetField(TiffTag.ROWSPERSTRIP, ttPage[i].Height);
                 //Set the offset for the page
                output.SetField(TiffTag.STRIPOFFSETS, ttPage[i].StripOffset);
                 //Save page data along with tags
                output.CheckpointDirectory();
                 //Write each strip one at a time using the same orginal strip size
                int numberOfStrips = ttPage[i].PageData.Length / ttPage[i].StripSize;
                int offset = 0;
                for (int n = 0; n < numberOfStrips; ++n)
                {
                    //Write all the image data (strips) for the page
                    if (ttPage[i].Encoded)
                        //output.WriteEncodedStrip(n, byteStrip, offset, byteStrip.Length - offset);
                        output.WriteEncodedStrip(0, ttPage[i].PageData, offset, ttPage[i].StripSize - offset);
                    else
                        output.WriteRawStrip(n, ttPage[i].PageData, offset, ttPage[i].StripSize - offset);
                     //Add to the offset keeping up with where we are
                    offset += ttPage[i].StripOffset;
                }
                 //Save the image page
                output.WriteDirectory();
            }
        }
         //ADDED
        Tiff.SetTagExtender(m_parentExtender);
    }
    catch
    {
        //ADDED
        Tiff.SetTagExtender(m_parentExtender);

        //Error occured
        return false;
    }
     //Return success
    return true;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM