Hello,
I've got a use case where I need to combine multiple PDFs into one while resizing all to be the same page size. Most sample code seems to do one or the other and I'm wondering if what I'd like to do is even possible.
So given an array of documents paths, I've been able to combine them using the following code:
std::string destinationFile = params[1];
PDFWriter pdfWriter;
PDFPageRange pageRange;
PDFParser parser;
InputFile pdfFile;
EStatusCode status = PDFHummus::eSuccess;
Php::out << "Creating " << destinationFile << std::endl;
pdfWriter.StartPDF("/tmp/file.pdf",ePDFVersion17);
for (auto &iter : params[0]) {
if (file_exists(iter.second.stringValue())) {
pdfWriter.AppendPDFPagesFromPDF(iter.second.stringValue(), pageRange);
Php::out << "\tWith: " << iter.second.stringValue() << std::endl;
} else {
Php::out << "\t " << iter.second.stringValue() << " doesn't exist!" << std::endl;
return false;
}
}
pdfWriter.EndPDF();
In #29 there is a link to some code about the ModifyingExistingFileContent test. However I'm having trouble understanding everything it is doing. When I add it to my particular use case (I modify the PDF I just combined from multiple sources). I can get different page sizes, however its basically just cropping the page, not resizing the content at all.
So a few questions:
- Is what I want to do possible?
- Do I need to open use a PDFWriter instance more than once? Or can I get all source pages and combine it manually while resizing the pages?
Below is the code after the code above that re-opens the modified file and re-writes the mediaBox size. Like I said it resizes the page, but not the content within it...
pdfWriter.ModifyPDF(params[1], ePDFVersion17, destinationFile);
status = pdfFile.OpenFile("/tmp/file.pdf");
status = parser.StartPDFParsing(pdfFile.GetInputStream());
if (status != PDFHummus::eSuccess) {
Php::out << "unable to parse input file" << std::endl;
} else {
Php::out << "Pages: " << parser.GetPagesCount() << std::endl;
}
PDFDocumentCopyingContext* copyingContext = NULL;
for (long unsigned int x = 0; x < parser.GetPagesCount(); x++) {
// Change 3rd page bbox to landscape by modifying the page object
copyingContext = pdfWriter.CreatePDFCopyingContextForModifiedFile();
if (!copyingContext) {
Php::out << "failed to create copying context for modified file" << std::endl;
status = eFailure;
return nullptr;
}
// create a new object for the page, copy all but media box, which will be changed
ObjectIDType pageId = copyingContext->GetSourceDocumentParser()->GetPageObjectID(x);
PDFObjectCastPtr<PDFDictionary> pageObj = copyingContext->GetSourceDocumentParser()->ParsePage(x);
MapIterator<PDFNameToPDFObjectMap> pageObjIt = pageObj->GetIterator();
pdfWriter.GetObjectsContext().StartModifiedIndirectObject(pageId);
DictionaryContext* modifiedPageObject = pdfWriter.GetObjectsContext().StartDictionary();
while (pageObjIt.MoveNext()) {
if (pageObjIt.GetKey()->GetValue() != "MediaBox") {
modifiedPageObject->WriteKey(pageObjIt.GetKey()->GetValue());
copyingContext->CopyDirectObjectAsIs(pageObjIt.GetValue());
}
}
// write new media box
modifiedPageObject->WriteKey("MediaBox");
pdfWriter.GetObjectsContext().StartArray();
pdfWriter.GetObjectsContext().WriteInteger(0);
pdfWriter.GetObjectsContext().WriteInteger(0);
pdfWriter.GetObjectsContext().WriteInteger(500);
pdfWriter.GetObjectsContext().WriteInteger(500);
pdfWriter.GetObjectsContext().EndArray();
pdfWriter.GetObjectsContext().EndLine();
pdfWriter.GetObjectsContext().EndDictionary(modifiedPageObject);
pdfWriter.GetObjectsContext().EndIndirectObject();
// cleanup
delete copyingContext;
}