OFD 优化
本节介绍 OFD 文档优化能力,用于压缩文件体积、清理冗余资源或按策略重编码图像资源。OFD 优化提供两类入口:
- 文件级优化:
foxit::ofd::Optimize的静态方法OfdOptimize、OfdCompress,直接对输入 OFD 文件路径执行优化并输出到新文件,无需先加载OFDDoc。 - 保存时优化:编辑文档后,在
OFDPackage::Save/SaveAs前调用EnableOptimizeResource等开关,请参阅 OFD 文件包。
任务场景
- 调用
Optimize::OfdOptimize对 OFD 文件路径执行一键压缩并输出到新文件。 - 使用
Optimize::OfdCompress配置downsample、compress_level、codec_type等参数进行自定义压缩。 - 通过
float_bit降低坐标浮点精度以减小体积(须评估对排版的影响)。 - 开启
res_optimizer对重复字体、图片等资源去重;保存前可配合OFDPackage::EnableOptimizeResource。
API 概览
| 功能 | C++ API(foxit::ofd) | 核心参数 / 描述 |
|---|---|---|
| 优化类 | Optimize | 静态方法,无需实例化 |
| 一键优化 | Optimize::OfdOptimize | input_ofd_path、output_ofd_path;SDK 内置默认策略 |
| 自定义压缩 | Optimize::OfdCompress | 见下表 OfdCompress 参数 |
| 编码类型 | Optimize::CompressCodecType | e_CompressCodecTypeJPEG2000、e_CompressCodecTypeJPEG |
| 保存时优化 | OFDPackage::EnableOptimizeResource | 包内保存前去重冗余资源;见 OFD 文件包 |
OfdCompress 参数
| 参数 | 类型 | 取值范围 | 说明 |
|---|---|---|---|
input_ofd_path | 路径 | — | 输入 OFD 文件路径 |
output_ofd_path | 路径 | — | 输出 OFD 文件路径(建议与输入路径不同) |
downsample | float | 0.0–1.0 | 正文图像降采样比例。越小分辨率越低、体积越小;1.0 表示不降采样 |
boot_downsample | float | 0.0–1.0 | 引导层(bootstrap)图像降采样比例,通常与 downsample 取相同或略低值 |
compress_level | int | 0–9 | 压缩等级。数值越大压缩越激进、体积越小,图像细节损失越多 |
codec_type | CompressCodecType | e_CompressCodecTypeJPEG2000(0)e_CompressCodecTypeJPEG(1) | 图像重编码格式 |
float_bit | int | 0–8(接口文档) | 坐标等浮点数精度位数。位数越低体积越小,过低可能导致排版错位 |
res_optimizer | bool | true / false | 是否开启资源去重,合并重复字体、图片等资源 |
lzma_compress | bool | true / false | 是否启用 LZMA 压缩(接口参数,见注意事项) |
执行优化
OfdOptimize 与 OfdCompress 均为 文件路径入、文件路径出 的同步调用:传入有效路径后直接执行,返回 true 表示成功。优化完成后可用 OFDPackage 打开输出文件验证页数与内容。路径为空或源文件不存在时将抛出参数/文件异常。
一键优化(OfdOptimize)
适用于大多数场景的快速压缩:无需配置参数,SDK 按内置策略清理冗余并优化资源。
c++
#include "ofd/fs_ofdoptimize.h"
#include "ofd/fs_ofdpackage.h"
#include "ofd/fs_ofddoc.h"
using namespace foxit;
using namespace foxit::ofd;
bool OptimizeOFDFile(const wchar_t* input_file, const wchar_t* output_file) {
if (!Optimize::OfdOptimize(WString(input_file), WString(output_file))) {
return false;
}
OFDPackage package(output_file);
if (package.IsEmpty() || package.GetDocumentCount() <= 0) {
return false;
}
OFDDoc doc = package.LoadDocument(0, L"");
return !doc.IsEmpty() && doc.GetPageCount() > 0;
}
java
import com.foxit.sdk.ofd.OFDDoc;
import com.foxit.sdk.ofd.OFDPackage;
import com.foxit.sdk.ofd.Optimize;
public class OFDOptimizeExample {
public static boolean optimizeOFDFile(String inputFile, String outputFile) throws Exception {
if (!Optimize.ofdOptimize(inputFile, outputFile)) {
return false;
}
OFDPackage pkg = new OFDPackage(outputFile);
if (pkg.isEmpty() || pkg.getDocumentCount() <= 0) {
return false;
}
OFDDoc doc = pkg.loadDocument(0, null);
return !doc.isEmpty() && doc.getPageCount() > 0;
}
}
自定义压缩(OfdCompress)
适用于需要精细控制压缩比的场景。以下示例采用偏平衡的参数组合(与 SDK 单测常用值接近):图像降采样 0.8、压缩等级 5、JPEG2000 编码、浮点精度 5 位,并开启资源去重。
c++
#include "ofd/fs_ofdoptimize.h"
using namespace foxit;
using namespace foxit::ofd;
bool CompressOFDFile(const wchar_t* input_file, const wchar_t* output_file) {
float downsample = 0.8f;
float boot_downsample = 0.8f;
int compress_level = 5;
Optimize::CompressCodecType codec_type = Optimize::e_CompressCodecTypeJPEG2000;
int float_bit = 5;
bool res_optimizer = true;
bool lzma_compress = false;
return Optimize::OfdCompress(
WString(input_file), WString(output_file),
downsample, boot_downsample, compress_level,
codec_type, float_bit, res_optimizer, lzma_compress);
}
java
import com.foxit.sdk.ofd.Optimize;
public class OFDCompressExample {
public static boolean compressOFDFile(String inputFile, String outputFile) throws Exception {
float downsample = 0.8f;
float bootDownsample = 0.8f;
int compressLevel = 5;
int codecType = Optimize.e_CompressCodecTypeJPEG2000;
int floatBit = 5;
boolean resOptimizer = true;
boolean lzmaCompress = false;
return Optimize.ofdCompress(
inputFile, outputFile,
downsample, bootDownsample, compressLevel,
codecType, floatBit, resOptimizer, lzmaCompress);
}
}
参数取值建议
| 参数 | 文档特征 / 目标 | 建议取值 |
|---|---|---|
downsample / boot_downsample | 图像资源占比高,需显著减小体积 | 0.5–0.7;可进一步降至 0.3–0.5 |
downsample / boot_downsample | 以矢量与文字为主,需保留清晰度 | 0.8–1.0 |
compress_level | 常规压缩,兼顾体积与画质 | 3–5 |
compress_level | 极限压缩、可接受更多画质损失 | 6–9 |
codec_type | 图文混排、追求更高压缩率 | e_CompressCodecTypeJPEG2000 |
codec_type | 下游解码器对 JPEG2000 支持不确定 | e_CompressCodecTypeJPEG |
float_bit | 正式排版、打印输出 | 5–8 |
float_bit | 可接受坐标精度损失(如仅出图检视) | 3–4 |
res_optimizer | 多页重复 logo、字体等资源 | true |
res_optimizer | 追求最快处理速度、资源本就精简 | false |
lzma_compress | 进一步压缩包内流数据(CPU 开销更高) | 按需开启;见注意事项 |
注意事项
- 备份原文件:优化会重写资源与内部文件布局,输出路径应使用新文件,操作前请备份原始 OFD。
- 与编辑流程的区别:
OfdOptimize/OfdCompress不经过OFDDoc编辑链路;若已在内存中修改文档,应使用OFDPackage::Save/SaveAs并配合EnableOptimizeResource,而非重复调用文件级优化。 - 页数一致性:正常优化不应改变文档页数;优化后建议打开输出文件核对
GetPageCount与关键页面内容。 - 画质与体积的权衡:降低
downsample/boot_downsample或提高compress_level会显著减小体积,但可能损失图像细节;float_bit过低可能导致坐标精度不足,引发排版错位或元素偏移。正式交付前请在目标阅读器上抽检。 - 编码格式选择:JPEG2000(
e_CompressCodecTypeJPEG2000)通常在同画质下体积更小,适合图文混排;JPEG(e_CompressCodecTypeJPEG)兼容性更广,适合下游系统对 JPEG2000 解码支持不确定的场景。 - 性能提示:
OfdCompress涉及图像重编码与资源去重,大文件或高compress_level时 CPU 与 I/O 耗时明显;res_optimizer开启时会扫描并合并重复资源,进一步增加处理时间。建议在后台线程执行,并向用户展示进度。 - LZMA 参数:接口提供
lzma_compress开关以控制是否启用 LZMA 压缩;若开启后体积变化不明显,请对照当前 SDK 版本的实际行为。 - 参数合法性:
downsample、boot_downsample须在0.0–1.0之间;compress_level须在0–9之间;codec_type仅支持e_CompressCodecTypeJPEG2000与e_CompressCodecTypeJPEG;非法参数将抛出e_ErrParam异常。