Search code examples
c#asp.netimagetifffilehandler

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. 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). 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.

  • Source Code (using a 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
    

Solution

  • I'm guessing that you'll have to loop over each frame in the TIFF.

    Here's an excerpt from Split multi page tiff file:

    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.