使用 C# 将 TIFF 转换为 PDF

在 .NET 应用开发中,TIFF 转 PDF 是一个常见的文档处理需求。TIFF 格式在扫描归档、传真传输和医学影像等领域广泛使用,但跨平台查看和分享的便利性不如PDF。本文介绍如何使用免费 .NET 库在 C# 中实现 TIFF 到 PDF 的转换。

环境准备

通过 NuGet 安装免费库 Free Spire.PDF:

复制代码
Install-Package FreeSpire.PDF

或使用.NET CLI:

csharp 复制代码
dotnet add package FreeSpire.PDF

单页TIFF转换

单页 TIFF 转换的核心思路是创建与图像尺寸相同的PDF页面,然后将图像绘制到页面中。需要注意移除PDF页面的默认边距,否则图像会被压缩或偏移。

csharp 复制代码
using Spire.Pdf;
using Spire.Pdf.Graphics;
using System.Drawing;

public void ConvertSingleTiffToPdf(string tiffPath, string pdfPath)
{
    // 加载TIFF图像
    PdfImage tiffImage = PdfImage.FromFile(tiffPath);

    // 创建PDF文档
    PdfDocument pdf = new PdfDocument();

    // 移除默认页边距
    pdf.PageSettings.Margins.All = 0;

    // 获取图像原始尺寸
    float width = tiffImage.PhysicalDimension.Width;
    float height = tiffImage.PhysicalDimension.Height;

    // 添加与图像同尺寸的PDF页面
    PdfPageBase page = pdf.Pages.Add(new SizeF(width, height));

    // 将图像绘制到页面,填满整个页面
    page.Canvas.DrawImage(tiffImage, 0, 0, width, height);

    // 保存并关闭
    pdf.SaveToFile(pdfPath);
    pdf.Close();

    // 释放图像资源
    tiffImage.Dispose();
}

这里使用 PhysicalDimension 获取图像的物理尺寸(以点为单位),确保 PDF 页面与 TIFF 尺寸完全匹配,避免缩放导致的画质损失。

多页 TIFF 转换

多页 TIFF 文件在单个文件中包含多个帧,每个帧对应文档中的一页。转换时需要遍历每一帧,为每个帧创建独立的PDF页面。

关键点在于使用 FrameDimension 来识别TIFF中的帧集合,通过 GetFrameCount 获取总帧数,再用 SelectActiveFrame 切换到指定帧。

csharp 复制代码
using Spire.Pdf;
using Spire.Pdf.Graphics;
using System.Drawing;
using System.Drawing.Imaging;

public void ConvertMultiPageTiffToPdf(string tiffPath, string pdfPath)
{
    // 使用System.Drawing.Image加载多页TIFF
    using (Image tiffImage = Image.FromFile(tiffPath))
    {
        // 获取帧维度信息
        FrameDimension dimension = new FrameDimension(
            tiffImage.FrameDimensionsList[0]);
        int frameCount = tiffImage.GetFrameCount(dimension);

        // 创建PDF文档
        PdfDocument pdf = new PdfDocument();
        pdf.PageSettings.Margins.All = 0;

        // 逐帧处理
        for (int i = 0; i < frameCount; i++)
        {
            // 切换到当前帧
            tiffImage.SelectActiveFrame(dimension, i);

            // 将当前帧转为PdfImage
            PdfImage pdfImage = PdfImage.FromImage(tiffImage);

            float width = pdfImage.PhysicalDimension.Width;
            float height = pdfImage.PhysicalDimension.Height;

            // 创建与当前帧尺寸匹配的页面
            PdfPageBase page = pdf.Pages.Add(new SizeF(width, height));
            page.Canvas.DrawImage(pdfImage, 0, 0, width, height);

            // 释放当前帧的图像资源
            pdfImage.Dispose();
        }

        pdf.SaveToFile(pdfPath);
        pdf.Close();
    }
}

每帧转换完成后及时调用 pdfImage.Dispose() 释放资源,这对处理帧数较多的TIFF文件尤为重要。

批量转换与合并

当需要将多个 TIFF 文件转换并合并为一个 PDF 时,可以复用同一个 PdfDocument 对象,将不同TIFF的帧依次添加到同一个文档中。

csharp 复制代码
public void MergeTiffsToOnePdf(string[] tiffPaths, string outputPath)
{
    PdfDocument pdf = new PdfDocument();
    pdf.PageSettings.Margins.All = 0;

    foreach (string tiffPath in tiffPaths)
    {
        using (Image tiffImage = Image.FromFile(tiffPath))
        {
            FrameDimension dimension = new FrameDimension(
                tiffImage.FrameDimensionsList[0]);
            int frameCount = tiffImage.GetFrameCount(dimension);

            for (int i = 0; i < frameCount; i++)
            {
                tiffImage.SelectActiveFrame(dimension, i);
                PdfImage pdfImage = PdfImage.FromImage(tiffImage);

                float width = pdfImage.PhysicalDimension.Width;
                float height = pdfImage.PhysicalDimension.Height;

                PdfPageBase page = pdf.Pages.Add(new SizeF(width, height));
                page.Canvas.DrawImage(pdfImage, 0, 0, width, height);

                pdfImage.Dispose();
            }
        }
    }

    pdf.SaveToFile(outputPath);
    pdf.Close();
}

批量处理时,建议逐个处理 TIFF文 件并在完成后立即释放图像资源,避免同时加载多个大文件导致内存占用过高。

备选方案对比(参考)

  • 原生 System.Drawing:只能读取 TIFF 帧,没有 PDF 生成能力,需要自己实现 PDF 写入,开发量大;
  • iTextSharp / PdfSharp:可实现图片插入 PDF,但多页 TIFF 帧读取需要自行处理;
  • Free Spire.PDF:代码量少,开箱即用,代价是免费版 10 页限制。

总结

这套方案适合小批量扫描档案、原型开发,用少量代码即可完成多页 TIFF 到 PDF 的转换。核心要点:遍历 TIFF 帧、逐帧新建 PDF 页面、合理释放资源,同时务必留意免费版本的页数限制。在正式项目上线前,需要针对文档页数、部署环境(Windows/Linux)做充分测试。

相关推荐
全栈项目管理程序猿1 小时前
ArcGIS JS 基础教程(28):图层渲染顺序管理
前端·javascript
huakoh1 小时前
MCP 工具报错走哪条通道:三条探针的最小复现检查
前端
用户033307413951 小时前
ParadeDB 的 pg_search 0.26 把十词 BM25 搜索从 129ms 降到 29ms
前端
不爱说话郭德纲1 小时前
从“点点点”到一键出包:我把 uni-app x Android 离线打包做成了脚本
android·前端·uni-app
Lstone73641 小时前
从 Jetpack Compose 到 CMP:跨平台开发学习笔记
前端
deli0071 小时前
多加一粒沙,整堆为什么就塌了?sandpile 模型 20 万粒实测
前端
涛涛ing1 小时前
乱序HTML流正式进入浏览器:前端流式渲染的“框架特权”被终结了
前端
__sjfzllv___1 小时前
在职前端Leader学习/转行 AI Agent -DAY73
前端
用户1733598075371 小时前
纯前端 PDF 压平避坑指南:压平后表单字段变了?
前端·javascript·vue.js