注意:在创建一个从未被LibTiff.Net库更改的新tiff图像时,我可以使用LibTiff.Net库来添加/更改标记而没有任何问题(第一次)。
在我使用LibTiff.Net库无论如何改变tiff标签后,当我第二次尝试改变它们时图像变得腐败。标签看起来很好,但图像本身显示为黑色图像(损坏)。
这是我班上使用的标签扩展器......
private static Tiff.TiffExtendProc m_parentExtender;
private static List<TIFFTAGS_TAG> m_lTagsToWrite;
private static void TagExtender(Tiff tif)
{
List<TiffFieldInfo> tfInfo = new List<TiffFieldInfo>();
Int16 readCount = 0;
Int16 writeCount = 0;
bool okToChange = false;
bool passCount = false;
//Make sure to create a new tiff field info for all the tags to be written
foreach (TIFFTAGS_TAG ttTag in m_lTagsToWrite)
{
switch (ttTag.TagType)
{
case TIFFTAGS_TAG_DATATYPE.ASCII:
readCount = -1;
writeCount = -1;
okToChange = true;
passCount = false;
break;
case TIFFTAGS_TAG_DATATYPE.LONG:
case TIFFTAGS_TAG_DATATYPE.RATIONAL:
case TIFFTAGS_TAG_DATATYPE.SHORT:
readCount = 2;
writeCount = 2;
okToChange = false;
passCount = true;
break;
}
if (ttTag.TagType != TIFFTAGS_TAG_DATATYPE.UNKNOWN)
{
//Add the new item to the list
tfInfo.Add(new TiffFieldInfo((TiffTag)ttTag.TagNumber, readCount, writeCount, (TiffType)ttTag.TagType, FieldBit.Custom, okToChange, passCount, ttTag.TagName));
}
}
//Turn the list into an array again
TiffFieldInfo[] tfInfoArray = tfInfo.ToArray();
//Add the fields to the main field info area
tif.MergeFieldInfo(tfInfoArray, tfInfoArray.Length);
//Propergate the chain if needed
if (m_parentExtender != null)
m_parentExtender(tif);
}
这是我目前用于在给定tiff上设置tiff标签的函数
public static bool SetTiffTags(string sFileName, List<TIFFTAGS_TAG> ttTagsInfo)
{
//Sets all the tiff tags in the image given.
//Returns true if successful or false if error occured
//Check if the file exists
if (!File.Exists(sFileName))
{
//File does not exist
return false;
}
try
{
//Set the tag info so that it can be carried over to the extender callback
m_lTagsToWrite = new List<TIFFTAGS_TAG>();
m_parentExtender = Tiff.SetTagExtender(TagExtender);
m_lTagsToWrite = ttTagsInfo;
using (Tiff tImage = Tiff.Open(sFileName, "a"))
{
if (tImage != null)
{
//Go to the first page
tImage.SetDirectory(0);
foreach (TIFFTAGS_TAG ttTag in ttTagsInfo)
{
switch (ttTag.TagType)
{
case TIFFTAGS_TAG_DATATYPE.ASCII:
try
{
//string
string sValue = ttTag.Value.ToString();
tImage.SetField((TiffTag)ttTag.TagNumber, sValue);
}
catch
{
//Could not convert to a string
return false;
}
break;
case TIFFTAGS_TAG_DATATYPE.LONG:
try
{
//long
int[] iValues;
if (ttTag.Value.GetType().ToString() == "System.Int32")
{
iValues = new int[] { (int)ttTag.Value };
}
else if (ttTag.Value.GetType().ToString() == "System.Int32[]")
{
iValues = (int[])ttTag.Value;
}
else return false;
tImage.SetField((TiffTag)ttTag.TagNumber, iValues.Count(), iValues);
}
catch
{
//Could not convert to a long
return false;
}
break;
case TIFFTAGS_TAG_DATATYPE.SHORT:
try
{
//short
Int16[] iValues;
if (ttTag.Value.GetType().ToString() == "System.Int16")
{
iValues = new Int16[] { (Int16)ttTag.Value };
}
else if (ttTag.Value.GetType().ToString() == "System.Int16[]")
{
iValues = (Int16[])ttTag.Value;
}
else return false;
tImage.SetField((TiffTag)ttTag.TagNumber, iValues.Count(), iValues);
}
catch
{
//Could not convert to a short
return false;
}
break;
case TIFFTAGS_TAG_DATATYPE.RATIONAL:
try
{
//float
Single[] iValues;
if (ttTag.Value.GetType().ToString() == "System.Single")
{
iValues = new Single[] { (Single)ttTag.Value };
}
else if (ttTag.Value.GetType().ToString() == "System.Single[]")
{
iValues = (Single[])ttTag.Value;
}
else return false;
tImage.SetField((TiffTag)ttTag.TagNumber, iValues.Count(), iValues);
}
catch
{
//Could not convert to a single
return false;
}
break;
default:
//This type of tag is not supported so error out
return false;
}
}
//Write the information to the tiff
tImage.CheckpointDirectory();
}
else
{
//Restore previous tag extender
Tiff.SetTagExtender(m_parentExtender);
return false;
}
}
//Restore previous tag extender
Tiff.SetTagExtender(m_parentExtender);
}
catch
{
//Restore previous tag extender
Tiff.SetTagExtender(m_parentExtender);
return false;
}
//Return success
return true;
}
答案 0 :(得分:1)
快速查看代码会让我觉得问题的原因是调用tImage.CheckpointDirectory();
通过此调用,您可以有效地将目录数据写入文件,而无需考虑可能已存在的内容。
我想迟早通过调用CheckpointDirectory
写入的目录开始占用的空间比之前为文件中的目录数据分配的空间要多,并且栅格数据的开头会被覆盖。
请尝试使用RewriteDirectory方法。