截图工具 (Snapshot)
福昕 PDF SDK(Web) 提供截图工具,开发者可以截取 PDF 页面中的指定区域,并将截图图片用于预览、上传、复制到剪贴板或接入自定义业务流程。
截图能力主要包含三部分:
- 通过
PDFPageRender.getSnapshot()或PDFViewer.takeSnapshot()获取指定区域的图片数据。 - 通过
PDFViewer.uploadImage()和SnapshotServer上传截图图片并生成可访问的图片地址。 - 通过
PDFViewer.copySnapshot()将截图复制到系统剪贴板。
截图接口
通过页面渲染对象截图
PDFPageRender.getSnapshot(left, top, width, height) 用于截取当前页面渲染对象上的指定区域。
javascript
const pageRender = pdfViewer.getPDFPageRender(pageIndex);
if (pageRender) {
const imageBlob = await pageRender.getSnapshot(left, top, width, height);
// 获取指定页面区域的图片数据。
}
通过 Viewer 截图
PDFViewer.takeSnapshot(pageIndex, left, top, width, height) 用于直接截取指定页面上的区域。pageIndex 从 0 开始。
javascript
const imageBlob = await pdfViewer.takeSnapshot(pageIndex, left, top, width, height);
// 获取指定页面区域的图片数据。
坐标参数
left、top、width 和 height 都使用 device pixels,表示页面左上角开始的设备像素坐标和区域大小。
| 参数 | 说明 |
|---|---|
pageIndex | 页面索引,从 0 开始。 |
left | 截图区域左上角相对页面左上角的 X 轴偏移,单位为 device pixels。 |
top | 截图区域左上角相对页面左上角的 Y 轴偏移,单位为 device pixels。 |
width | 截图区域宽度,单位为 device pixels。 |
height | 截图区域高度,单位为 device pixels。 |
如果业务中使用的是 PDF 坐标,需要先转换为页面渲染使用的设备像素坐标。可以参考 API Reference 中的 PDFPage.getDevicePoint()、PDFPageRender.transformPoint() 等坐标转换接口。
复制截图到剪贴板
PDFViewer.copySnapshot(dataURL) 用于将图片复制到系统剪贴板。该接口接收图片地址或 Data URL 字符串,不应直接传入 Blob。
下面示例将截图得到的 Blob 转换为 Data URL 后复制:
javascript
function blobToDataURL(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(blob);
});
}
button.addEventListener('click', async () => {
const imageBlob = await pdfViewer.takeSnapshot(0, 0, 0, 200, 200);
const dataURL = await blobToDataURL(imageBlob);
const copied = await pdfViewer.copySnapshot(dataURL);
if (copied) {
console.log('截图已复制到剪贴板');
}
});
注意
受浏览器安全策略限制,复制剪贴板通常需要在用户触发的短时事件处理函数内调用,例如按钮点击事件。剪贴板访问还需要 HTTPS 或 localhost 等安全来源。
图片存储服务
上传截图图片
PDFViewer.uploadImage(blob) 用于通过截图图片存储服务上传图片,并返回可访问的图片 URL。
javascript
const imageBlob = await pdfViewer.takeSnapshot(0, 0, 0, 200, 200);
const imageURL = await pdfViewer.uploadImage(imageBlob);
console.log('截图图片地址:', imageURL);
上传服务适用于以下场景:
- 将截图保存到业务服务器。
- 获取同源图片 URL,避免部分浏览器对跨源图片或剪贴板操作的限制。
- 将截图图片地址写入业务数据或发送给其他系统。
默认图片存储服务
SDK 内置 SnapshotServer,可通过 viewerOptions.snapshotServer 修改上传行为。
javascript
const SnapshotServer = PDFViewCtrl.SnapshotServer;
const pdfui = new PDFUI({
viewerOptions: {
snapshotServer: new SnapshotServer({
origin: location.origin,
uploadSnapshotAPIPath: 'snapshot/upload',
payloadFieldName: 'file',
method: 'POST',
render: function (responseText) {
return responseText;
}
})
},
renderTo: document.body
});
SnapshotServer 常用配置如下:
| 配置项 | 说明 |
|---|---|
origin | 服务域名。 |
uploadSnapshotAPIPath | 上传接口路径。 |
payloadFieldName | 上传表单字段名,默认值为 file。 |
method | 请求方法,支持 POST 或 PUT。 |
render(responseText) | 解析服务端响应,返回最终图片 URL。 |
提示
如果服务端返回格式为 { success: true, data: { url: '/snapshot/image/xxx' } },可以在 render 中解析并返回 data.url。
javascript
const snapshotServer = new SnapshotServer({
uploadSnapshotAPIPath: 'snapshot/upload',
render: function (responseText) {
const result = JSON.parse(responseText);
return result.data.url;
}
});
自定义图片存储服务
如果需要添加自定义请求头、鉴权逻辑、上传前校验或特殊响应解析,可以实现自定义 snapshotServer 对象。
javascript
const pdfui = new PDFUI({
viewerOptions: {
snapshotServer: {
render(responseText) {
const result = JSON.parse(responseText);
return result.url;
},
uploadImage(imageBlob) {
const formData = new FormData();
formData.append('file', imageBlob, 'snapshot.png');
return fetch('/snapshot/upload', {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`
},
body: formData
})
.then(response => response.text())
.then(responseText => this.render(responseText));
}
}
},
renderTo: document.body
});
截图工具 UI 入口
如果使用 UIExtension,SDK 已提供截图工具的预配置组件:
<snapshot-button>:普通按钮形式的截图入口。<snapshot-ribbon-button>:Ribbon 按钮形式的截图入口,8.2.0 起推荐使用。states:SnapshotToolController:切换当前 state-handler 为STATE_HANDLER_SNAPSHOT_TOOL。
可以在自定义布局模板中直接添加截图按钮:
html
<snapshot-ribbon-button></snapshot-ribbon-button>
也可以使用等价的基础组件和控制器:
html
<ribbon-button
text="toolbar.buttons.snapshot"
@controller="states:SnapshotToolController"
@tooltip
tooltip-title="toolbar.buttons.snapshot"
name="snapshot-button"
icon-class="fv__icon-toolbar-snapshot"
>toolbar.buttons.snapshot
</ribbon-button>
更多组件用法请参考 预配置业务组件。
完整示例
javascript
const SnapshotServer = PDFViewCtrl.SnapshotServer;
function blobToDataURL(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(blob);
});
}
const pdfui = new PDFUI({
viewerOptions: {
snapshotServer: new SnapshotServer({
origin: location.origin,
uploadSnapshotAPIPath: 'snapshot/upload',
payloadFieldName: 'file',
method: 'POST',
render: function (responseText) {
return responseText;
}
})
},
renderTo: document.body
});
const pdfViewer = await pdfui.getPDFViewer();
document.querySelector('#copy-snapshot').addEventListener('click', async () => {
try {
// 截取第 1 页左上角 200 x 200 的区域。
const imageBlob = await pdfViewer.takeSnapshot(0, 0, 0, 200, 200);
// 上传到业务服务。
const imageURL = await pdfViewer.uploadImage(imageBlob);
console.log('截图图片地址:', imageURL);
// 复制到剪贴板。
const dataURL = await blobToDataURL(imageBlob);
const copied = await pdfViewer.copySnapshot(dataURL);
if (!copied) {
console.warn('截图复制失败');
}
} catch (error) {
console.error('截图处理失败:', error);
}
});
注意事项
getSnapshot()和takeSnapshot()截取的是页面渲染区域,不会修改 PDF 文档内容。- 截图区域参数使用 device pixels,不是 PDF 坐标。
- 较大的截图区域可能产生较大的图片数据,应根据业务场景控制截图范围。
copySnapshot()受浏览器剪贴板权限和安全来源限制,建议在用户点击事件中调用。PDFPageRender.getSnapshot()属于浏览器端渲染能力,不支持 Server 环境。