Convert bitmaps to one multipage TIFF image in .NE

2019-01-04 07:55发布

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.

6条回答
闹够了就滚
2楼-- · 2019-01-04 07:57

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;
        }
    }
}
查看更多
唯我独甜
3楼-- · 2019-01-04 08:10

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);
        }
    }   
查看更多
萌系小妹纸
4楼-- · 2019-01-04 08:17

Not being a fan of Microsoft's track record when it comes to handling and creating files of standardized formats, I would suggest using ImageMagick, available as a .Net library in the form of MagickNet (beware, http://midimick.com/magicknet/ currently has a spyware popup, I have alerted the site owner).

查看更多
男人必须洒脱
5楼-- · 2019-01-04 08:19

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:

ImageCodecInfo encoderInfo = GetEncoderInfo("image/tiff");

EncoderParameters encoderParams = new EncoderParameters(2);
EncoderParameter parameter = new EncoderParameter(
    Encoder.Compression, (long)EncoderValue.CompressionCCITT4);
encoderParams.Param[0] = parameter;
parameter = new EncoderParameter(Encoder.SaveFlag, 
    (long)EncoderValue.MultiFrame);
encoderParams.Param[1] = parameter;

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

查看更多
狗以群分
6楼-- · 2019-01-04 08:19

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);
查看更多
可以哭但决不认输i
7楼-- · 2019-01-04 08:20

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


}
查看更多
登录 后发表回答