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("@foxitsoftware/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();
...
设置所有图层节点的信息
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("@foxitsoftware/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);
...
编辑图层树
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("@foxitsoftware/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);