c# – 在Windows 7 / .Net 4.0上将多页Tiff拆分为单个Tiff

我最近搬到了一个新的开发盒,从Windows XP 32位到Windows 7 64位.这两台机器都运行.Net Framework 4.0版,用于使用Visual Studio 2010进行开发.

升级到Windows 7 64位后,我的代码将多页Tiff图像分割成单独的图像现在已被破坏(之前在XP 32 Bit上工作正常,除了MS填充顺序错误).在调试之后,.Net Framework似乎正确地读取了位图元数据,但是,堆栈中的某些组件错误地持久化了一些Tiff标签(273,278和279).我已经尝试了几种方法来完成拆分,包括GDI和FreeImage库,但都在.Net中失败.我能够使用Image Magick和另一个带有效标签值的第三方工具成功拆分Tiff.

具体来说,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);
                        }
                    }
                }
            }
        }
    }
}

解决方法:

您可以尝试使用LibTiff.Net库.它是免费的开源(BSD许可证).

该库附带了tiffcp实用程序,可以从您的代码中使用它来分割/合并TIFF图像.或者您可以使用该实用程序的源代码作为示例.

LibTiff.Net还包含使用应用程序中的tiffcp合并和分割TIFF图像的示例.

免责声明:我是图书馆的维护者之一.

上一篇:如何使用C#以低分辨率形式提供高分辨率图像


下一篇:c# – 使用libtiff.net编写大量TIFF页面的有效方法