我是PDFNet SDK的新手,仍然在尝试拼凑一些PDF功能是如何工作的。我对SDK的广度和深度印象深刻,但我试图理解SDK如何与层(又名可选内容组或ocg)一起工作。特别是,我试图确定如何检测哪些层是不可见的(OFF),以便它们和它们的内容可以从PDF中删除。我最初关注的是pdftron.PDF.OCG名称空间中的类,尤其是Group类。这允许我迭代组并获得基本信息,如名称和当前状态(ON/OFF),如下面的代码片段所示:
Config init_cfg = doc.GetOCGConfig();
Context ctx = new Context(init_cfg);
Obj ocgs = doc.GetOCGs(); // Get the array of all OCGs in the document.
if (ocgs != null)
{
int i, sz = ocgs.Size();
for (i = 0; i < sz; ++i)
{
Group ocg = new Group(ocgs.GetAt(i));
bool ocgState = ocg.GetCurrentState(ctx); // check if ocg is OFF or ON
if (!ocgState) // layer is not visible
{
// need calls here to delete layer and content
}
}
}
到目前为止,一切顺利。但是,我没有看到任何方法可以删除这些类中的层和相关内容。我错过什么了吗?如果没有,在SDK中是否有其他方法来完成删除层?
提前感谢!
好了,在对SDK示例进行了更多的研究和大量的实验之后,我找到了一种方法,到目前为止我已经尝试过的pdf有效。解决方案是基于ElementEdit示例,再加上Context.SetNonOCDrawing()、Context.SetOCDrawMode()和Element.IsOCVisible()方法,根据层的on/OFF状态忽略不可见的页面元素。最终的结果是删除了关闭的图层的内容,图层本身仍然留下,但现在是空的。不完美,但对我来说已经足够了。无论如何,以下是我基于SDK示例编写的代码:
private void ProcessElements(ElementReader reader, ElementWriter writer, XSet visited)
{
Element element;
while ((element = reader.Next()) != null) // Read page contents
{
switch (element.GetType())
{
//always write these element types (visible or non-visible)
case Element.Type.e_marked_content_begin:
case Element.Type.e_marked_content_end:
case Element.Type.e_marked_content_point:
case Element.Type.e_group_begin:
case Element.Type.e_group_end:
writer.WriteElement(element);
continue;
}
// do not retain other elements that are not visible
if (!element.IsOCVisible())
continue;
// retain remaining element types if visible
switch (element.GetType())
{
// special processing for form elements
case Element.Type.e_form:
{
writer.WriteElement(element); // write Form XObject reference to current stream
Obj form_obj = element.GetXObject();
if (!visited.Contains(form_obj.GetObjNum())) // if this XObject has not been processed
{
// recursively process the Form XObject
visited.Add(form_obj.GetObjNum());
ElementWriter new_writer = new ElementWriter();
reader.FormBegin();
new_writer.Begin(form_obj, true);
ProcessElements(reader, new_writer, visited);
new_writer.End();
reader.End();
}
break;
}
default:
writer.WriteElement(element);
break;
}
}
}
private void RemoveNonVisibleLayers_Click(string filename, string outputfile)
{
PDFNet.Initialize();
try
{
// Open the test file
XSet visited = new XSet();
using (PDFDoc doc = new PDFDoc(filename))
using (ElementReader page_reader = new ElementReader())
using (ElementWriter writer = new ElementWriter())
{
doc.InitSecurityHandler();
Config init_cfg = doc.GetOCGConfig();
Context ctx = new Context(init_cfg);
ctx.SetNonOCDrawing(false);
ctx.SetOCDrawMode(Context.OCDrawMode.e_VisibleOC);
PageIterator itr;
for (itr = doc.GetPageIterator(); itr.HasNext(); itr.Next()) // Read every page
{
itr.GetPageNumber());
page_reader.Begin(itr.Current(), ctx);
writer.Begin(itr.Current(), ElementWriter.WriteMode.e_replacement, false);
ProcessElements(page_reader, writer, visited);
writer.End();
page_reader.End();
}
doc.Save(outputfile, SDFDoc.SaveOptions.e_remove_unused);
doc.Close();
}
}
catch (PDFNetException ee)
{
Console.WriteLine(ee.Message);
}
}