PDF processing
Correct images embedded in PDF files
The PDF samples demonstrate how to extract images from PDF files, apply corrections, embed the corrected image back into the PDF, and save the modified PDF. This is useful for photo books, or any PDF containing images that would benefit from enhancement. This requires that the PDF content is "layered" - saved with the images as separate objects rather than flattened into a single layer. The sample uses the PFCPDFImageIterator class to access and modify images within the PDF structure.
Key functions
A summary of key functions and purposes:
| Function | Purpose |
|---|---|
PFCPDFImageIterator::load | Open a PDF file for processing |
PFCPDFImageIterator::nextImage | Get the next image from the PDF |
PFCPDFImageIterator::save | Write the modified PDF to disk |
PFCPDFImage::imageFile | Access the image data for correction |
C/C++ implementation
The following excerpts are from PDF_Sample.cpp.
Load the PDF file
Open the PDF file using the iterator. The load function returns a status code indicating success or failure.
#include "PFCPDFImageIterator.h"
#include "PFCPDFImage.h"
PFCPDFImageIterator file;
// Open the PDF file
if (file.load(inputPath) != PFCPDFImageIterator::LoadStatus::Ok) {
printf("Cannot load PDF: %s\n", inputPath);
return 1;
}Iterate and correct images
Loop through all images in the PDF using nextImage(). Each call returns a PFCPDFImage object containing the unpacked image data that you can correct like any other image.
// Create correction engine
PFCENGINE *pEngine = PFC_CreateEngine();
PFC_LoadAIEngine(pEngine,
AI_SCENE_DETECTION | AI_CORRECTIONS | AI_COLOR | AI_FACEMESH,
binPath.c_str());
// Process each image in the PDF
while (PFCPDFImage* pdfImage = file.nextImage()) {
// Access the image data
PFCImageFile* imgFile = pdfImage->imageFile;
// Set up PFCIMAGE struct
PFCIMAGE im;
im.width = imgFile->width;
im.height = imgFile->height;
im.stride = imgFile->stride;
im.format = (PFCPIXELFORMAT)imgFile->pfcImageFormat();
im.data = imgFile->raw_image;
//setup Engine and apply auto corrections
PFCENGINE* pEngine = PFC_CreateEngine();
// Load AI engine (assuming all dlls and models are in exe folder):
std::string exePath = std::string(argv[0]);
std::string binPath = exePath.substr(0, exePath.find_last_of('/')).c_str();
int aistatus = PFC_LoadAIEngine(pAiEngine, AI_SCENE_DETECTION | AI_CORRECTIONS | AI_COLOR | AI_FACEMESH, binPath.c_str());
// We set params within AutoCorrect(), so this can start out empty.
PFCPARAM ignoredParam;
int result = PFC_AutoCorrect(&image, NULL, ignoredParam, -1, NULL, false, NULL, pEngine, false);
printf("Image corrected with status: %d\n", result);
// Release profile (image data is modified in place)
PFC_ReleaseProfile(pProfile);
}
PFC_DestroyEngine(pEngine);Save the modified PDF
After processing all images, save the PDF with the corrected images embedded.
if (file.save(outputPath) != PFCPDFImageIterator::SaveStatus::Ok) {
printf("Cannot save PDF: %s\n", outputPath);
return 1;
}Complete workflow
The full workflow loads, processes, and saves in sequence.
// 1. Load PDF
PFCPDFImageIterator file;
file.load("input.pdf");
// 2. Set up correction engine
// Create correction engine
PFCENGINE *pEngine = PFC_CreateEngine();
PFC_LoadAIEngine(pEngine,
AI_SCENE_DETECTION | AI_CORRECTIONS | AI_COLOR | AI_FACEMESH,
binPath.c_str());
// 3. Process each image in the PDF
while (PFCPDFImage* pdfImage = file.nextImage()) {
// Access the image data
PFCImageFile* imgFile = pdfImage->imageFile;
// Set up PFCIMAGE struct
PFCIMAGE im;
im.width = imgFile->width;
im.height = imgFile->height;
im.stride = imgFile->stride;
im.format = (PFCPIXELFORMAT)imgFile->pfcImageFormat();
im.data = imgFile->raw_image;
//setup Engine and apply auto corrections
PFCENGINE* pEngine = PFC_CreateEngine();
// Load AI engine (assuming all dlls and models are in exe folder):
std::string exePath = std::string(argv[0]);
std::string binPath = exePath.substr(0, exePath.find_last_of('/')).c_str();
int aistatus = PFC_LoadAIEngine(pAiEngine, AI_SCENE_DETECTION | AI_CORRECTIONS | AI_COLOR | AI_FACEMESH, binPath.c_str());
// We set params within AutoCorrect(), so this can start out empty.
PFCPARAM ignoredParam;
int result = PFC_AutoCorrect(&image, NULL, ignoredParam, -1, NULL, false, NULL, pEngine, false);
printf("Image corrected with status: %d\n", result);
// Release profile (image data is modified in place)
PFC_ReleaseProfile(pProfile);
}
PFC_DestroyEngine(pEngine);
file.save("output.pdf");Important notes
The nextImage() function returns images one at a time. When you call nextImage() again, the previous image's memory may be reused. Process each image completely before moving to the next.
The corrections are applied in place to the image data. When you call save(), the PDF is written with all the corrected images.
Source files
You can find the code snippets in the following files:
| Platform | Sample | Path |
|---|---|---|
| Linux/macOS | PDFSample | Linux/PDFSample/PDF_Sample.cpp |
| Windows | PDFSample | Win/PDFSample/PDFSample.cpp |
PDF processing requires the PFCPDF library (libPFCPDF.so on Linux, PFCPDF.dll on Windows). Make sure this library is available in your build environment.
PFC-SDK Version 10.7.3.1317 built from df9dbc8727c92fb9b1d2c68b21e60ea9c7229e1a on 03-23-2026.
Copyright © 2026 EyeQ Imaging Inc. All rights reserved.