I have downloaded pdf file from one site, and on each page there is hyperlink to this site in a rectangle. I want to remove link from every page. I am using PDFBox version 2.0.8
I figured out that link description is located in ANNOTS in every page of the document. I deleted ANOOTS corresponding to link. Of cause I set needToUpdated flag true to every node in the chain from the PDF catalog. In debug mode I see that readOnly flag is set to true in AccessPermission object. When I open edited pdf file all pages are empty and for every page Acrobat Reader shows the following error:
There was an error processing a page. Invalid Function resource.
I have several questions:
- Can I programmatically change the pdf file when readOnly flag is set to true in AccessPermission object?
- Why I get error described above?
- What do I need to do to remove unnecessary link from page and every page display properly in pdf document?
Here is my code(sorry for quality this is only draft):
File book = new File(path_to_pdf_file);
PDDocument document = PDDocument.load(book);
document.setAllSecurityToBeRemoved(true);
COSDictionary dictionary = document.getDocumentCatalog().getCOSObject();
dictionary.removeItem(COSName.PERMS);
dictionary.setNeedToBeUpdated(true);
((COSObject) document.getDocumentCatalog().getCOSObject().getItem(COSName.PAGES)).setNeedToBeUpdated(true);
dictionary = document.getDocumentCatalog().getPages().getCOSObject();
dictionary.setNeedToBeUpdated(true);
COSArray arr = (COSArray) dictionary.getDictionaryObject(COSName.KIDS);
arr.setNeedToBeUpdated(true);
COSArray arrayForLoop;
COSDictionary tempDic;
for (int k = 0; k < arr.size(); ++k) {
COSObject object = (COSObject) arr.get(k);
object.setNeedToBeUpdated(true);
dictionary = (COSDictionary) object.getObject();
dictionary.setNeedToBeUpdated(true);
arrayForLoop = (COSArray) dictionary.getItem(COSName.ANNOTS);
arrayForLoop.setNeedToBeUpdated(true);
arrayForLoop = (COSArray) arrayForLoop.getCOSObject();
arrayForLoop.setNeedToBeUpdated(true);
dictionary = (COSDictionary) arrayForLoop.get(0);
dictionary.setNeedToBeUpdated(true);
dictionary.removeItem(COSName.TYPE);
dictionary.removeItem(COSName.SUBTYPE);
dictionary.removeItem(COSName.RECT);
dictionary.removeItem(COSName.BORDER);
tempDic = (COSDictionary) dictionary.getItem(COSName.A);
tempDic.setNeedToBeUpdated(true);
dictionary.removeItem(COSName.A);
}
document.saveIncremental(new FileOutputStream(path_to_save_file));
document.close();
In code above I iterate over every page, delete ANNOTS that corresponding to link. Also I used saveIncremental method to traverse all modified nodes from leaf to root. Thank you for your answers.