OCG - layers , replacing image

267 views
Skip to first unread message

Lars Eirik Rønning

unread,
May 5, 2008, 10:35:07 AM5/5/08
to pdfne...@googlegroups.com
Hi.
I would like to be able to replace image or graphics on a given layer.
Is this possible with your product?

It is important that i am able to replace the old item with a new one.
I have full control over the input pdf thus i know its structure and that no item is used in more than one layer.(ocg)

The problem i have sofar is that i am not able to easily retrieve which layer the element belongs to.
I have found the /Xobject with its OC in the page's contentstream, but this is not easy to parse.

I hope you are able to provivde me with an example or som help on my way!

Thanks.
Lars Eirik

Support

unread,
May 5, 2008, 6:17:33 PM5/5/08
to PDFTron PDFNet SDK
In case you are creating PDF layers as illustrated in PDFLayers sample
project (http://www.pdftron.com/net/samplecode.html#PDFLayers) you can
use the following approach to identify the layer to which the content
belongs.

- When you encounter Form XObject, you can obtain for dictionary using
element.GetXObject().
- If the dictionary contains OC entry, the form content is part of
some optional content group/layer.
- For simple groups you can obtain the layer name using
group.GetName().

// C# pseudocode (JAVA or C++ cose is essentially the same)

string cur_layer_name;

void ProcessElements(ElementReader reader) {
Element element;
while ((element = reader.Next()) != null) {
switch (element.GetType()) {
case Element.Type.e_path:
break;
case Element.Type.e_text:
break;
case Element.Type.e_form: {
Obj xobject = element.GetXObject();
Obj oc = xobject.FindObj("OC");
if (oc != null) {
// Check if this is OC Membership dictionary or OCG
pdftron.PDF.OCG.OCMD md = new pdftron.PDF.OCG.OCMD(oc);
if (md.IsValid()) {
// cur_layer_name = traverse the array of OCGs using
md.GetOCGs();
}
else {
pdftron.PDF.OCG.Group grp = new pdftron.PDF.OCG.Group(oc);
if (grp.IsValid()) {
cur_layer_name = grp.GetName();
}
}
}

reader.FormBegin();
ProcessElements(reader);
reader.End();
break;
}
}
}
}

Support

unread,
May 6, 2008, 3:17:41 PM5/6/08
to PDFTron PDFNet SDK
Thanks for helping.
I will try this tomorrow.
There is a problem at the moment as the pdf does not have and will not
have the OC entry since i am not sure how this is added.
We will depend on desginers who use Illustrator and export to pdf.
This pdf will be opened and the replacement will be made.
As i wrote in my initial question the only way to retrieve the actual
layer being used is via the page contents stream.
If you have any other ideas on how this can best me solved i am eager
to hear!

Thanks
Lars Ronning

Support

unread,
May 6, 2008, 3:23:51 PM5/6/08
to PDFTron PDFNet SDK
In this case you are probably dealing with PDF documents with non-
standard OCGs/layers. In case you are processing Illustrator documents
you may want to inspect 'marked content' elements:
e_marked_content_begin and e_marked_content_end. This marked content
is not part of PDF spec (and may require some reverse engineering on
your end), however you may be able to extract lots of useful
information about the structure of the document.

For example:

string _current_tag;

if (element.GetType() == Element.Type.e_marked_content_begin) {
// This element marks the beginning of marked content sequence (i.e.
BMC or BDC operator).
Obj mc_tag = element.GetMCTag();
if (mc_tag != null) {
_current_tag = mc_tag.GetName();
}

Obj mc_prop = element.GetMCPropertyDict ();
if (mc_prop != null) {
// Traverse the marked content properties dictionary...
// or use mc_prop.Find("Key") to search for specific key/value
pairs
DictIterator itr = mc_prop.GetDictIterator();
while (itr.HasNext()) {
Obj key = itr.Key();
// Console.WriteLine("{0}", key.GetName()); // Key
Obj value = itr.Value();
// ...
itr.Next()
}
}
}
else if (element.GetType() == Element.Type.e_marked_content_end)
// marks the end of marked content sequence (EMC) } ...

Reply all
Reply to author
Forward
0 new messages