You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将多页TIFF图像保存至MemoryStream?

多页TIFF保存到MemoryStream仅生成第一页的问题解决

问题根源分析

你的代码存在几个关键错误:

  1. 冗余且错误的流初始化:先将单页TIFF写入byteStream再读取为Image对象,这个tiff对象本身是单页的,后续SaveAdd操作无法正确追加帧到目标流。
  2. EncoderParameters参数不匹配:flushParams构造时指定长度为1,但参数数组里包含了flushParam和lastPageParam两个参数,导致参数无效,无法正确完成多帧写入的收尾。
  3. 流位置未重置:写完tiffStream后未将流的Position重置到开头,直接调用Image.FromStream只能读取到空或不完整的内容。

修正后的代码

public void Test()
{
    // Add 3 image files to the cache list
    List<Image> imageCache = new List<Image>();
    imageCache.Add(Image.FromFile(@"c:\test\testInput1.tif"));
    imageCache.Add(Image.FromFile(@"c:\test\testInput2.tif"));
    imageCache.Add(Image.FromFile(@"c:\test\testInput3.tif"));

    // Get the tiff image codec
    ImageCodecInfo codec = ImageCodecInfo.GetImageEncoders().Where(c => c.MimeType == "image/tiff").First();
    if (codec == null)
        throw new Exception("Tiff codec not found.");

    // Create compression encoder parameter
    EncoderParameter compressionParam = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionCCITT4);

    // Create first page frame parameter
    EncoderParameter firstFrameParam = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.MultiFrame);

    // Create additional pages frame parameter
    EncoderParameter additionalFramesParam = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.FrameDimensionPage);

    // Create color depth parameter
    EncoderParameter colorDepthParam = new EncoderParameter(Encoder.ColorDepth, (long)1);

    // Create last frame + flush parameter
    EncoderParameter lastFrameFlushParam = new EncoderParameter(Encoder.SaveFlag, (long)(EncoderValue.LastFrame | EncoderValue.Flush));

    // Create first page encoder parameters
    EncoderParameters firstFrameParams = new EncoderParameters(2)
    {
        Param = new EncoderParameter[]
        {
            compressionParam,
            firstFrameParam,
        }
    };

    // Create additional pages encoder parameters
    EncoderParameters additionalFrameParams = new EncoderParameters(2)
    {
        Param = new EncoderParameter[]
        {
            compressionParam,
            additionalFramesParam,
        }
    };

    // Create save to file encoder parameters
    EncoderParameters saveToFileParams = new EncoderParameters(2)
    {
        Param = new EncoderParameter[]
        {
            compressionParam,
            colorDepthParam,
        }
    };

    // Create final flush encoder parameters (修正长度为1,因为合并了LastFrame和Flush)
    EncoderParameters flushParams = new EncoderParameters(1)
    {
        Param = new EncoderParameter[]
        {
            lastFrameFlushParam
        }
    };

    using (MemoryStream tiffStream = new MemoryStream())
    {
        // 直接使用第一页图像启动多帧保存
        Image firstPage = imageCache[0];
        firstPage.Save(tiffStream, codec, firstFrameParams);

        // 追加后续页面
        for (int page = 1; page < imageCache.Count; page++)
        {
            firstPage.SaveAdd(imageCache[page], additionalFrameParams);
        }

        // 完成多帧写入并刷新
        firstPage.SaveAdd(flushParams);

        // 重置流位置到开头,确保能完整读取
        tiffStream.Position = 0;

        // 将MemoryStream中的多页TIFF保存到文件
        using (Image tiffOutput = Image.FromStream(tiffStream))
        {
            tiffOutput.Save(@"c:\test\testOutput.tif", codec, saveToFileParams);
        }
    }

    // 释放图像资源(避免内存泄漏)
    foreach (Image img in imageCache)
    {
        img.Dispose();
    }
}

关键修正点

  • 去掉了冗余的byteStream步骤,直接使用第一页图像初始化多帧保存流程,确保SaveAdd能正确追加帧到目标MemoryStream。
  • 将LastFrame和Flush合并为一个EncoderParameter,修正flushParams的参数长度匹配问题。
  • 在读取tiffStream前重置Position为0,保证能读取到完整的多页TIFF数据。
  • 添加了图像资源的释放逻辑,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Arvo Bowen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:11:00