.NET Image.Save()忽略已更改的TIFF属性项

.NET Image.Save()忽略已更改的TIFF属性项,.net,tiff,.net,Tiff,情境:我有一个包含文本数据和许多二进制TIFF图像的文件。我需要更改一些tiff属性标记,因为在将它们放入该文件之前最初创建tiff时,它们的配置错误。因此,我将二进制数据转储到字节[],然后转储到内存流,然后转储到映像,然后继续从Image.PropertyItems中删除所有PropertyItems,然后通过Image.SetPropertyItem()重新创建我自己的标记。最后,我使用正确的编码器信息和编码器参数执行Image.Save() 问题:创建的文件不包含我创建的所有属性项,我更

情境:我有一个包含文本数据和许多二进制TIFF图像的文件。我需要更改一些tiff属性标记,因为在将它们放入该文件之前最初创建tiff时,它们的配置错误。因此,我将二进制数据转储到字节[],然后转储到内存流,然后转储到映像,然后继续从Image.PropertyItems中删除所有PropertyItems,然后通过Image.SetPropertyItem()重新创建我自己的标记。最后,我使用正确的编码器信息和编码器参数执行Image.Save()

问题:创建的文件不包含我创建的所有属性项,我更改的某些项已被完全忽略。属性项中的数据类型也被忽略(short改为long等)。就像Image.Save()重写它想要的任何东西一样。更具体地说,我将ImageWith和ImageLength属性指定为SHORT,并将它们写为LONG。PlanarConfig属性项甚至根本没有被写入

下面是我的一些代码:(知道为什么会发生这种情况以及如何修复吗?)

const int SHORT=3;
常数int SHORT_LEN=2;
常量int LONG=4;
常量int LONG_LEN=4;
常数int有理=5;
const int RATIONAL_LEN=8;
字节[]bytesFront=bco.Records[0]。字段[4]。数据;
字节[]bytesRear=bco.Records[0]。字段[6]。数据;
MemoryStream msFront=新的MemoryStream(bytesFront);
位图imgFront=(位图)Image.FromStream(msFront);
PropertyItem pi=imgFront.GetPropertyItem(imgFront.PropertyIdList.First());
foreach(PropertyItem currentPropertyItem位于imgFront.PropertyItems中)
{
imgFront.RemovePropertyItem(currentPropertyItem.Id);
}
//子文件类型
pi.Id=254;
pi.类型=长;
pi.Len=长_Len;
pi.Value=GetBytes((uint)0);
imgFront.SetPropertyItem(pi);
//图像宽度
pi.Id=256;
pi.类型=短;
pi.Len=短_Len;
pi.Value=GetBytes((ushort)imgFront.Width);
imgFront.SetPropertyItem(pi);
//...
//平面配置
pi.Id=284;
pi.类型=短;
pi.Len=短_Len;
pi.Value=GetBytes((ushort)1);
imgFront.SetPropertyItem(pi);
//解析单元
pi.Id=296;
pi.类型=短;
pi.Len=短_Len;
pi.Value=GetBytes((ushort)2);
imgFront.SetPropertyItem(pi);
ImageCodecInfo encoderInfo=ImageCodecInfo.GetImageEncoders().First(i=>i.MimeType==“image/tiff”);
EncoderParameters EncoderParameters=新的EncoderParameters(1);
encoderParameters.Param[0]=新的EncoderParameter(System.Drawing.Imaging.Encoder.Compression,(long)EncoderValue.compressionCCIT4);
保存(@“C:\Temp\imgFront.tif”、encoderInfo、encoderParameters);

好的,所以我了解到,也许.NET Framework不是TIFF的最终权威,它实际上可以做任何它想做的事情。你几乎无法控制它。我最终学会了使用LibTiff.NET,并使用以下代码完成了我需要的工作:

byte[] bytesOriginal = bco.Records[0].Fields[4].Data;
MemoryStream streamOriginal = new MemoryStream(bytesOriginal);

streamOriginal.Seek(0, SeekOrigin.Begin);
Tiff tiffMemory = Tiff.ClientOpen("In-Memory", "r", streamOriginal, new TiffStream());
Tiff tiffFile = Tiff.Open(@"C:\Temp\imgTest2.tif", "w");

tiffFile.SetField(TiffTag.SUBFILETYPE, tiffMemory.GetField(TiffTag.SUBFILETYPE).First());
tiffFile.SetField(TiffTag.IMAGEWIDTH, tiffMemory.GetField(TiffTag.IMAGEWIDTH).First());
tiffFile.SetField(TiffTag.IMAGELENGTH, tiffMemory.GetField(TiffTag.IMAGELENGTH).First());
tiffFile.SetField(TiffTag.BITSPERSAMPLE, tiffMemory.GetField(TiffTag.BITSPERSAMPLE).First());
tiffFile.SetField(TiffTag.COMPRESSION, tiffMemory.GetField(TiffTag.COMPRESSION).First());
tiffFile.SetField(TiffTag.PHOTOMETRIC, tiffMemory.GetField(TiffTag.PHOTOMETRIC).First());
tiffFile.SetField(TiffTag.STRIPOFFSETS, tiffMemory.GetField(TiffTag.STRIPOFFSETS).First());
tiffFile.SetField(TiffTag.ORIENTATION, tiffMemory.GetField(TiffTag.ORIENTATION).First());
tiffFile.SetField(TiffTag.SAMPLESPERPIXEL, tiffMemory.GetField(TiffTag.SAMPLESPERPIXEL).First());
tiffFile.SetField(TiffTag.ROWSPERSTRIP, tiffMemory.GetField(TiffTag.ROWSPERSTRIP).First());
tiffFile.SetField(TiffTag.STRIPBYTECOUNTS, tiffMemory.GetField(TiffTag.STRIPBYTECOUNTS).First());
tiffFile.SetField(TiffTag.XRESOLUTION, tiffMemory.GetField(TiffTag.XRESOLUTION).First());
tiffFile.SetField(TiffTag.YRESOLUTION, tiffMemory.GetField(TiffTag.YRESOLUTION).First());
tiffFile.SetField(TiffTag.PLANARCONFIG, tiffMemory.GetField(TiffTag.PLANARCONFIG).First());
tiffFile.SetField(TiffTag.RESOLUTIONUNIT, tiffMemory.GetField(TiffTag.RESOLUTIONUNIT).First());

tiffFile.CheckpointDirectory();

byte[] bytesNew = new byte[tiffMemory.RawStripSize(0)];
tiffMemory.ReadRawStrip(0, bytesNew, 0, bytesNew.Length);
tiffFile.WriteRawStrip(0, bytesNew, bytesNew.Length);

tiffMemory.Close();
tiffFile.Close();
byte[] bytesOriginal = bco.Records[0].Fields[4].Data;
MemoryStream streamOriginal = new MemoryStream(bytesOriginal);

streamOriginal.Seek(0, SeekOrigin.Begin);
Tiff tiffMemory = Tiff.ClientOpen("In-Memory", "r", streamOriginal, new TiffStream());
Tiff tiffFile = Tiff.Open(@"C:\Temp\imgTest2.tif", "w");

tiffFile.SetField(TiffTag.SUBFILETYPE, tiffMemory.GetField(TiffTag.SUBFILETYPE).First());
tiffFile.SetField(TiffTag.IMAGEWIDTH, tiffMemory.GetField(TiffTag.IMAGEWIDTH).First());
tiffFile.SetField(TiffTag.IMAGELENGTH, tiffMemory.GetField(TiffTag.IMAGELENGTH).First());
tiffFile.SetField(TiffTag.BITSPERSAMPLE, tiffMemory.GetField(TiffTag.BITSPERSAMPLE).First());
tiffFile.SetField(TiffTag.COMPRESSION, tiffMemory.GetField(TiffTag.COMPRESSION).First());
tiffFile.SetField(TiffTag.PHOTOMETRIC, tiffMemory.GetField(TiffTag.PHOTOMETRIC).First());
tiffFile.SetField(TiffTag.STRIPOFFSETS, tiffMemory.GetField(TiffTag.STRIPOFFSETS).First());
tiffFile.SetField(TiffTag.ORIENTATION, tiffMemory.GetField(TiffTag.ORIENTATION).First());
tiffFile.SetField(TiffTag.SAMPLESPERPIXEL, tiffMemory.GetField(TiffTag.SAMPLESPERPIXEL).First());
tiffFile.SetField(TiffTag.ROWSPERSTRIP, tiffMemory.GetField(TiffTag.ROWSPERSTRIP).First());
tiffFile.SetField(TiffTag.STRIPBYTECOUNTS, tiffMemory.GetField(TiffTag.STRIPBYTECOUNTS).First());
tiffFile.SetField(TiffTag.XRESOLUTION, tiffMemory.GetField(TiffTag.XRESOLUTION).First());
tiffFile.SetField(TiffTag.YRESOLUTION, tiffMemory.GetField(TiffTag.YRESOLUTION).First());
tiffFile.SetField(TiffTag.PLANARCONFIG, tiffMemory.GetField(TiffTag.PLANARCONFIG).First());
tiffFile.SetField(TiffTag.RESOLUTIONUNIT, tiffMemory.GetField(TiffTag.RESOLUTIONUNIT).First());

tiffFile.CheckpointDirectory();

byte[] bytesNew = new byte[tiffMemory.RawStripSize(0)];
tiffMemory.ReadRawStrip(0, bytesNew, 0, bytesNew.Length);
tiffFile.WriteRawStrip(0, bytesNew, bytesNew.Length);

tiffMemory.Close();
tiffFile.Close();