How to change the order of Optional Content Groups?

I have a PDF file with a hierarchy of layers (aka OCG). Using the following code snippet


var ocProps = reader.Catalog.GetAsDict(PdfName.OCPROPERTIES);
var occd = ocProps.GetAsDict(PdfName.D);
var order = occd.GetAsArray(PdfName.ORDER);
I can query the current order from the source file. But I have no idea how to modify this data in order to copy it into a new file with the following snippet.


var reader = new PdfReader(input);
var document = new Document(reader.GetPageSizeWithRotation(1));
var pdfCopyProvider = new PdfCopy(document,
    new System.IO.FileStream(output, System.IO.FileMode.Create));
// TBD do OCG modification ...
var importedPage = pdfCopyProvider.GetImportedPage(reader, 1);
Nonetheless, the OCG information is copied to the new PDF file by default.

Any hint on this is welcome.

Posted on StackOverflow on Apr 24, 2014 by Holger

You're already very close to the solution. See the ChangeOCGOrder example to find out how to change ocg.pdf into ocg_reordered.pdf.

You already had something like this:

PdfDictionary catalog = reader.getCatalog();
PdfDictionary ocProps = catalog.getAsDict(PdfName.OCPROPERTIES);
PdfDictionary occd = ocProps.getAsDict(PdfName.D);
PdfArray order = occd.getAsArray(PdfName.ORDER);

This is good: you're looking at the right place!

Now you need something like this:

PdfObject nestedLayers = order.getPdfObject(0);
PdfObject nestedLayerArray = order.getPdfObject(1);
PdfObject groupedLayers = order.getPdfObject(2);
PdfObject radiogroup = order.getPdfObject(3);
order.set(0, radiogroup);
order.set(1, nestedLayers);
order.set(2, nestedLayerArray);
order.set(3, groupedLayers);

In my example, the ORDER array contains 4 elements. I get these four elements, and I change the order of the entries in the original array.

Note that I could also have done something like:


That would have the same effect as the 8 lines of code above, but the 8 lines help you understand the mechanism.

Thanks, that works! In addition to your answer, I publish the C# version of the manipulatePdf method:

public void ManipulatePdf(string source, string destination) {
    var reader = new PdfReader(source);
    var ocProps = reader.Catalog.GetAsDict(PdfName.OCPROPERTIES);
    var occd = ocProps.GetAsDict(PdfName.D);
    var order = occd.GetAsArray(PdfName.ORDER);

    var nestedLayers = (PdfObject)order[0];
    var nestedLayerArray = (PdfObject)order[1];
    var groupedLayers = (PdfObject)order[2];
    var radiogroup = (PdfObject)order[3];

    order[0] = radiogroup;
    order[1] = nestedLayers;
    order[2] = nestedLayerArray;
    order[3] = groupedLayers;

    var stamper = new PdfStamper(reader, new System.IO.FileStream(destination, System.IO.FileMode.Create));

Ready to use iText?

Try our iText 7 Library and add-ons FREE for 30 days. Test your proof of concept, and see if our solution is right for you.

Get my FREE trial

Still have questions? 

We're happy to answer your questions. Reach out to us and we'll get back to you shortly.

Contact us
Stay updated

Join 11,000+ subscribers and become an iText PDF expert by staying up to date with our new products, updates, tips, technical solutions and happenings.

Subscribe Now