0

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

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

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

const int SHORT = 3;
const int SHORT_LEN = 2;
const int LONG = 4;
const int LONG_LEN = 4;
const int RATIONAL = 5;
const int RATIONAL_LEN = 8;

byte[] bytesFront = bco.Records[0].Fields[4].Data;
byte[] bytesRear = bco.Records[0].Fields[6].Data;
MemoryStream msFront = new MemoryStream(bytesFront);
Bitmap imgFront = (Bitmap)Image.FromStream(msFront);

PropertyItem pi = imgFront.GetPropertyItem(imgFront.PropertyIdList.First<int>());

foreach (PropertyItem currentPropertyItem in imgFront.PropertyItems)
{
    imgFront.RemovePropertyItem(currentPropertyItem.Id);
}

// SubFile Type
pi.Id = 254;
pi.Type = LONG;
pi.Len = LONG_LEN;
pi.Value = GetBytes((uint)0);
imgFront.SetPropertyItem(pi);

// Image Width
pi.Id = 256;
pi.Type = SHORT;
pi.Len = SHORT_LEN;
pi.Value = GetBytes((ushort)imgFront.Width);
imgFront.SetPropertyItem(pi);

//...

// Planar Config
pi.Id = 284;
pi.Type = SHORT;
pi.Len = SHORT_LEN;
pi.Value = GetBytes((ushort)1);
imgFront.SetPropertyItem(pi);

// Resolution Unit
pi.Id = 296;
pi.Type = SHORT;
pi.Len = SHORT_LEN;
pi.Value = GetBytes((ushort)2);
imgFront.SetPropertyItem(pi);

ImageCodecInfo encoderInfo = ImageCodecInfo.GetImageEncoders().First(i => i.MimeType == "image/tiff");
EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionCCITT4);

imgFront.Save(@"C:\Temp\imgFront.tif", encoderInfo, encoderParameters);
4

1 回答 1

0

好的,所以我了解到,.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();
于 2013-01-16T21:53:39.797 回答