状況: テキスト データと多くの TIFF 画像をバイナリで含むファイルがあります。そのファイルに配置される前に tiff が最初に作成されたときに間違って構成されているため、変更する必要があるいくつかの tiff プロパティ タグがあります。そのため、バイナリ データを byte[]、MemoryStream、Image の順にダンプし、Image.PropertyItems からすべての PropertyItems を削除し、Image.SetPropertyItem() を介して独自のタグを再作成します。最後に、正しいエンコーダー情報とエンコーダー パラメーターを使用して Image.Save() を実行します。
問題: 作成されたファイルに、作成したすべてのプロパティ項目が含まれておらず、変更した項目の一部が完全に無視されています。プロパティ項目のデータ型も無視されています (short が long に変更されたなど)。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);