在.NET 2.0中将位图转换为一个多页TIFF图像

问题描述 投票:41回答:7

如何将一组位图转换为TIFF格式的全新图像,在这个新的tiff图像中添加所有位图作为帧?

使用.NET 2.0。

c# .net .net-2.0 drawing tiff
7个回答
78
投票

从第一个位图开始,将其放入Image对象

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

将位图保存为内存为tiff

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

将Tiff放入另一个Image对象

Image tiff = Image.FromStream(byteStream)

准备编码器:

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

保存到文件:

tiff.Save(sOutFilePath, encoderInfo, encoderParams);

对于后续页面,请准备编码器:

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

最后刷新文件:

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

这应该让你开始。


23
投票

在Google上进行了一些搜索后,发现了这篇文章。我尝试了'b'c'd'e'f'g'h'在帖子中的代码,但这对我不起作用。也许,我没有正确地做某事。

在任何情况下,我发现另一个帖子将图像保存到多页tiffs。这是帖子的链接:http://www.bobpowell.net/addframes.htm

此外,这是适合我的代码。它应该与该帖子相同。

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

4
投票

有用的话题。谢谢(你的)信息。我需要从base64编码的字符串数组中缝合多页图像。这是我根据此主题中的信息放在一起的内容。我不太清楚为什么我必须创建一个具有明确指定的图像格式的内存流,但这是最终工作,如果有更好的方法来处理这个请告诉我。谢谢

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

3
投票

在处理和创建标准化格式的文件时,我不建议使用Microsoft的跟踪记录,我建议使用ImageMagick,以MagickNet的形式提供.Net库(请注意,http://midimick.com/magicknet/目前有一个间谍软件弹出窗口,我已经发出警报网站所有者)。


3
投票

Necromancing 接受的答案有点模糊。 这是完整的工作代码:

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


}

2
投票

这是multi-tiff文件的拆分操作。它就像字符串子串函数一样工作。第一个图像索引将是您的MasterBitMap,您将继续向MasterBitmap添加框架,直到索引结束。

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
投票

以下是如何在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
© www.soinside.com 2019 - 2024. All rights reserved.