
在 C++ 中将图像转换为 OFD(Open Fixed-layout Document)格式,是文档处理系统中的常见需求。尤其在中国,OFD 已成为官方文档归档、交换和分发的重要标准格式。在实际开发过程中,开发人员往往需要将扫描文档或图片文件转换为 OFD 文档,以便统一存储、归档,或集成到电子文档管理系统和自动化工作流程中。
如果从底层自行实现图像到 OFD 的转换,通常需要处理图像格式解析、页面尺寸设置以及文档结构构建等复杂细节,同时还要确保生成的文件符合 OFD 规范。借助 Spire.PDF for C++,开发人员可以通过简洁的 API 快速实现图像到 OFD 的转换。该库支持 PNG、JPG、BMP、TIFF 和 EMF 等常见图像格式,并自动处理文档结构和渲染过程。
本文将介绍如何在 C++ 中实现图像转换为 OFD 文档,并提供单图像转换、多图像生成多页 OFD 以及批量转换等实用示例。
快速导航
- 了解图像到 OFD 转换
- 准备工作
- 在 C++ 中将单个图像转换为 OFD
- 在 C++ 中将多个图像转换为多页 OFD
- 将图像适配到固定页面大小
- 批量将单个图像转换为单个 OFD
- 常见问题与注意事项
- 常见问题解答
1. 了解图像到 OFD 转换
OFD 是一种基于 XML 的固定版式文档格式,其功能与 PDF 类似,但在字符集支持和政府文档标准方面针对中文环境进行了优化。
将图像转换为 OFD,本质上是创建一个符合 OFD 规范的文档结构,并将图像内容嵌入到文档页面中。
图像转 OFD 的常见应用场景包括:
- 将扫描发票或收据进行数字化归档
- 构建统一的电子文档存储系统
- 搭建自动化文档处理流程
- 将传统图像文档转换为标准化电子文档
在实际实现中,通常的处理流程是:创建文档对象,将图像绘制到页面上,然后按照 OFD 规范导出为 OFD 文件。
2. 准备工作
在 C++ 中实现图像到 OFD 的转换之前,需要先安装并配置 Spire.PDF for C++。
通过 NuGet 安装(推荐)
将 Spire.PDF 添加到 C++ 项目的最简单方式是使用 NuGet,它会自动下载库文件并配置相关依赖。
安装步骤如下:
- 在 Visual Studio 中打开项目
- 在 解决方案资源管理器 中右键单击 引用
- 选择 管理 NuGet 程序包
- 搜索 Spire.PDF.Cpp
- 点击 安装
安装完成后,可以在代码中引入该库:
#include "Spire.Pdf.o.h"
手动安装
您也可以 下载 Spire.PDF for C++,然后通过配置 include 和 lib 目录手动将其集成到项目中。
详细说明请参考:
如何在 C++ 应用程序中集成 Spire.PDF for C++
3. 在 C++ 中将单个图像转换为 OFD
下面的示例演示如何将单个图像文件转换为 OFD 文档。代码首先创建一个 PDF 文档对象,然后加载图像并将其绘制到页面上,最后将文档保存为 OFD 格式。
#include "Spire.Pdf.o.h"
using namespace Spire::Pdf;
int main()
{
// 创建新的 PDF 文档
PdfDocument* ofd = new PdfDocument();
// 加载图像文件
auto image = PdfImage::FromFile(L"Sample.jpg");
// 根据图像尺寸计算页面大小
float pageWidth = image->GetWidth();
float pageHeight = image->GetHeight();
// 添加与图像尺寸匹配的页面
auto page = ofd->GetPages()->Add(new SizeF(pageWidth, pageHeight));
// 在页面上绘制图像
page->GetCanvas()->DrawImage(image, 0, 0, pageWidth, pageHeight);
// 保存为 OFD 文件
ofd->SaveToFile(L"ImageToOfd.ofd", FileFormat::OFD);
// 释放资源
delete ofd;
return 0;
}
以下截图展示了由源图像生成的 OFD 文档效果。

核心类与方法
PdfDocument 表示文档对象,用于创建页面并导出最终的 OFD 文件。
PdfImage::FromFile() 从指定路径加载图像文件,并创建可绘制到页面上的图像对象。
PdfDocument::GetPages()->Add() 向文档中添加新页面。本示例根据图像尺寸动态设置页面大小。
PdfCanvas::DrawImage() 将图像绘制到页面画布的指定位置和尺寸。
SaveToFile() 将文档保存到磁盘,并使用 FileFormat::OFD 指定输出格式为 OFD。
这种方式可以确保图像在 OFD 页面中以正确比例显示,从而保持原始图像质量。
移除页面边距(可选)
默认情况下,文档页面可能包含边距,这会导致图像周围出现空白区域。如果希望图像完全填充页面,可以将页面边距设置为 0:
ofd->GetPageSettings()->SetMargins(0.0);
如果需要保留一定留白,也可以自定义边距:
ofd->GetPageSettings()->SetMargins(10.0);
合理设置边距有助于控制页面布局效果。
注意:如果代码运行时出现 C++ 版本兼容性问题,可通过如下方式解决:
- 方法一:在 项目属性 → C/C++ → 预处理器 → 预处理器定义 中添加
_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING - 方法二:在 项目属性 → 配置属性 → 常规 中,将 C++ 语言标准 设置为
ISO C++14 标准 (/std:c++14)
4. 在 C++ 中将多个图像转换为多页 OFD
在文档归档或批量处理场景中,通常需要将多张图像合并到同一个 OFD 文件中。下面的示例展示了如何创建一个多页 OFD 文档,并在每个页面中放置一张不同的图像。
代码会遍历图像文件列表,为每张图像创建独立页面,并根据图像尺寸设置页面大小,然后将图像绘制到对应页面中。
#include "Spire.Pdf.o.h"
#include <vector>
#include <filesystem>
#include <algorithm>
using namespace Spire::Pdf;
namespace fs = std::filesystem;
int main()
{
// 创建新的 PDF 文档(用于保存为 OFD)
PdfDocument* ofd = new PdfDocument();
// 指定图片文件夹
std::wstring folderPath = L"./images";
// 遍历文件夹
for (const auto& entry : fs::directory_iterator(folderPath))
{
if (!entry.is_regular_file())
continue;
std::wstring path = entry.path().wstring();
std::wstring ext = entry.path().extension().wstring();
// 转为小写方便比较
std::transform(ext.begin(), ext.end(), ext.begin(), ::towlower);
// 判断是否为支持的图片格式
if (ext == L".png" || ext == L".jpg" || ext == L".jpeg" || ext == L".bmp")
{
// 加载图片
auto image = PdfImage::FromFile(path.c_str());
// 获取图片尺寸
float pageWidth = image->GetWidth();
float pageHeight = image->GetHeight();
// 创建页面
auto page = ofd->GetPages()->Add(new SizeF(pageWidth, pageHeight));
// 绘制图片
page->GetCanvas()->DrawImage(image, 0, 0, pageWidth, pageHeight);
}
}
// 保存为 OFD
ofd->SaveToFile(L"multi_page_document.ofd", FileFormat::OFD);
delete ofd;
return 0;
}
以下截图展示了生成的多页 OFD 文档,每张图像分别置于独立页面。

此实现遍历图像文件集合,为每张图像创建独立页面,并以恰当的尺寸绘制内容。生成的 OFD 文档在单一文件中保留所有源图像的顺序和版式。
注意: #include <filesystem> 仅在 C++ 17 及以上的 C++ 标准下可用。
如果需要对已经转换出的 OFD 文档进行合并操作,请参考 如何使用 C++ 合并 OFD/PDF 文档。
5. 将图像适配到固定页面大小
在许多实际文档工作流中,页面通常需要遵循 标准页面尺寸,而不是直接使用图像原始尺寸。例如,扫描的合同、表格或报告往往需要统一为 A4 或 Letter 等标准页面格式。
要实现这一点,可以先创建具有固定尺寸的页面,然后按照比例缩放图像,使其在不变形的情况下适应页面范围。
下面的示例演示了如何在保持纵横比的前提下,将图像缩放并适配到固定页面大小。
#define NOMINMAX
#include "Spire.Pdf.o.h"
#include <algorithm>
using namespace Spire::Pdf;
int main()
{
// 创建新的 PDF 文档
PdfDocument* ofd = new PdfDocument();
// 添加固定尺寸的页面(如 A4)
PdfPageBase* page = ofd->GetPages()->Add(PdfPageSize::A4);
// 加载图像
auto image = PdfImage::FromFile(L"Sample.jpg");
// 获取页面尺寸
float pageWidth = page->GetCanvas()->GetClientSize().GetWidth();
float pageHeight = page->GetCanvas()->GetClientSize().GetHeight();
// 获取图像尺寸
float imgWidth = image->GetWidth();
float imgHeight = image->GetHeight();
// 计算等比缩放比例
float scale = std::min(pageWidth / imgWidth, pageHeight / imgHeight);
float scaledWidth = imgWidth * scale;
float scaledHeight = imgHeight * scale;
// 在页面上绘制缩放后的图像
page->GetCanvas()->DrawImage(image, 0, 0, scaledWidth, scaledHeight);
// 保存为 OFD
ofd->SaveToFile(L"FixedPageSize.ofd", FileFormat::OFD);
delete ofd;
return 0;
}
以下截图展示了图像如何缩放以适应固定页面尺寸(A4),同时保持其纵横比。

这种方法确保不同尺寸的图像可以统一放置在标准化文档版式中,同时保持原始比例,避免图像变形。相同技术也可应用于从多张图像生成多页 OFD 文档的场景。
6. 批量将单个图像转换为单个 OFD
在自动化文档处理系统中,往往需要将大量图像文件批量转换为 OFD 文档。为了提高代码复用性,可以将转换逻辑封装为独立函数,并通过循环处理多个文件。
下面的示例演示了一种简单的批量处理实现方式,同时包含基本的错误处理和进度输出。
#include "Spire.Pdf.o.h"
#include <vector>
#include <iostream>
#include <filesystem>
#include <algorithm>
using namespace Spire::Pdf;
namespace fs = std::filesystem;
void ConvertImageToOFD(const std::wstring& inputPath, const std::wstring& outputPath)
{
// 创建新的 PDF 文档(用于生成 OFD)
PdfDocument* ofd = new PdfDocument();
try
{
// 加载图像文件
auto image = PdfImage::FromFile(inputPath.c_str());
// 计算页面尺寸(与图像尺寸保持一致)
float pageWidth = image->GetWidth();
float pageHeight = image->GetHeight();
// 添加与图像尺寸匹配的页面
auto page = ofd->GetPages()->Add(new SizeF(pageWidth, pageHeight));
// 在页面上绘制图像
page->GetCanvas()->DrawImage(image, 0, 0, pageWidth, pageHeight);
// 保存为 OFD
ofd->SaveToFile(outputPath.c_str(), FileFormat::OFD);
std::wcout << L"已转换:" << inputPath << L" -> " << outputPath << std::endl;
}
catch (const std::exception& ex)
{
std::wcout << L"转换 " << inputPath << L" 时出错:" << ex.what() << std::endl;
}
// 清理文档
delete ofd;
}
int main()
{
// 定义要遍历的图片文件夹
std::wstring folderPath = L"./images";
// 遍历文件夹中的所有文件,并自动执行转换
for (const auto& entry : fs::directory_iterator(folderPath))
{
// 仅处理普通文件
if (!entry.is_regular_file())
continue;
fs::path filePath = entry.path();
std::wstring ext = filePath.extension().wstring();
// 将扩展名转换为小写以便统一比较
std::transform(ext.begin(), ext.end(), ext.begin(), ::towlower);
// 判断是否为支持的图像格式
if (ext == L".png" || ext == L".jpg" || ext == L".jpeg" || ext == L".bmp")
{
// 获取输入图像路径
std::wstring inputPath = filePath.wstring();
// 生成对应的 OFD 输出路径(与图像同名)
fs::path outputPath = filePath.parent_path() / (filePath.stem().wstring() + L".ofd");
// 执行转换
ConvertImageToOFD(inputPath, outputPath.wstring());
}
}
std::wcout << L"批量转换完成。" << std::endl;
return 0;
}
这种批处理方式提供:
- 可复用的模块化转换函数
- 针对单个文件失败的错误处理机制
- 便于监控的进度输出
- 清晰的资源管理
该实现独立处理每张图像,确保单个失败不会中断整个批量操作。
7. 注意事项
图像文件路径问题
确保图像文件路径正确且可访问。加载图像时建议使用绝对路径或验证工作目录:
// 为提高可靠性,使用绝对路径
auto image = PdfImage::FromFile(L"C:\\Documents\\scanned_invoice.png");
内存管理
妥善清理 PdfDocument 和 PdfImage 对象以防止内存泄漏。使用后务必删除动态分配的对象:
delete ofd;
不支持的图像格式
Spire.PDF 支持常见图像格式,包括 PNG、JPEG、BMP、EMF 和 TIFF。请确保输入文件采用受支持的格式。对于不受支持的格式,需先使用图像处理库将其转换为受支持格式。
页面尺寸注意事项
当基于图像尺寸创建页面时,请注意过大的图像可能导致生成的 OFD 文档难以查看或打印。建议对大图像实施尺寸限制或缩放处理:
#define NOMINMAX
#include <algorithm>
// 应用最大页面尺寸限制
const float MAX_WIDTH = 1000.0f;
const float MAX_HEIGHT = 1400.0f;
float pageWidth = std::min(static_cast<float>(image->GetWidth()), MAX_WIDTH);
float pageHeight = std::min(static_cast<float>(image->GetHeight()), MAX_HEIGHT);
文件编码
处理包含中文字符或特殊符号的文件路径时,应使用宽字符串(std::wstring)以确保正确的编码处理,避免文件操作中出现编码问题。
C++ 语言标准
如果在某些环境中遇到编译问题,可尝试在 项目属性 → C/C++ → 预处理器 → 预处理器定义 中添加 _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;也可在 项目属性 → 配置属性 → 常规 中,将 C++ 语言标准 设置为 ISO C++14 标准 (/std:c++14)。
总结
本文介绍了如何使用 Spire.PDF for C++ 将图像转换为 OFD 文档。通过简单的 API 调用,开发人员即可实现单图像转换、多图像生成多页文档以及批量转换等功能。
该技术在扫描文档数字化、电子档案管理以及自动化文档处理流程中具有广泛应用。
除了 OFD 转换外,Spire.PDF for C++ 还提供丰富的 PDF 文档处理能力,包括 PDF 创建、编辑、转换以及多种格式导出等功能。借助该库,开发人员可以高效完成复杂的文档处理任务,同时确保生成文档符合相关行业标准。
如需体验完整功能,可 申请 30 天免费许可证。
8. 常见问题解答
将图像转换为 OFD 是否需要第三方软件?
不需要。Spire.PDF 可以独立完成图像到 OFD 的转换,无需依赖 Adobe Acrobat 或其他外部 PDF 软件。
OFD 转换支持哪些图像格式?
Spire.PDF 支持常见图像格式,包括 PNG、JPEG、BMP、EMF 和 TIFF。
Spire.PDF 是否适用于批量处理?
是的。Spire.PDF 针对服务器环境进行了优化,可以高效处理大量图像转换任务。
转换前可以添加水印或文本吗?
可以。Spire.PDF 允许在页面画布上绘制文本或图片,因此可以在导出为 OFD 前添加水印。
相关教程:
OFD 输出会影响图像质量吗?
不会。转换过程中会保留原始图像的分辨率和质量,页面尺寸也会根据图像大小进行适配。







