0

状況: テキスト データと多くの 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);
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 に答える