合同、报告一类的 PDF 要加配图或标识时,图片直接叠上去会盖住正文,只能缩到角落。已经排进文档的图片要调淡,又得回到源文件重新排版,手上没有源文件就只能将就。这两件事在桌面软件里都靠手工,也接不进批量生成的 Web 流程;放到服务端处理,文件还得先离开用户的设备。
本文用 Spire.PDF for JavaScript 在浏览器里完成。新图由 PdfCanvas.SetTransparency() 按指定的 alpha 画进页面;页面上已有的图片则交给 PdfImageHelper 找出来,删除后按原界框以半透明重绘。整个过程基于 WebAssembly 运行,PDF 通过虚拟文件系统(VFS)读写,无需后端配合。
本文介绍两个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.PDF for JavaScript。以下示例默认已安装 Spire.PDF 并完成 WebAssembly 模块初始化。
添加指定透明度的图像到 PDF 文档
Spire.PDF for JavaScript 提供 PdfCanvas.SetTransparency() 方法,用于给画布设置透明度。只传 alpha 时,填充与描边共用这一个值,取值 0 到 1:0 完全透明,1 完全不透明。它从调用处开始对之后的所有绘制生效,所以要用 Save() 与 Restore() 把范围框住,免得页面上的其他内容跟着变淡。
具体操作步骤如下:
- 获取 Spire.PDF 的 WASM 模块,确认已就绪。
- 把待处理的 PDF 文件与图片载入 VFS。
- 创建
PdfDocument对象并加载 PDF,取出第一页;用PdfImage.FromFile()载入图片。 - 用
PdfCanvas.Save()保存画布状态,调用SetTransparency()设置透明度,再用DrawImage()绘制图片。 - 用
Restore()恢复画布状态,最后用SaveToFile()保存结果并触发下载。
添加半透明图片的代码如下:
function App() {
const addTransparentImage = async () => {
// 获取 Spire.PDF WASM 模块
const pdfModule = window.wasmModule?.spirepdf;
// 检查模块是否就绪
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// 将待处理的 PDF 与图片载入 VFS
const inputFileName = '数据概览.pdf';
const imageFileName = '风景.jpg';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
await window.spire.FetchFileToVFS(imageFileName, "", `${process.env.PUBLIC_URL}/data/`);
// 创建 PdfDocument 对象并加载 PDF 文档
let doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
// 取出第一页,载入要绘制的图片
let page = doc.Pages.get_Item(0);
let image = pdfModule.PdfImage.FromFile(imageFileName);
// 保存画布状态,透明度只在本段绘制中生效
const state = page.Canvas.Save();
// alpha 取 0.35,图片半透明,下方内容仍可辨认
page.Canvas.SetTransparency({ alpha: 0.35 });
page.Canvas.DrawImage({ image: image, x: 145, y: 400, width: 300, height: 173 });
// 恢复画布状态,避免影响后续绘制
page.Canvas.Restore({ state: state });
// 保存结果文件
const outputFileName = '半透明图片.pdf';
doc.SaveToFile(outputFileName);
doc.Close();
// 从 VFS 读取生成的文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>添加半透明图片</h1>
<button onClick={addTransparentImage}>
开始添加
</button>
</div>
);
}
export default App;
叠加 35% 不透明度的图片后,下方内容仍能透出:

调整 PDF 页面上现有图片的透明度
Spire.PDF for JavaScript 还提供 PdfImageHelper 类,用于读取、删除和替换页面上的图片。GetImagesInfo() 返回每张图片的界框与图像流,从图像流重新创建 PdfImage,再用 DeleteImage() 删掉原图、按 Bounds 以指定透明度重绘,页面上现有图片的透明程度就调好了。
具体操作步骤如下:
- 获取 Spire.PDF 的 WASM 模块,确认已就绪。
- 把待处理的 PDF 文件载入 VFS。
- 创建
PdfDocument对象并加载 PDF,取得页面;用PdfImageHelper.GetImagesInfo()读出页面上的所有图片。 - 逐张用
PdfImage.FromStream()从PdfImageInfo.Image重新创建图片,并记下Bounds。 - 调用
DeleteImage()删除全部原图,再按原界框以指定透明度重绘,最后用SaveToFile()保存并触发下载。
调整现有图片透明度的代码如下:
function App() {
const adjustImageTransparency = async () => {
// 获取 Spire.PDF WASM 模块
const pdfModule = window.wasmModule?.spirepdf;
// 检查模块是否就绪
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// 将待处理的 PDF 载入 VFS
const inputFileName = '数据概览.pdf';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// 创建 PdfDocument 对象并加载 PDF 文档
let doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
// 取出第一页,读取页面上的图片信息
let page = doc.Pages.get_Item(0);
let helper = new pdfModule.PdfImageHelper();
let images = helper.GetImagesInfo(page);
// 先收集每张图片的图像流与界框,供删除后重绘使用
let items = [];
for (let i = 0; i < images.length; i++) {
items.push({
info: images[i],
image: pdfModule.PdfImage.FromStream(images[i].Image),
bounds: images[i].Bounds
});
}
// 先删除全部原图,再统一重绘;逐张删完就画会被后续删除覆盖
for (let i = 0; i < items.length; i++) {
helper.DeleteImage({ imageInfo: items[i].info });
}
// 按原界框以 40% 的不透明度重绘每张图片
for (let i = 0; i < items.length; i++) {
const { image, bounds } = items[i];
const state = page.Canvas.Save();
page.Canvas.SetTransparency({ alpha: 0.4 });
page.Canvas.DrawImage({
image: image,
x: bounds.X,
y: bounds.Y,
width: bounds.Width,
height: bounds.Height
});
page.Canvas.Restore({ state: state });
}
// 保存结果文件
const outputFileName = '现有图片透明度.pdf';
doc.SaveToFile(outputFileName);
doc.Close();
// 从 VFS 读取生成的文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>调整现有图片透明度</h1>
<button onClick={adjustImageTransparency}>
开始调整
</button>
</div>
);
}
export default App;
页面上的三张图片按原位置以 40% 的不透明度重绘,正文部分不受影响:

常见问题
设置了图片透明度,为什么后面绘制的内容也变淡了
原因:透明度记在画布状态里,SetTransparency() 之后的所有绘制都会沿用这个值,直到状态被恢复或重新设置。
解决:用 Save() 与 Restore() 把设置包起来,让透明度只作用于中间那段绘制:
const state = page.Canvas.Save();
page.Canvas.SetTransparency({ alpha: 0.35 });
page.Canvas.DrawImage({ image: image, x: 145, y: 400, width: 300, height: 173 });
page.Canvas.Restore({ state: state });
调整现有图片时,为什么只有最后一张变透明了
原因:DeleteImage() 会重写页面的内容流。每删一张就立刻重绘,下一次删除又会把上一次的绘制一起覆盖掉,最后往往只剩最后一张还在。
解决:把收集、删除、重绘分成三步:先读出所有图片的图像流与界框,再统一删除原图,最后统一重绘。
// 先删除全部原图
for (let i = 0; i < items.length; i++) {
helper.DeleteImage({ imageInfo: items[i].info });
}
// 再统一重绘
for (let i = 0; i < items.length; i++) {
const { image, bounds } = items[i];
const state = page.Canvas.Save();
page.Canvas.SetTransparency({ alpha: 0.4 });
page.Canvas.DrawImage({
image: image,
x: bounds.X,
y: bounds.Y,
width: bounds.Width,
height: bounds.Height
});
page.Canvas.Restore({ state: state });
}
只想调整页面上的其中一张图片,怎么改
原因:GetImagesInfo() 按页面上的顺序返回所有图片,每项都是一个 PdfImageInfo,界框可以从 Bounds 读出。
解决:不遍历全部,直接取需要的那一项处理即可。下面的写法只调整第一张:
let images = helper.GetImagesInfo(page);
let info = images[0];
let image = pdfModule.PdfImage.FromStream(info.Image);
let bounds = info.Bounds;
helper.DeleteImage({ imageInfo: info });
const state = page.Canvas.Save();
page.Canvas.SetTransparency({ alpha: 0.4 });
page.Canvas.DrawImage({ image: image, x: bounds.X, y: bounds.Y, width: bounds.Width, height: bounds.Height });
page.Canvas.Restore({ state: state });
alpha 取 0 和 1 分别是什么效果
原因:alpha 表示不透明程度,0 到 1 之间线性取值。
解决:取 0 时图片完全透明、在页面上不可见;取 1 时完全不透明,与直接绘制没有区别。需要淡化的效果,通常取 0.2 到 0.5 之间。
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







