Недавно я перешел на новую среду разработки с 32-разрядной версии Windows XP на 64-разрядную версию Windows 7. Обе машины работают под управлением .Net Framework версии 4.0 для разработки с помощью Visual Studio 2010.
После обновления до 64-разрядной версии Windows 7 мой код для разделения многостраничного изображения Tiff на отдельные изображения теперь не работает (ранее работал нормально на 32-разрядной версии XP, за исключением ошибки порядка заполнения MS). После отладки метаданные растрового изображения правильно считываются .Net Framework, однако некоторые компоненты в стеке неправильно сохраняют некоторые теги Tiff (273, 278 и 279). Я пробовал несколько способов выполнить разделение, включая GDI+ и библиотеку FreeImage, но все они терпят неудачу в .Net. Мне удалось успешно разделить Tiff с помощью Image Magick и другого стороннего инструмента с допустимыми значениями тегов.
В частности, теги Tiff 273, 278 (должны совпадать с 257, но не совпадают) и 279 имеют неверные значения.
Это известная проблема Microsoft? Есть ли обходной путь? Я неправильно выполняю это задание? Очень разочарован, так как это прекрасно работало на XP 32, и эта ОС не является вариантом развертывания.
// Copy bytes into our memory
using (MemoryStream ms = new MemoryStream())
{
using (BinaryWriter bw = new BinaryWriter(ms))
{
// Get the multi page tiff image's size, and allocate a place to put it.
int size = RdmInstance.ImageSize;
byte[] imgContents = new byte[size + 1];
// Create the pointer and assign the Rdm image address to it
IntPtr pointerToImage = new IntPtr(RdmInstance.ImageData);
// Copy the bytes from unmanaged memory to managed memory
Marshal.Copy(pointerToImage, imgContents, 0, size);
// Now, write that contents into our memory stream
bw.Write(imgContents);
// Check for multiple tiff pages, split them out and write them out correctly for the Fed
TiffBitmapDecoder decoder = new TiffBitmapDecoder(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
if (decoder.Frames.Count > 0)
{
// check for multi page tiff
for (int i = 0; i < decoder.Frames.Count; i++)
{
log.InfoFormat("Loading Multi Page Tiff Frame [{0}]... to bitmap", i);
// First is front, second is back
// TODO - it would be better to get this out of tiff tag RDM sets with the page info
string fileName = (i == 0) ? frontFileName : backFileName;
BitmapSource bmSrc = decoder.Frames[i];
TiffBitmapEncoder encoder = new TiffBitmapEncoder();
encoder.Compression = TiffCompressOption.Ccitt4;
encoder.Frames.Add(BitmapFrame.Create(bmSrc));
log.InfoFormat("Saving Multi Page Tiff Frame [{0}]... to file {1}.", i, fileName);
using (var fs = new FileStream(fileName, FileMode.Create))
{
encoder.Save(fs);
}
/*
* jknipp - 6/4/2010
* Microsoft has a bug in their TiffBitmapEncoder where
* they incorrectly set tag 266 (Fill Order) to 0, where the TIFF
* spec says it should be 1 or 2. We fix this here.
* Reopen the stupid file and fix the fill order
*/
using (var file = new FileStream(fileName, FileMode.Open))
{
TiffBitmapDecoder output = new TiffBitmapDecoder(file, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
InPlaceBitmapMetadataWriter metadata = output.Frames[0].CreateInPlaceBitmapMetadataWriter();
var fillOrder = metadata.GetQuery("/ifd/{ushort=266}");
log.DebugFormat("Read Fill Order Metadata tag as {0}", fillOrder);
// If .Net added a bogus fill order, correct it
if (fillOrder != null && (ushort)fillOrder == 0)
{
log.InfoFormat("Correcting FILL ORDER in file {0}", fileName);
metadata.SetQuery("/ifd/{ushort=266}", (ushort)1);
// Try to save new metadata
if (metadata.TrySave())
{
fillOrder = metadata.GetQuery("/ifd/{ushort=266}");
log.Info("Fill order correction successful!");
log.DebugFormat("Read New Fill Order Metadata tag as {0}", fillOrder);
}
}
}
}
}
}
}