You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在pdf.js渲染的Canvas显示前添加自定义文本?

问题原因与解决方案

问题根源

  • canvas无法嵌套HTML元素:canvas是独立的位图绘制容器,它内部不能直接放置div、span等HTML元素,浏览器只会渲染canvas自身的绘制内容,忽略其DOM子节点。
  • 文本被PDF渲染覆盖:pdf.js渲染PDF页面时,会对canvas的上下文进行全区域的像素重绘(比如通过drawImage绘制PDF的光栅数据),如果先调用fillText画文本,后续的PDF渲染会完全覆盖这些像素,导致文本不可见。

可行解决方法

1. 调整绘制顺序:先渲染PDF,再叠加文本

把自定义文本的绘制逻辑放在PDF渲染完成的回调中,确保文本绘制在PDF内容之上:

function renderPage(page) {
  const viewport = page.getViewport({ scale: 1.5 });
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  canvas.height = viewport.height;
  canvas.width = viewport.width;

  // 先渲染PDF
  page.render({
    canvasContext: ctx,
    viewport: viewport
  }).promise.then(() => {
    // PDF渲染完成后绘制文本
    ctx.fillStyle = '#ff0000';
    ctx.font = '24px sans-serif';
    ctx.fillText('Hello World', 50, 50); // 调整坐标控制文本位置
  });

  document.body.appendChild(canvas);
}

2. 用容器包裹canvas,叠加HTML文本元素

不需要修改canvas,给每个canvas套一个相对定位的容器,再在容器内添加绝对定位的文本元素,实现文本与PDF内容的视觉叠加:

function renderPage(page) {
  const viewport = page.getViewport({ scale: 1.5 });
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  canvas.height = viewport.height;
  canvas.width = viewport.width;

  // 创建容器并设置定位
  const container = document.createElement('div');
  container.style.position = 'relative';
  container.style.display = 'block';
  container.style.marginBottom = '10px';

  // 创建文本元素
  const textEl = document.createElement('span');
  textEl.textContent = 'Hello World';
  textEl.style.position = 'absolute';
  textEl.style.top = '50px';
  textEl.style.left = '50px';
  textEl.style.color = 'red';
  textEl.style.fontSize = '24px';

  // 渲染PDF并组装容器
  page.render({ canvasContext: ctx, viewport }).promise.then(() => {
    container.appendChild(canvas);
    container.appendChild(textEl);
    document.body.appendChild(container);
  });
}

3. 将canvas转为图片后再编辑(适合静态导出场景)

如果需要生成带文本的静态内容,可以先把渲染好的PDF canvas转为图片,再绘制到新canvas上并添加文本:

function renderPage(page) {
  const viewport = page.getViewport({ scale: 1.5 });
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  canvas.height = viewport.height;
  canvas.width = viewport.width;

  page.render({ canvasContext: ctx, viewport }).promise.then(() => {
    // 将PDF canvas转为图片
    const pdfImg = new Image();
    pdfImg.src = canvas.toDataURL('image/png');
    pdfImg.onload = () => {
      // 创建新canvas
      const finalCanvas = document.createElement('canvas');
      const finalCtx = finalCanvas.getContext('2d');
      finalCanvas.width = canvas.width;
      finalCanvas.height = canvas.height;
      
      // 绘制PDF图片
      finalCtx.drawImage(pdfImg, 0, 0);
      // 绘制自定义文本
      finalCtx.fillStyle = 'red';
      finalCtx.font = '24px Arial';
      finalCtx.fillText('Hello World', 50, 50);
      
      document.body.appendChild(finalCanvas);
    };
  });
}

内容的提问来源于stack exchange,提问作者Mastas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 11:03:18