C#:如何通过MemoryStream将多页TIFF转换为一个长图像?

所以我已经能够拍摄多页TIFF文件并将其转换为单个jpeg图像,但它会使TIFF变平。 通过展平它,我的意思是它只返回第一页。 目标是检索TIFF(通过内存流),打开TIFF的每一页并将其附加到新的jpeg(或任何Web图像)。 因此,无需插件即可在Web上创建一个长图像。 我确实安装了MODI.dll,但我不确定如何在这个实例中使用它,但它是一个选项。

  • 源代码(使用FileHandler):

    #region multi-page tiff to single page jpeg var byteFiles = dfSelectedDocument.File.FileBytes; // <-- FileBytes is a byte[] or byte array source. byte[] jpegBytes; using( var inStream = new MemoryStream( byteFiles ) ) using( var outStream = new MemoryStream() ) { System.Drawing.Image.FromStream( inStream ).Save( outStream, ImageFormat.Jpeg ); jpegBytes = outStream.ToArray(); } context.Response.ContentType = "image/JPEG"; context.Response.AddHeader( "content-disposition", string.Format( "attachment;filename=\"{0}\"", dfSelectedDocument.File.FileName.Replace( ".tiff", ".jpg" ) ) ); context.Response.Buffer = true; context.Response.BinaryWrite( jpegBytes ); #endregion 

我猜你必须在TIFF中循环每一帧。

这是Split多页面tiff文件的摘录:

 private void Split(string pstrInputFilePath, string pstrOutputPath) { //Get the frame dimension list from the image of the file and Image tiffImage = Image.FromFile(pstrInputFilePath); //get the globally unique identifier (GUID) Guid objGuid = tiffImage.FrameDimensionsList[0]; //create the frame dimension FrameDimension dimension = new FrameDimension(objGuid); //Gets the total number of frames in the .tiff file int noOfPages = tiffImage.GetFrameCount(dimension); ImageCodecInfo encodeInfo = null; ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders(); for (int j = 0; j < imageEncoders.Length; j++) { if (imageEncoders[j].MimeType == "image/tiff") { encodeInfo = imageEncoders[j]; break; } } // Save the tiff file in the output directory. if (!Directory.Exists(pstrOutputPath)) Directory.CreateDirectory(pstrOutputPath); foreach (Guid guid in tiffImage.FrameDimensionsList) { for (int index = 0; index < noOfPages; index++) { FrameDimension currentFrame = new FrameDimension(guid); tiffImage.SelectActiveFrame(currentFrame, index); tiffImage.Save(string.Concat(pstrOutputPath, @"\", index, ".TIF"), encodeInfo, null); } } } 

您应该能够调整上面的逻辑以附加到JPG上,而不是创建单独的文件。

如果您在使用其他答案中建议的SelectActiveFrame方法时遇到可怕的“GDI +中发生一般错误”错误(可以说是所有错误的Rickroll),我强烈建议使用System.Windows.Media.Imaging.TiffBitmapDecoder类(您需要添加对PresentationCore.dll框架库的引用 )。

下面是一个示例代码(它将所有TIFF帧放入标准位图列表中):

 List bmpLst = new List(); using (var msTemp = new MemoryStream(data)) { TiffBitmapDecoder decoder = new TiffBitmapDecoder(msTemp, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); int totFrames = decoder.Frames.Count; for (int i = 0; i < totFrames; ++i) { // Create bitmap to hold the single frame System.Drawing.Bitmap bmpSingleFrame = BitmapFromSource(decoder.Frames[i]); // add the frame (as a bitmap) to the bitmap list bmpLst.Add(bmpSingleFrame); } } 

这是BitmapFromSource帮助方法:

 public static Bitmap BitmapFromSource(BitmapSource bitmapsource) { Bitmap bitmap; using (var outStream = new MemoryStream()) { BitmapEncoder enc = new BmpBitmapEncoder(); enc.Frames.Add(BitmapFrame.Create(bitmapsource)); enc.Save(outStream); bitmap = new Bitmap(outStream); } return bitmap; } 

有关此变通办法的更多信息,我还建议阅读我写的这篇博客文章 。