How can I get the names of all Layers / OCGs on a particular page?

Question:

How can I get the names of all Layers / OCGs on a particular page?

Answer:

C# code:

`

///


/// Shows how to parse OCGs associated with a page / finds all OCGs associated with individual pages
///

private static Dictionary<int, Dictionary<string, string>> ParseLayers(string inputFilePath)
{
Dictionary<int, Dictionary<string, string>> pageLayers = new Dictionary<int, Dictionary<string, string>>();

using (PDFDoc document = new PDFDoc(inputFilePath))
{
document.InitSecurityHandler();

using (PageIterator pageIterator = document.GetPageIterator())
{
for (; pageIterator.HasNext(); pageIterator.Next())
{
Page page = pageIterator.Current();
int pageID = page.GetIndex();
var layers = new Dictionary<string, string>();
pageLayers.Add(pageID, layers);

var resources = page.GetResourceDict();
ParseResources(resources, layers);
}
}
}

return pageLayers;
}

private static void ParseResources(Obj resources, Dictionary<string, string> layers)
{
if (resources == null) return;

var properties = resources.FindObj(“Properties”);

if (properties != null)
{
ParseProperties(properties, layers);
}

var xobject = resources.FindObj(“XObject”);
if(xobject != null && xobject.IsDict())
{
for (DictIterator xobjectIterator = xobject.GetDictIterator(); xobjectIterator.HasNext(); xobjectIterator.Next())
{
var o = xobjectIterator.Value();
if (!o.IsDict() && !o.IsStream()) continue;
var subResources = o.FindObj(“Resources”);
ParseResources(subResources, layers);
}
}
}

private static void ParseProperties(Obj properties, Dictionary<string, string> layers)
{
for (DictIterator propertyIterator = properties.GetDictIterator(); propertyIterator.HasNext(); propertyIterator.Next())
{
var type = propertyIterator.Value().FindObj(“Type”);

if ((type == null) || (!type.IsName()))
{
continue;
}

string typeName = type.GetName();

// found a layer
if (typeName == “OCG”)
{
Obj ocName = propertyIterator.Value().FindObj(“Name”);

if ((ocName == null) || (!ocName.IsString()))
{
continue;
}

string nameOfLayer = ocName.GetAsPDFText();
string mcid = propertyIterator.Key().GetName();

// adds the layer information as key value pair to the dictionary
if (!layers.ContainsKey(mcid))
{
layers.Add(mcid, nameOfLayer);
}
}
}
}
`

Below is updated C# code to also parse Annotations on a page that might be part of a layer too.

`
///


/// Shows how to parse OCGs associated with a page / finds all OCGs associated with individual pages
///

private static Dictionary<int, Dictionary<string, string>> ParseLayers(string inputFilePath)
{
Dictionary<int, Dictionary<string, string>> pageLayers = new Dictionary<int, Dictionary<string, string>>();

using (PDFDoc document = new PDFDoc(inputFilePath))
{
document.InitSecurityHandler();

using (PageIterator pageIterator = document.GetPageIterator())
{
for (; pageIterator.HasNext(); pageIterator.Next())
{
Page page = pageIterator.Current();
int pageID = page.GetIndex();
var layers = new Dictionary<string, string>();
pageLayers.Add(pageID, layers);

var resources = page.GetResourceDict();
ParseResources(resources, layers);
ParseAnnotations(page, layers);
}
}
}

return pageLayers;
}

private static void ParseAnnotations(Page page, Dictionary<string, string> layers)
{
int numAnnots = page.GetNumAnnots();
for(int i = 0; i < numAnnots; ++i)
{
Annot annot = page.GetAnnot(i);
if(!annot.IsValid()) continue;
Obj oc = annot.GetOptionalContent();
if (oc == null) continue;
string nameOfLayer = GetName(oc);
layers.Add(String.Format(“Annot {0}”, i), nameOfLayer);
}
}

private static void ParseResources(Obj resources, Dictionary<string, string> layers)
{
if (resources == null) return;

var properties = resources.FindObj(“Properties”);

if (properties != null)
{
ParseProperties(properties, layers);
}

var xobject = resources.FindObj(“XObject”);
if (xobject != null && xobject.IsDict())
{
for (DictIterator xobjectIterator = xobject.GetDictIterator(); xobjectIterator.HasNext(); xobjectIterator.Next())
{
var o = xobjectIterator.Value();
if (!o.IsDict() && !o.IsStream()) continue;
var subResources = o.FindObj(“Resources”);
ParseResources(subResources, layers);
}
}
}

private static bool IsOCG(Obj o)
{
if (o == null) return false;
if (!o.IsDict()) return false;
Obj type = o.FindObj(“Type”);
if (type == null) return false;
if (!type.IsName()) return false;
string typeName = type.GetName();
return typeName.CompareTo(“OCG”) == 0;
}

private static string GetName(Obj o)
{
Obj oName = o.FindObj(“Name”);
if ((oName == null) || (!oName.IsString())) return “”;
return oName.GetAsPDFText();
}

private static void ParseProperties(Obj properties, Dictionary<string, string> layers)
{
for (DictIterator propertyIterator = properties.GetDictIterator(); propertyIterator.HasNext(); propertyIterator.Next())
{
if(!IsOCG(propertyIterator.Value())) continue;

string nameOfLayer = GetName(propertyIterator.Value());
string mcid = propertyIterator.Key().GetName();

// adds the layer information as key value pair to the dictionary
if (!layers.ContainsKey(mcid))
{
layers.Add(mcid, nameOfLayer);
}
}
}
`