/Rotate 烘焙进内容流、页面框和注释矩形,然后将 /Rotate 重置为 0,使可视布局得以保留,而不再依赖旋转显示提示function FlattenPageRotation(
const Options : TPdfFlattenRotationOptions;
out Report : TPdfFlattenRotationReport): Boolean; overload;
function FlattenPageRotation(
const PageNumbers : array of Integer;
const Options : TPdfFlattenRotationOptions;
out Report : TPdfFlattenRotationReport): Boolean; overload;
许多下游工具(较旧的打印管道、图像提取器、OCR 预处理器、光栅转换器)会忽略页面的 /Rotate 条目,以错误的方向渲染已旋转的页面。FlattenPageRotation 将当前旋转的逆变换应用到页面内容、注释矩形和页面框,然后将 /Rotate 设为 0。调用之后,可见页面与旋转后的原始页面完全一致,但不再依赖阅读器应用旋转提示
单参数重载处理每个页面;PageNumbers 重载接受一个从零开始的数组,调用方可以只展平一个子集。已经处于 /Rotate=0 的页面会计入 Report.SkippedPageCount 并保持不变
在内部,每个旋转页面先通过 FPDFPage_CountObjects + FPDFPage_GetObject + FPDFPageObj_TransformF 处理内容,再通过 FPDFPage_GetAnnot + FPDFAnnot_GetRect / FPDFAnnot_SetRect 处理注释,然后通过 FPDFPage_SetMediaBox / FPDFPage_SetCropBox 处理页面框,最后用 0 调用 FPDFPage_SetRotation。矩阵由 FPDFPage_GetMediaBox 返回的未旋转 MediaBox 推导
PageNumbers — 要处理的从零开始的页面索引。传入空数组(或使用单参数重载)以展平每个页面Options — TPdfFlattenRotationOptions,包含 TransformAnnotations、TransformPageBoxes 和 AutoUpdate。Default 转换注释、交换页面框,并在每个旋转页面之后调用 UpdatePageReport — TPdfFlattenRotationReport,包含 ProcessedPageCount、SkippedPageCount、FailedPageCount、TotalObjectsTransformed 和 TotalAnnotationsTransformed,以及 Succeeded 和 ErrorMessage[0, 1, -1, 0, H, 0],180° 使用 [-1, 0, 0, -1, W, H],270° 使用 [0, -1, 1, 0, 0, W],其中 W 和 H 是未旋转的 MediaBox 尺寸TransformPageBoxes=False 禁用left <= right / bottom <= top 不变量PageNumber 会在调用前后保存和恢复,因此调用方可以安全地继续在先前活动的页面上工作/Rotate=0 的页面会被跳过并计入 Report.SkippedPageCount;全部跳过的运行仍返回 True,因为没有发生任何失败
var
Options: TPdfFlattenRotationOptions;
Report: TPdfFlattenRotationReport;
begin
Pdf1.FileName := 'C:\Scanned.pdf';
Pdf1.Active := True;
Options := TPdfFlattenRotationOptions.Default;
Pdf1.FlattenPageRotation(Options, Report);
Pdf1.SaveAs('C:\Scanned_flat.pdf');
end;