Annotation Flattener
AnnotationFlattener burns annotation appearances into the page content stream and removes the annotation objects, producing a static PDF. This is useful for locking down filled forms, finalizing review markup, or preparing documents for print.
Opening a PDF
Section titled “Opening a PDF”use Phpdftk\Pdf\Toolkit\AnnotationFlattener;
// From file$flattener = AnnotationFlattener::open('form.pdf');
// From string$flattener = AnnotationFlattener::openString($pdfBytes);
// Encrypted PDF$flattener = AnnotationFlattener::open('secured.pdf', password: 'secret');Flatten all annotations
Section titled “Flatten all annotations”$flattener->flattenAll()->save('flat.pdf');Restrict to specific pages:
use Phpdftk\Pdf\Toolkit\PageSelector;
$flattener->flattenAll(PageSelector::pages(1, 2))->save('flat.pdf');Flatten by annotation type
Section titled “Flatten by annotation type”Flatten only specific annotation subtypes (PDF /Subtype values):
$flattener->flattenType('FreeText', 'Stamp')->save('flat.pdf');Flatten forms only
Section titled “Flatten forms only”A convenience method that flattens only Widget annotations (form fields):
$flattener->flattenForms()->save('flat-form.pdf');
// On specific pages$flattener->flattenForms(PageSelector::range(1, 3))->save('flat-form.pdf');How it works
Section titled “How it works”For each annotation targeted for flattening:
- The annotation’s normal appearance stream (
/AP /N) is located - The appearance is positioned using the annotation’s
/Rectand the appearance’s/BBox - A transformation matrix maps the appearance BBox to the annotation Rect
- The appearance is invoked as an XObject (
Dooperator) in a new content stream appended to the page - The annotation is removed from the page’s
/Annotsarray
Annotations without an appearance stream are left unchanged.
Chaining and saving
Section titled “Chaining and saving”AnnotationFlattener::open('reviewed.pdf') ->flattenType('Highlight', 'StrikeOut') ->flattenForms() ->save('finalized.pdf');$bytes = $flattener->toBytes();Document info
Section titled “Document info”$flattener->getPageCount(); // intEscape hatch
Section titled “Escape hatch”$reader = $flattener->getReader(); // PdfReader