Convert bitmaps to one multipage TIFF image in .NET 2.0

后端 未结 7 1938
有刺的猬
有刺的猬 2020-11-27 11:29

How can i convert an array of bitmaps into a brand new image of TIFF format, adding all the bitmaps as frames in this new tiff image?

using .NET 2.0.

相关标签:
7条回答
  • helpful topic. thanks for the info. I had a need to stitch a multipage image from an array of base64 encoded strings. This is what i put together based on the information in this thread. I dont quite underststand why i have to create a memory stream with the image format specified explicitly but this is what ended up working, if there is a better way to deal with this please let me know. thanks

    /// <summary>
        /// Takes in an array of base64 encoded strings and creates a multipage tiff.
        /// </summary>
        /// <param name="sOutFile">file to be generated</param>
        /// <param name="pagesbase64Array"></param>
        private void SaevAsMultiPageTiff(string sOutFile, string[] pagesbase64Array)
        {
            System.Drawing.Imaging.Encoder encoder = System.Drawing.Imaging.Encoder.SaveFlag;
            ImageCodecInfo encoderInfo = ImageCodecInfo.GetImageEncoders().First(i => i.MimeType == "image/tiff");
            EncoderParameters encoderParameters = new EncoderParameters(1);
            encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.MultiFrame);
    
            Bitmap firstImage = null;
            try
            {
    
                using (MemoryStream ms1 = new MemoryStream())
                {
                    using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(pagesbase64Array[0])))
                    {
                        Image.FromStream(ms).Save(ms1, ImageFormat.Tiff);
                        firstImage = (Bitmap)Image.FromStream(ms1);
                    }
                    // Save the first frame of the multi page tiff
                    firstImage.Save(sOutFile, encoderInfo, encoderParameters); //throws Generic GDI+ error if the memory streams are not open when this is called
                }
    
    
                encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.FrameDimensionPage);
    
                Bitmap imagePage;
                // Add the remining images to the tiff
                for (int i = 1; i < pagesbase64Array.Length; i++)
                {
    
                    using (MemoryStream ms1 = new MemoryStream())
                    {
                        using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(pagesbase64Array[i])))
                        {
                            Image.FromStream(ms).Save(ms1, ImageFormat.Tiff);
                            imagePage = (Bitmap)Image.FromStream(ms1);
                        }
    
                        firstImage.SaveAdd(imagePage, encoderParameters); //throws Generic GDI+ error if the memory streams are not open when this is called
                    }
                }
    
            }
            catch (Exception)
            {
                //ensure the errors are not missed while allowing for flush in finally block so files dont get locked up.
                throw;
            }
            finally
            {
                // Close out the file
                encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.Flush);
                firstImage.SaveAdd(encoderParameters);
            }
        }   
    
    0 讨论(0)
  • 2020-11-27 12:01

    Came across this post after a bit of searching on Google. I tried the code that was in the post by a'b'c'd'e'f'g'h', but that didn't work for me. Perhaps, I was not doing something correctly.

    In any case, I found another post that saved images to multi page tiffs. Here is the link to the post: http://www.bobpowell.net/addframes.htm

    Also, here is the code that worked for me. It should be identical to that post.

    Encoder encoder = Encoder.SaveFlag;
    ImageCodecInfo encoderInfo = ImageCodecInfo.GetImageEncoders().First(i => i.MimeType == "image/tiff");
    EncoderParameters encoderParameters = new EncoderParameters(1);
    encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.MultiFrame);
    
    // Save the first frame of the multi page tiff
    Bitmap firstImage = (Bitmap) _scannedPages[0].RawContent;
    firstImage.Save(fileName, encoderInfo, encoderParameters);
    
    encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.FrameDimensionPage);
    
    // Add the remaining images to the tiff
    for (int i = 1; i < _scannedPages.Count; i++)
    {
       Bitmap img = (Bitmap) _scannedPages[i].RawContent;
       firstImage.SaveAdd(img, encoderParameters);
    }
    
    // Close out the file
    encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.Flush);
    firstImage.SaveAdd(encoderParameters);
    
    0 讨论(0)
  • 2020-11-27 12:02

    Necromancing
    The accepted answer is a bit vague.
    Here's full working code:

    public class MultiPageTiff
    {
    
    
        private static System.Drawing.Imaging.ImageCodecInfo GetEncoderInfo(string mimeType)
        {
            System.Drawing.Imaging.ImageCodecInfo[] encoders =
                System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
    
            if (encoders != null)
            {
                for (int i = 0; i < encoders.Length; i++)
                {
                    if (encoders[i].MimeType == mimeType)
                    {
                        return encoders[i];
                    } // End if (encoders[i].MimeType == mimeType) 
                } // Next i 
    
            } // End if (encoders != null) 
    
            return null;
        } // End Function GetEncoderInfo 
    
    
        public static System.Drawing.Image Generate(string[] filez)
        {
            System.Drawing.Image multiPageFile = null;
            byte[] ba = null;
    
    
            System.Drawing.Imaging.ImageCodecInfo tiffCodec = GetEncoderInfo("image/tiff");
    
    
            using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
            {
                for (int i = 0; i < filez.Length; ++i)
                {
                    using (System.Drawing.Image inputImage = System.Drawing.Image.FromFile(filez[i]))
                    {
    
                        using (System.IO.MemoryStream byteStream = new System.IO.MemoryStream())
                        {
                            inputImage.Save(byteStream, System.Drawing.Imaging.ImageFormat.Tiff);
    
                            if (i == 0)
                            {
                                multiPageFile = System.Drawing.Image.FromStream(byteStream);
                                multiPageFile = SaveImages(tiffCodec, ms, multiPageFile, null);
                            }
                            else
                            {
    
                                using (System.Drawing.Image tiffImage = System.Drawing.Image.FromStream(byteStream))
                                {
                                    multiPageFile = SaveImages(tiffCodec, ms, tiffImage, multiPageFile);
                                } // End Using tiffImage 
    
                            }
                        } // End Using byteStream 
    
                    } // End Using inputImage 
    
                } // Next i 
    
                ba = ms.ToArray();
            } // End Using ms 
    
            System.IO.File.WriteAllBytes(@"d:\mytiff.tiff", ba);
    
            //if (multiPageFile != null)
            //{
            //    multiPageFile.Dispose();
            //    multiPageFile = null;
            //}
    
            return multiPageFile;
        }
    
    
        private static System.Drawing.Image SaveImages(
              System.Drawing.Imaging.ImageCodecInfo tiffCodec
            , System.IO.MemoryStream outputStream
            , System.Drawing.Image tiffImage, System.Drawing.Image firstImage)
        {
    
    
            using (System.Drawing.Imaging.EncoderParameters encParameters =
                  new System.Drawing.Imaging.EncoderParameters(3))
            {
    
                if (firstImage == null)
                {
                    encParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(
                        System.Drawing.Imaging.Encoder.SaveFlag
                        , (long)System.Drawing.Imaging.EncoderValue.MultiFrame // 18L 
                    );
                }
                else
                {
                    encParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(
                        System.Drawing.Imaging.Encoder.SaveFlag
                        , (long)System.Drawing.Imaging.EncoderValue.FrameDimensionPage // 23L
                    );
                }
    
                encParameters.Param[1] = new System.Drawing.Imaging.EncoderParameter(
                    System.Drawing.Imaging.Encoder.ColorDepth, 24L
                );
    
    
                encParameters.Param[2] = new System.Drawing.Imaging.EncoderParameter(
                    System.Drawing.Imaging.Encoder.Compression
                    , (long)System.Drawing.Imaging.EncoderValue.CompressionLZW
                );
    
    
                if (firstImage == null)
                {
                    firstImage = tiffImage;
    
                    ((System.Drawing.Bitmap)tiffImage).SetResolution(96, 96);
                    firstImage.Save(outputStream, tiffCodec, encParameters);
                }
                else
                {
                    ((System.Drawing.Bitmap)tiffImage).SetResolution(96, 96);
    
                    firstImage.SaveAdd(tiffImage, encParameters);
                }
    
                if (encParameters.Param[0] != null)
                    encParameters.Param[0].Dispose();
    
                if (encParameters.Param[1] != null)
                    encParameters.Param[1].Dispose();
    
                if (encParameters.Param[2] != null)
                    encParameters.Param[2].Dispose();
    
            } // End Using encParameters 
    
            return firstImage;
        }
    
    
    }
    
    0 讨论(0)
  • 2020-11-27 12:06

    Here is the split operation of multi-tiff file. It works just like string substring function. The first index of image will be your MasterBitMap and you will keep adding frame to the MasterBitmap till the end of index.

    public void SaveMultiFrameTiff(int start, int end)
        {            
            string outputFileName = "out.TIF";  
            string inputFileName = "input.TIF";            
    
            try
            {                
    
                Bitmap MasterBitmap = new Bitmap(inputFileName ); //Start page of document(master)
                Image imageAdd = Image.FromFile(inputFileName );  //Frame Image that will be added to the master          
                Guid guid = imageAdd.FrameDimensionsList[0]; //GUID
                FrameDimension dimension = new FrameDimension(guid);
                // start index cannot be less than 0 and cannot be greater than frame count        
                if (start < 1 || end > MasterBitmap.GetFrameCount(dimension)) { return; }        
    
                EncoderParameters ep = new EncoderParameters(1);
    
                //Get Image Codec Information
                ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
                ImageCodecInfo codecInfo = codecs[3]; //image/tiff
    
                //MultiFrame Encoding format
                EncoderParameter epMultiFrame = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
                ep.Param[0] = epMultiFrame;
                MasterBitmap.SelectActiveFrame(dimension, start - 1);
                MasterBitmap.Save(outputFileName, codecInfo, ep);//create master document
    
                //FrameDimensionPage Encoding format
                EncoderParameter epFrameDimensionPage = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.FrameDimensionPage);
                ep.Param[0] = epFrameDimensionPage;
    
                for (int i = start; i < end; i++)
                {
                    imageAdd.SelectActiveFrame(dimension, i);//select next frame
                    MasterBitmap.SaveAdd(new Bitmap(imageAdd), ep);//add it to the master
                }
    
                //Flush Encoding format
                EncoderParameter epFlush = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.Flush);
                ep.Param[0] = epFlush;
                MasterBitmap.SaveAdd(ep); //flush the file                   
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-27 12:16

    Start with the first bitmap by putting it into an Image object

    Bitmap bitmap = (Bitmap)Image.FromFile(file);
    

    Save the bitmap to memory as tiff

    MemoryStream byteStream = new MemoryStream();
    bitmap.Save(byteStream, ImageFormat.Tiff);
    

    Put Tiff into another Image object

    Image tiff = Image.FromStream(byteStream)
    

    Prepare encoders:

    var encoderInfo = ImageCodecInfo.GetImageEncoders().First(i => i.MimeType == "image/tiff");
    
    EncoderParameters encoderParams = new EncoderParameters(2);
    encoderParams.Param[0] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionNone);
    encoderParams.Param[1] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
    

    Save to file:

    tiff.Save(sOutFilePath, encoderInfo, encoderParams);
    

    For subsequent pages, prepare encoders:

    EncoderParameters EncoderParams = new EncoderParameters(2);
    EncoderParameter SaveEncodeParam = new EncoderParameter(
         Encoder.SaveFlag, 
         (long)EncoderValue.FrameDimensionPage);
    EncoderParameter CompressionEncodeParam = new EncoderParameter(
         Encoder.Compression, (long)EncoderValue.CompressionNone);
    EncoderParams.Param[0] = CompressionEncodeParam;
    EncoderParams.Param[1] = SaveEncodeParam;
    tiff.SaveAdd(/* next image as tiff - do the same as above with memory */, EncoderParams);
    

    Finally flush the file:

    EncoderParameter SaveEncodeParam = new EncoderParameter(
         Encoder.SaveFlag, (long)EncoderValue.Flush);
    EncoderParams = new EncoderParameters(1);
    EncoderParams.Param[0] = SaveEncodeParam;
    tiff.SaveAdd(EncoderParams);
    

    That should get you started.

    0 讨论(0)
  • 2020-11-27 12:19

    Here is how to do this in vb.net:

    Imports System.Drawing.Imaging
    
    Sub CreateTiff(sOutTiffFile As String, sInFile1 As String, sInFile2 As String)
        Dim bitmap As Bitmap = Image.FromFile(sInFile1)
        Dim byteStream As MemoryStream = New MemoryStream()
        bitmap.Save(byteStream, System.Drawing.Imaging.ImageFormat.Tiff)
    
        Dim tiff As Image = Image.FromStream(byteStream)
    
        Dim oParams As EncoderParameters = New EncoderParameters(2)
        oParams.Param(0) = New EncoderParameter(Imaging.Encoder.Compression, EncoderValue.CompressionCCITT4)
        oParams.Param(1) = New EncoderParameter(Imaging.Encoder.SaveFlag, EncoderValue.MultiFrame)
        tiff.Save(sOutTiffFile, GetEncoderInfo("image/tiff"), oParams)
    
        'Next Page
        Dim bitmap2 As Bitmap = Image.FromFile(sInFile2)
        oParams.Param(1) = New EncoderParameter(Imaging.Encoder.SaveFlag, EncoderValue.FrameDimensionPage)
        tiff.SaveAdd(bitmap2, oParams)
    
        'Flush 
        Dim oFlushParams As EncoderParameters = New EncoderParameters(1)
        oFlushParams.Param(0) = New EncoderParameter(Imaging.Encoder.SaveFlag, EncoderValue.Flush)
        tiff.SaveAdd(oFlushParams)
    End Sub
    
    Private Function GetEncoderInfo(mimeType As String) As System.Drawing.Imaging.ImageCodecInfo
        Dim encoders = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()
        For i As Integer = 0 To encoders.Length - 1
            If encoders(i).MimeType = mimeType Then
                Return encoders(i)
            End If
        Next
        Return Nothing
    End Function
    
    0 讨论(0)
提交回复
热议问题