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

84 views
Skip to first unread message

Yasser Khan

unread,
Jan 29, 2019, 8:01:29 PM1/29/19
to pdfne...@googlegroups.com
Question:

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

Answer:

C# code:


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

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);
            }
        }
    }
}


Ryan

unread,
Jan 8, 2020, 7:57:30 PM1/8/20
to PDFTron PDFNet SDK
Below is updated C# code to also parse Annotations on a page that might be part of a layer too.

/// <summary>
/// Shows how to parse OCGs associated with a page / finds all OCGs associated with individual pages
/// </summary>
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());
Reply all
Reply to author
Forward
0 new messages