我似乎找不到任何关于如何使用 LibTiff.Net 库删除 tiff 标签的文档。我喜欢图书馆,但这一种方法对我需要做的事情很重要。有一次我希望我可以设置一个标签并将它的价值设置为空。我曾希望这会奏效,但这是消极的。
任何人都知道如何使用 LibTiff.Net 库删除 tiff 标签?
我似乎找不到任何关于如何使用 LibTiff.Net 库删除 tiff 标签的文档。我喜欢图书馆,但这一种方法对我需要做的事情很重要。有一次我希望我可以设置一个标签并将它的价值设置为空。我曾希望这会奏效,但这是消极的。
任何人都知道如何使用 LibTiff.Net 库删除 tiff 标签?
请查看 LibTiff.Net 附带的 TiffCP 实用程序(尤其是其源代码)。
LibTiff.Net 不提供删除标签的方法(LibTiff 也是如此)。您需要实现部分TiffCP 功能才能实现。
基本上,您将需要复制您希望保留的所有标签,并复制像素数据而不对其进行解码和重新编码。
另请查看将多条 TIFF 图像转换为单条样本。它展示了如何复制标签并将原始(未解码的数据)从一张图像复制到另一张图像。该示例在某些情况下实际上会解码数据,因为它需要更改条带的数量,但您不需要解码数据。
我认为您基本上必须将输入文件复制到新的 TIFF 图像中,过滤掉您在此过程中不需要的标签。查看 tiffcp 实用程序,它是常规 libtiff 发行版的一部分。它有点这样做,减去过滤。
免责声明:我从未使用过 LibTiff.Net,并假设它与 LibTiff 非常相似。
看看 tiffcp.c
首先,它手动复制/设置一些已知的标签,例如分辨率、压缩、颜色等。然后它复制所有可以在没有预处理的情况下复制的标签集:
for (p = tags; p < &tags[NTAGS]; p++)
CopyTag(p->tag, p->count, p->type);
然后它复制实际的像素数据。根据我的回忆,这将删除 tiffcp 不知道的任何标签。如果您要删除的标签在列表中,您可以通过从该列表中删除它来轻松删除它。
注意:首先,这可能看起来像一个很大的答案,但我想确保查看此内容的人看到所有“我创建的专有类,以保持所有内容都装箱以保持清洁。为了保持答案的排序为可能并且为了提供信息,我只会粘贴 DeleteTiffTags 方法的代码。其余代码可以通过这里下载。
现在谈谈好东西......我最终花了大约一天的时间来实现这一点,这要归功于伟大的 stackoverflow 社区回答的各种问题。我在我的一个类中编写了两个小(非常详细)方法来删除 tiff 标签。第一个是删除给定标签的列表,第二个是删除单个标签,该标签适用于上述方法。同样在这个例子中,我添加了几行来支持我的自定义 tiff 标签...它们都将在前面加上 //ADDED 注释。
课程:
public static class TIFFTAGS - 这个类是主类,通过执行 TIFFTAGS.DeleteTiffTags() 之类的操作简单地调用;因为它是一个静态类,所以不需要创建它的对象来使用它的方法。
私有类 TIFFTAGS_PAGE - 此类是驻留在 TIFFTAGS 类中的私有类。它的目的是包含所有可能在 tiff 中的页面的所有单页信息。它是私有的,仅用于内部目的。
public class TIFFTAGS_TAG - 这是我制作的一个类,用于将标签包装成我喜欢的东西。使用标准标记类型名称,例如 ASCII、SHORT、LONG 和 RATIONAL。
方法/功能:
TagExtender() - 这个小宝石是一个回调函数,允许您将 CUSTOM 标签实际保存在 tiff 中。没有它,当您删除任何标签时,所有自定义标签都会消失(即使您只删除了一个标签)。
DeleteTiffTags() - 这是删除标签列表的主要方法。只需传入一个 ushort 标签号列表,所有这些都将被删除。请记住,不使用TagExtender函数会导致您的自定义标签失效 !
DeleteTiffTag() - 这仅用于删除单个 tiff 标签。它调用 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;
}