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

NextJS中jsPDF转换next/image图片异常问题求助

问题:Next.js Image组件配合fill属性在jsPDF生成PDF时显示异常

在Next.js项目中使用next/image组件,将其包裹在div中并设置fill属性后,Chrome浏览器显示正常,但通过jsPDF生成PDF时图片显示异常。

代码示例

PDF下载逻辑

const downloadPdf = () => {
  const input = pdfRef.current;
  html2canvas(input, { scale: 5 }).then((canvas) => {
    const imgData = canvas.toDataURL('image/png', 1.0);
    const pdf = new jsPDF('l', 'px', 'a5', true);
    const imgProps = pdf.getImageProperties(imgData);

    // 文档和图片尺寸计算
    const pdfWidth = pdf.internal.pageSize.getWidth();
    const pdfHeight = pdf.internal.pageSize.getHeight();
    const imgWidth = imgProps.width;
    const imgHeight = imgProps.height;

    // 计算适配页面的缩放比例
    const scale = Math.max(pdfHeight / imgHeight, pdfWidth / imgWidth);
    const finalWidth = imgWidth * scale;
    const finalHeight = imgHeight * scale;
    const leftMargin = (pdfWidth - finalWidth) / 2;
    // 添加图片到PDF
    pdf.addImage(imgData, 'PNG', leftMargin, 0, finalWidth, finalHeight, 'alias', 'FAST');
    pdf.save('certificate.pdf');
  });
};

Image组件代码

<div ref={certificateRef} className={`${styles.certificate__background} ${!dataCertificate && styles.disable}`}>
  <Image
    id="backgroundCertificate"
    src="/images/certificate-active.svg"
    alt="TEK4_IMAGE"
    fill
    priority
    style={{ objectFit: 'contain' }}
  />
</div>

问题原因

  1. next/image的fill属性依赖父容器的position: relative定位,如果父容器样式中未明确设置,html2canvas渲染时可能无法正确识别图片位置
  2. html2canvas对Next.js优化后的SVG图片支持存在兼容性问题,fill模式下的动态尺寸计算在快照时可能未完成
  3. 即使设置了priority,图片可能在html2canvas执行快照时仍未完全加载或渲染完成

解决方法

1. 确保父容器定位正确

给包裹Image的div明确添加position: relative样式,可直接在className对应的CSS中设置,或通过内联样式补充:

<div 
  ref={certificateRef} 
  className={`${styles.certificate__background} ${!dataCertificate && styles.disable}`}
  style={{ position: 'relative' }}
>
  {/* Image组件 */}
</div>

2. 等待图片完全加载后再生成PDF

在调用html2canvas前,确保图片已加载完成,可通过监听Image的onLoad事件标记加载状态:

const [imageLoaded, setImageLoaded] = useState(false);

// ...

<Image
  id="backgroundCertificate"
  src="/images/certificate-active.svg"
  alt="TEK4_IMAGE"
  fill
  priority
  style={{ objectFit: 'contain' }}
  onLoad={() => setImageLoaded(true)}
/>

// 下载PDF时判断状态
const downloadPdf = () => {
  if (!imageLoaded) return;
  const input = pdfRef.current;
  // 后续逻辑不变
};

3. 替换为原生img标签(适合不需要Next.js图片优化的场景)

如果不需要next/image的自动优化、懒加载等功能,直接使用原生img标签避免兼容性问题:

<div 
  ref={certificateRef} 
  className={`${styles.certificate__background} ${!dataCertificate && styles.disable}`}
  style={{ position: 'relative', width: '100%', height: '100%' }}
>
  <img
    src="/images/certificate-active.svg"
    alt="TEK4_IMAGE"
    style={{ width: '100%', height: '100%', objectFit: 'contain' }}
  />
</div>

4. 调整html2canvas配置

给html2canvas添加额外配置项,提升渲染兼容性:

html2canvas(input, {
  scale: 5,
  useCORS: true,
  logging: false,
  backgroundColor: null // 避免添加默认背景色影响SVG透明区域
}).then((canvas) => {
  // 后续逻辑不变
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 03:24:49