Разделение многостраничного Tiff на один Tiff в Windows 7 / .Net 4.0

Я недавно перешел на новую версию для разработки с Windows XP 32 Bit до Windows 7 64 bit. На обеих машинах установлена ​​.Net Framework версии 4.0 для разработки с Visual Studio 2010.

После обновления до 64-разрядной версии Windows 7 мой код для разделения многостраничного образа Tiff на отдельные образы теперь не работает (ранее нормально работал на XP 32). Бит, кроме ошибки порядка заполнения 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);
                        }
                    }
                }
            }
        }
    }
}
5
задан John Saunders 10 April 2013 в 23:34
поделиться