简体   繁体   English

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

[英]C#: How do I convert a multi-page TIFF via MemoryStream into one long image?

So I have been able to take a multi-page TIFF file and convert it to a single jpeg image but it flattens the TIFF. 因此,我已经能够提取多页TIFF文件并将其转换为单个jpeg图像,但它会使TIFF变平。 By flatten it, I mean it only returns the first page. 展平它是指它仅返回第一页。 The goal is to retrieve the TIFF (via memory stream), open each page of the TIFF and append it to a new jpeg (or any web image). 目标是检索TIFF(通过内存流),打开TIFF的每个页面,并将其附加到新的jpeg(或任何Web图像)上。 Thus creating one long image to view on the web without the aid of a plugin. 因此,无需借助插件即可创建一个长图像以在网络上查看。 I do have the MODI.dll installed but I am not sure how to use it in this instance but it is an option. 我确实安装了MODI.dll,但不确定在这种情况下如何使用它,但这是一个选择。

  • Source Code (using a FileHandler): 源代码(使用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 

I'm guessing that you'll have to loop over each frame in the TIFF. 我猜您将不得不遍历TIFF中的每个帧。

Here's an excerpt from Split multi page tiff file : 这是拆分多页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); 
            } 
        } 
    } 

You should be able to adapt the logic above to append onto your JPG rather than create separate files. 您应该能够调整上述逻辑以附加到JPG上,而不是创建单独的文件。

In case you get the dreadful "A generic error occurred in GDI+" error (which is arguably the Rickroll of all errors) when using the SelectActiveFrame method suggested in the other answers, I strongly suggest to use the System.Windows.Media.Imaging.TiffBitmapDecoder class instead (you will need to add a Reference to the PresentationCore.dll framework library). 如果使用其他答案中建议的SelectActiveFrame方法时遇到可怕的“ GDI +中发生一般性错误”错误(可以说是所有错误的Rickroll),强烈建议使用System.Windows.Media.Imaging.TiffBitmapDecoder类(您将需要添加对PresentationCore.dll框架库的引用 )。

Here's an example code that does just that (it puts all the TIFF frames into a list of standard Bitmaps): 这是一个示例代码,它就是这样做的(它将所有TIFF帧放入标准位图列表中):

List<System.Drawing.Bitmap> bmpLst = new List<System.Drawing.Bitmap>();

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);
    }
}

And here's the BitmapFromSource helper method: 这是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;
}

For further info regarding this workaround, I also suggest to read this blog post I wrote. 有关此变通办法的更多信息,我也建议阅读我写的这篇博客文章

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在不安装任何exe的情况下将多页PDF文件转换为多页Tiff - How to Convert Multi-Page PDF files to Multi-Page Tiff with out installing any exe 将多个多页 tiff 图像合并到单个 tiff C# - Merge multiple multi-page tiff images to a single tiff C# CoSign API:如何通过C#SAPI启用多页签名? - CoSign API: How can I enable Multi-Page signing through the C# SAPI? c#datagridview多页打印 - c# datagridview multi-page print 如何定义一个表面上实现为静态只读字段的对象? (使用iText 7将多页TIFF转换为PDF) - How to define an object apparently implemented as a static read-only field? (Using iText 7 to convert multi-page TIFF to PDF) 如何使用C#仅将第一页从Multipage Blob .Tiff图像转换和显示为.Jpeg - How to Convert and display only the first page from Multipage Blob .Tiff image to .Jpeg using C# 如何将MemoryStream从Google Drive获取请求转换为XML文件C#? - How do I convert the MemoryStream from a Google Drive Get request to an XML File C#? C#iTextsharp替换多页PDF的页面 - C# iTextsharp Replace Page of a multi-page PDF 如何在C#中将TIFF图像添加到另一个图像的底部? - How to add a TIFF image to the bottom of another one in C#? C#如何将MessageBodyStream转换为MemoryStream? - C# How to convert MessageBodyStream to MemoryStream?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM