Skip to content

PDF 图层 (PDF Layer / Optional Content Groups) ​

福昕 PDF SDK 全面支持 PDF 图层,也称为可选内容组 (Optional Content Groups,简称 OCG)。这项特性允许用户根据需要选择性地显示或隐藏多图层 PDF 文档中不同图层的内容。多图层技术在诸多领域有着广泛的应用,例如 CAD 制图、地图绘制、分层艺术设计以及多语言文档管理等。

图层树与图层节点

在福昕 PDF SDK 中,PDF 图层通过图层节点进行组织和管理。要访问图层信息,开发者首先需要构建一个 PDF LayerTree 对象。随后,通过调用 LayerTree.getRootNode() 方法 (以 Java 开发语言为例),即可获取代表整个图层树结构的根图层节点。开发者可以从该根节点出发,遍历枚举图层树中的所有子节点,从而访问文档中的所有图层。

API 功能

福昕 PDF SDK 提供了丰富的 API,用于执行以下 PDF 图层相关的操作:

  • 获取和设置图层数据
  • 控制不同图层内容的可见性 (查看或隐藏)
  • 设置和修改图层名称
  • 添加和删除图层
  • 编辑现有图层属性

创建一个 PDF 图层 ​

c++
#include "include/common/fs_common.h"
#include "include/pdf/fs_pdfdoc.h"
#include "include/common/fs_render.h"
#include "include/pdf/fs_pdflayer.h"

using namespace foxit;
using namespace pdf;
...
// Assuming PDFDoc doc has been loaded.

LayerTree layertree(doc);
LayerNode root = layertree.GetRootNode();
if (root.IsEmpty()) {
	printf("No layer information!\r\n");
	return ;
}	
...
C
#include "include/fs_basictypes_c.h"
#include "include/fs_common_c.h"
#include "include/fs_pdfdoc_c.h"
#include "include/fs_render_c.h"
#include "include/fs_pdflayer_c.h"

 ...
// Assuming FS_PDFDOC_HANDLE doc has been loaded.

FS_LAYERTREE_HANDLE layertree;
FSDK_LayerTree_Create(doc, &layertree);
FS_LAYERNODE_HANDLE root;
FSDK_LayerTree_GetRootNode(layertree, &root);
FS_BOOL return_value;
FSDK_LayerTree_IsEmpty(layertree, &return_value);
if (return_value) {
printf("No layer information!\r\n");
return ;
}	
...	
java
import static com.foxit.sdk.pdf.LayerTree;
import static com.foxit.sdk.pdf.LayerNode;
...	

LayerTree layertree = new LayerTree(doc);
LayerNode root = layertree.getRootNode();
py
import sys
import site

if sys.version_info.major == 2:
    _PYTHON2_ = True
else:
    _PYTHON2_ = False

if _PYTHON2_:
    #replace with the python2 lib path
    site.addsitedir('../../../')
    from FoxitPDFSDKPython2 import *
else:
    from FoxitPDFSDKPython3 import *
...
# Assuming PDFDoc doc has been loaded.

layertree = LayerTree(doc)
root = layertree.GetRootNode()
if root.IsEmpty():
    print("No layer information!\r\n")
    return
... 
objc
 #include "FSPDFObjC.h"
...

// Assuming FSPDFDoc doc has been loaded.
...

FSLayerTree* layertree = [[FSLayerTree alloc] initWithDocument:doc];
FSLayerNode* root = [layertree getRootNode];
if ([root isEmpty]) {
    return -1;
}
...	
js
const FSDK = require("@fuxinsoft/foxit-pdf-sdk-node");
...
// Assuming PDFDoc doc has been loaded.

let layertree = new FSDK.LayerTree(doc);
let root = layertree.GetRootNode();
if (root.IsEmpty()) {
  console.log("No layer information!\r\n");
  return;
}
... 
csharp
using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
 ...
// Assuming PDFDoc doc has been loaded.

LayerTree layertree = new LayerTree(doc);
LayerNode root = layertree.GetRootNode();
...	
go
import (
. “foxit.com/fsdk”
“fmt”
)
...
# Assuming PDFDoc doc has been loaded.

layertree := NewLayerTree(doc)
root := layertree.GetRootNode()
if root.IsEmpty(){
    fmt.Printf("No layer information!\r\n")
return
}
... 

设置所有图层节点的信息 ​

c++
#include "include/common/fs_common.h"
#include "include/pdf/fs_pdfdoc.h"
#include "include/common/fs_render.h"
#include "include/pdf/fs_pdflayer.h"

using namespace foxit;
using namespace foxit::common;
using foxit::common::Library;
using namespace pdf;
 ...
// Assuming PDFDoc doc has been loaded.

void SetAllLayerNodesInformation(LayerNode layer_node) {
  if (layer_node.HasLayer()) {
    layer_node.SetDefaultVisible(true);
    layer_node.SetExportUsage(LayerTree::e_StateUndefined);
    layer_node.SetViewUsage(LayerTree::e_StateOFF);
    LayerPrintData print_data("subtype_print", LayerTree::e_StateON);
    layer_node.SetPrintUsage(print_data);
    LayerZoomData zoom_data(1, 10);
    layer_node.SetZoomUsage(zoom_data);
    WString new_name = WString(L"[View_OFF_Print_ON_Export_Undefined]") + layer_node.GetName();
    layer_node.SetName(new_name);
  }
  int count = layer_node.GetChildrenCount();
  for (int i = 0; i < count; i++) {
    LayerNode child = layer_node.GetChild(i);
    SetAllLayerNodesInformation(child);
  }
}

LayerTree layertree(doc);
LayerNode root = layertree.GetRootNode();
SetAllLayerNodesInformation(root);
...	
C
#include "include/fs_basictypes_c.h"
#include "include/fs_common_c.h"
#include "include/fs_pdfdoc_c.h"
#include "include/fs_render_c.h"
#include "include/fs_pdflayer_c.h"
 ...

// Assuming FS_PDFDOC_HANDLE doc has been loaded.

void SetAllLayerNodesInformation(LayerNode layer_node) {
  FS_BOOL return_HasLayer;
  FSDK_LayerNode_HasLayer(layer_node, &return_HasLayer);
  if (return_HasLayer) {
    FS_BOOL return_value;
    FSDK_LayerNode_SetDefaultVisible(layer_node, true, &return_value);
    FSDK_LayerNode_SetExportUsage(layer_node, e_FSStateUndefined, &return_value);;
    FSDK_LayerNode_SetViewUsage(layer_node, e_FSStateOFF, &return_value);
    FSLayerPrintData print_data;
    print_data.print_state = e_FSStateON;
    print_data.subtype.str = "subtype_print";
    print_data.subtype.len = strlen("subtype_print");
    FSDK_LayerNode_SetPrintUsage(layer_node, print_data, &return_value);
    FSLayerZoomData zoom_data;
    zoom_data.max_factor = 10;
    zoom_data.min_factor = 1;
    FSDK_LayerNode_SetZoomUsage(layer_node, zoom_data, &return_value);
    FS_WSTR return_GetName;
    FSDK_LayerNode_GetName(layer_node, &return_GetName);
wchar_t new_name[255];
swprintf_s(new_name, 255, L” [View_OFF_Print_ON_Export_Undefined]%ls”, return_GetName.str)
    FSDK_LayerNode_SetName(layer_node, new_name, &return_value);
  }
  int count = 0;
  FSDK_LayerNode_GetChildrenCount(layer_node, &count);
  for (int i = 0; i < count; i++) {
    FS_LAYERNODE_HANDLE child;
    FSDK_LayerNode_GetChild(layer_node, i, &child);
    SetAllLayerNodesInformation(child);
  }
}

FS_LAYERTREE_HANDLE layertree;
FSDK_LayerTree_Create(doc, &layertree);
FS_LAYERNODE_HANDLE root;
FSDK_LayerTree_GetRootNode(layertree, &root);
SetAllLayerNodesInformation(root);
...
java
import com.foxit.sdk.pdf.*;
...	

static void setAllLayerNodesInformation(LayerNode layer_node) throws PDFException {
    if (layer_node.hasLayer()) {
        layer_node.setDefaultVisible(true);
        layer_node.setExportUsage(e_StateUndefined);
        layer_node.setViewUsage(e_StateOFF);
        LayerPrintData print_data = new LayerPrintData("subtype_print", e_StateON);
        layer_node.setPrintUsage(print_data);
        LayerZoomData zoom_data = new LayerZoomData(1, 10);
        layer_node.setZoomUsage(zoom_data);
        String new_name = String.format("[View_OFF_Print_ON_Export_Undefined]") +  layer_node.getName();
        layer_node.setName(new_name);
    }
    int count = layer_node.getChildrenCount();
    for (int i = 0; i < count; i++) {
        LayerNode child = layer_node.getChild(i);
        setAllLayerNodesInformation(child);
    }
}
...
py
import sys
import site

if sys.version_info.major == 2:
    _PYTHON2_ = True
else:
    _PYTHON2_ = False

if _PYTHON2_:
    #replace with the python2 lib path
    site.addsitedir('../../../')
    from FoxitPDFSDKPython2 import *
else:
from FoxitPDFSDKPython3 import *

...
# Assuming PDFDoc doc has been loaded.

def SetAllLayerNodesInformation(layer_node):
    if layer_node.HasLayer():
        layer_node.SetDefaultVisible(True)
        layer_node.SetExportUsage(LayerTree.e_StateUndefined)
        layer_node.SetViewUsage(LayerTree.e_StateOFF)
        print_data = LayerPrintData("subtype_print", LayerTree.e_StateON)
        layer_node.SetPrintUsage(print_data)
        zoom_data = LayerZoomData(1, 10)
        layer_node.SetZoomUsage(zoom_data)
        new_name = "[View_OFF_Print_ON_Export_Undefined]" + layer_node.GetName()
        layer_node.SetName(new_name)
    
    count = layer_node.GetChildrenCount()
    for i in range(0, count):
        child = layer_node.GetChild(i)
        SetAllLayerNodesInformation(child)

layertree = LayerTree(doc)
root = layertree.GetRootNode()
SetAllLayerNodesInformation(root)
...
objc
#include "FSPDFObjC.h"
...

// Assuming FSPDFDoc doc has been loaded.
...

FSLayerTree* layertree = [[FSLayerTree alloc] initWithDocument:doc];
FSLayerNode* root = [layertree getRootNode];
if ([root isEmpty]) {
    return -1;
}
setAllLayerNodesInformation(root);

void setAllLayerNodesInformation(FSLayerNode* layer_node) {
    if ([layer_node hasLayer]) {
        [layer_node setDefaultVisible:YES];
        [layer_node setExportUsage:FSLayerTreeStateUndefined];
        [layer_node setViewUsage:FSLayerTreeStateOFF];
        FSLayerPrintData* print_data = [[FSLayerPrintData alloc] initWithSubtype:@"subtype_print" print_state:FSLayerTreeStateON];
        [layer_node setPrintUsage:print_data];
        FSLayerZoomData* zoom_data = [[FSLayerZoomData alloc] initWithMin_factor:1 max_factor:10];
        [layer_node setZoomUsage:zoom_data];
        NSString* new_name = [NSString stringWithFormat:@"%@%@",@"[View_OFF_Print_ON_Export_Undefined]", [layer_node getName]];
        [layer_node setName:new_name];
    }
    int count = [layer_node getChildrenCount];
    for (int i = 0; i < count; i++) {
        FSLayerNode* child = [layer_node getChild:i];
        setAllLayerNodesInformation(child);
    }
}
...	
js
const FSDK = require("@fuxinsoft/foxit-pdf-sdk-node");

...
// Assuming PDFDoc doc has been loaded.

function SetAllLayerNodesInformation(layer_node) {
  if (layer_node.HasLayer()) {
    layer_node.SetDefaultVisible(true);
    layer_node.SetExportUsage(FSDK.LayerTree.e_StateUndefined);
    layer_node.SetViewUsage(FSDK.LayerTree.e_StateOFF);
    let print_data = new FSDK.LayerPrintData("subtype_print", FSDK.LayerTree.e_StateON);
    layer_node.SetPrintUsage(print_data);
    let zoom_data = new FSDK.LayerZoomData(1, 10);
    layer_node.SetZoomUsage(zoom_data);
    let new_name = "[View_OFF_Print_ON_Export_Undefined]" + layer_node.GetName();
    layer_node.SetName(new_name);
  }
  let count = layer_node.GetChildrenCount();
  for (let i = 0; i < count; i++) {
    let child = layer_node.GetChild(i);
    SetAllLayerNodesInformation(child);
  }
}

let layertree = new FSDK.LayerTree(doc);
let root = layertree.GetRootNode();
SetAllLayerNodesInformation(root);
...
csharp
using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
...
// Assuming PDFDoc doc has been loaded.

public static void SetAllLayerNodesInformation(LayerNode layer_node) 
{
     if (layer_node.HasLayer()) 
     {
        layer_node.SetDefaultVisible(true);
        layer_node.SetExportUsage(LayerTree.UsageState.e_StateUndefined);
        layer_node.SetViewUsage(LayerTree.UsageState.e_StateOFF);
        LayerPrintData print_data = new LayerPrintData("subtype_print", LayerTree.UsageState.e_StateON);
        layer_node.SetPrintUsage (print_data);
        LayerZoomData zoom_data = new LayerZoomData(1, 10);
        layer_node.SetZoomUsage(zoom_data);
        string new_name = "[View_OFF_Print_ON_Export_Undefined]" + layer_node.GetName();
        layer_node.SetName(new_name);
     }
     int count = layer_node.GetChildrenCount();
     for (int i = 0; i < count; i++) 
     {
        using (LayerNode child = layer_node.GetChild(i))
        {
              SetAllLayerNodesInformation(child);
        }
     }
}

LayerTree layertree = new LayerTree(doc);
LayerNode root = layertree.GetRootNode();
if (root.IsEmpty())
{
    return;
}
SetAllLayerNodesInformation(root);
...
go
import (
. “foxit.com/fsdk”
)

...
# Assuming PDFDoc doc has been loaded.

func SetAllLayerNodesInformation(layer_node LayerNode){
    if layer_node.HasLayer(){
        layer_node.SetDefaultVisible(true)
        layer_node.SetExportUsage(LayerTreeE_StateUndefined)
        layer_node.SetViewUsage(LayerTreeE_StateOFF)
        print_data = LayerPrintData("subtype_print", LayerTreeE_StateON)
        layer_node.SetPrintUsage(print_data)
        zoom_data := LayerZoomData(1, 10)
        layer_node.SetZoomUsage(zoom_data)
        new_name := "[View_OFF_Print_ON_Export_Undefined]" + layer_node.GetName()
        layer_node.SetName(new_name)
    }
    count := layer_node.GetChildrenCount()
    for i:=0;i< count;i++{
        child := layer_node.GetChild(i)
        SetAllLayerNodesInformation(child)
}
}
layertree := NewLayerTree(doc)
root := layertree.GetRootNode()
SetAllLayerNodesInformation(root)
...


编辑图层树 ​

c++
#include "include/common/fs_common.h"
#include "include/pdf/fs_pdfdoc.h"
#include "include/common/fs_render.h"
#include "include/pdf/fs_pdflayer.h"

using namespace foxit;
using namespace foxit::common;
using namespace pdf;
 ...
// Assuming PDFDoc doc has been loaded.

// edit layer tree
PDFDoc doc(input_file);
error_code = doc.Load();
layertree = LayerTree(doc);
root = layertree.GetRootNode();
int children_count = root.GetChildrenCount();
root.RemoveChild(children_count -1);
LayerNode child = root.GetChild(children_count - 2);
LayerNode child0 = root.GetChild(0);
child.MoveTo(child0, 0);
child.AddChild(0, L"AddedLayerNode", true);
child.AddChild(0, L"AddedNode", false);
C
#include "include/fs_basictypes_c.h"
#include "include/fs_common_c.h"
#include "include/fs_pdfdoc_c.h"
#include "include/fs_render_c.h"
#include "include/fs_pdflayer_c.h"
 ...	

// Assuming FS_PDFDOC_HANDLE doc has been loaded.

// edit layer tree
FS_PDFDOC_HANDLE doc;
FSDK_PDFDoc_Create0(input_file, &doc);
FSErrorCode code = FSDK_PDFDoc_Load(doc, NULL);
FSDK_LayerTree_Create(doc, &layertree);
FSDK_LayerTree_GetRootNode(layertree, &root);
int children_count = 0;
FSDK_LayerNode_GetChildrenCount(root, &children_count);
FS_BOOL return_value;
FSDK_LayerNode_RemoveChild(root, children_count - 1, &return_value);
FS_LAYERNODE_HANDLE child;
FSDK_LayerNode_GetChild(root, children_count - 2, &child);
FS_LAYERNODE_HANDLE child0;
FSDK_LayerNode_GetChild(root, 0, &child0);
FSDK_LayerNode_MoveTo(child, child0, 0, &return_value);
FS_LAYERNODE_HANDLE return_AddChild;
FSDK_LayerNode_AddChild(root, 0, L"AddedLayerNode", true, &return_AddChild);
FSDK_LayerNode_AddChild(root, 0, L"AddedNode", false, &return_AddChild);
java
import com.foxit.sdk.pdf.*;
...

LayerTree layertree = new LayerTree(doc);
LayerNode root = layertree.getRootNode();
int children_count = root.getChildrenCount();
root.removeChild(children_count -1);
LayerNode child = root.getChild(children_count - 2);
LayerNode child0 = root.getChild(0);
child.moveTo(child0, 0);
child.addChild(0, "AddedLayerNode", true);
child.addChild(0, "AddedNode", false);
...
py
import sys
import site

if sys.version_info.major == 2:
    _PYTHON2_ = True
else:
    _PYTHON2_ = False

if _PYTHON2_:
    #replace with the python2 lib path
    site.addsitedir('../../../')
    from FoxitPDFSDKPython2 import *
else:
from FoxitPDFSDKPython3 import *
…
# Assuming PDFDoc doc has been loaded.

# edit layer tree
doc = PDFDoc(input_file)
error_code = doc.Load("")
layertree = LayerTree(doc)
root = layertree.GetRootNode()
children_count = root.GetChildrenCount()
root.RemoveChild(children_count -1)
child = root.GetChild(children_count - 2)
child0 = root.GetChild(0)
child.MoveTo(child0, 0)
child.AddChild(0, "AddedLayerNode", True)
child.AddChild(0, "AddedNode", False)
objc
#include "FSPDFObjC.h"
...

FSLayerTree* layertree = [[FSLayerTree alloc] initWithDocument:doc];
FSLayerNode* root = [layertree getRootNode];
if ([root isEmpty]) {
    return -1;
}
int children_count = [root getChildrenCount];
[root removeChild:children_count-1];
FSLayerNode* child = [root getChild:children_count-2];
FSLayerNode* child0 = [root getChild:0];
[child moveTo:child0 index:0];
[child addChild:0 name:@"AddedLayerNode" has_Layer:YES];
[child addChild:0 name:@"AddedNode" has_Layer:NO];
...
js
const FSDK = require("@fuxinsoft/foxit-pdf-sdk-node");
…
// Assuming PDFDoc doc has been loaded.

// edit layer tree.
let doc = new FSDK.PDFDoc(input_file);
let error_code = doc.Load("");
let layertree = new FSDK.LayerTree(doc);
let root = layertree.GetRootNode();
let children_count = root.GetChildrenCount();
root.RemoveChild(children_count - 1);
let child = root.GetChild(children_count - 2);
let child0 = root.GetChild(0);
child.MoveTo(child0, 0);
child.AddChild(0, "AddedLayerNode", true);
child.AddChild(0, "AddedNode", false);
csharp
using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
 ...
// Assuming PDFDoc doc has been loaded.

LayerTree layertree = new LayerTree(doc);
LayerNode root = layertree.GetRootNode();
int children_count = root.GetChildrenCount();
root.RemoveChild(children_count - 1);
LayerNode child = root.GetChild(children_count - 2);
LayerNode child0 = root.GetChild(0);
child.MoveTo(child0, 0);
child.AddChild(0, "AddedLayerNode", true);
child.AddChild(0, "AddedNode", false);
go
import (
. “foxit.com/fsdk”
)
…
# Assuming PDFDoc doc has been loaded.

# edit layer tree
doc := NewPDFDoc(input_file)
error_code := doc.Load("")
layertree := NewLayerTree(doc)
root := layertree.GetRootNode()
children_count := root.GetChildrenCount()
root.RemoveChild(children_count -1)
child := root.GetChild(children_count - 2)
child0 := root.GetChild(0)
child.MoveTo(child0, 0)
child.AddChild(0, "AddedLayerNode", true)
child.AddChild(0, "AddedNode", false)