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

FPDI技术问题:如何基于像素坐标精准定位文本与图像元素

FPDI嵌入元素精准定位问题与解决方案

核心问题

在使用FPDI向PDF嵌入文本和图像时,无法精准对齐演示PDF中的原始坐标。尝试用72/96的比例将像素转成点,但元素位置仍有偏差,需明确:

  • FPDI采用何种计量单位?
  • 如何准确将像素坐标转换为该单位实现精准放置?

现有代码片段

public function addTextElement($pdf, $element): void {
    // Conversion of pixel coordinates to points
    $x = $element['response_meta_json']['cord']['x'] * (72 / 96);
    $y = $element['response_meta_json']['cord']['y'] * (72 / 96);

    // Set font and position
    $pdf->SetFont($element['response_meta_json']['font-family'] ?? 'Arial', '', $element['response_meta_json']['font-size'] ?? 12);
    $pdf->SetXY($x, $y);
    $pdf->MultiCell(
      $element['response_meta_json']['area']['width'],
      $element['response_meta_json']['area']['height'],
      $element['response_meta_json']['value']
    );
}

public function addImageElement($pdf, $element): void {
    // Conversion of pixel coordinates to points
    $x = $element['response_meta_json']['cord']['x'] * (72 / 96);
    $y = $element['response_meta_json']['cord']['y'] * (72 / 96);

    // Manual positioning for testing purposes
    $x = 132.29166667;
    $y = 200.81875;

    $imageSrc = $element['response_meta_json']['img_src'];

    // Image embedding with coordinates
    $pdf->Image(
      $imageSrc,
      $x,
      $y,
      $element['response_meta_json']['area']['width'],
      $element['response_meta_json']['area']['height']
    );
}

解决方案

1. FPDI的计量单位

FPDI继承自FPDF,默认使用点(Point)作为计量单位,1点 = 1/72英寸。需要注意的是:PDF的坐标系原点(0,0)在页面左下角,而多数设计工具的像素坐标原点在左上角,这是坐标偏差的核心原因之一。

2. 像素转点的准确转换步骤

  • 确认原始设计DPI:
    72/96的比例仅适用于屏幕DPI为96的场景,如果演示PDF的原始设计DPI为其他值(如印刷常用300DPI),比例会出错。正确转换公式为:
    点坐标 = 像素坐标 × (72 / 原始设计DPI)
    可通过Adobe Acrobat等工具查看PDF文档分辨率,或从设计源文件确认DPI。

  • 修正Y轴坐标:
    由于PDF与设计工具的Y轴方向相反,需将设计Y坐标转换为PDF坐标系的Y值:
    PDF_Y = 页面高度(点) - 转换后的像素Y(点) - 元素高度(点)
    页面高度可通过$pdf->h获取,例如A4纸的高度约为842点(297mm × 72/25.4 ≈ 842)。

  • 统一单位转换:
    元素的宽高也需要用相同的DPI比例转换,避免尺寸偏差。

3. 修正后的代码示例

public function addTextElement($pdf, $element): void {
    // 替换为演示PDF的原始设计DPI
    $designDpi = 96;
    $conversionRatio = 72 / $designDpi;

    // X坐标直接转换(原点一致)
    $x = $element['response_meta_json']['cord']['x'] * $conversionRatio;
    // Y坐标修正坐标系方向
    $pixelY = $element['response_meta_json']['cord']['y'] * $conversionRatio;
    $elementHeight = $element['response_meta_json']['area']['height'] * $conversionRatio;
    $y = $pdf->h - $pixelY - $elementHeight;

    // 转换元素宽高
    $width = $element['response_meta_json']['area']['width'] * $conversionRatio;
    $height = $elementHeight;

    $pdf->SetFont($element['response_meta_json']['font-family'] ?? 'Arial', '', $element['response_meta_json']['font-size'] ?? 12);
    $pdf->SetXY($x, $y);
    $pdf->MultiCell($width, $height, $element['response_meta_json']['value']);
}

public function addImageElement($pdf, $element): void {
    $designDpi = 96;
    $conversionRatio = 72 / $designDpi;

    $x = $element['response_meta_json']['cord']['x'] * $conversionRatio;
    $pixelY = $element['response_meta_json']['cord']['y'] * $conversionRatio;
    $elementHeight = $element['response_meta_json']['area']['height'] * $conversionRatio;
    $y = $pdf->h - $pixelY - $elementHeight;

    $width = $element['response_meta_json']['area']['width'] * $conversionRatio;
    $height = $elementHeight;

    $imageSrc = $element['response_meta_json']['img_src'];
    $pdf->Image($imageSrc, $x, $y, $width, $height);
}

4. 调试技巧

  • 使用$pdf->Rect($x, $y, $width, $height)绘制元素边框,对比演示PDF的元素位置,快速定位偏差原因。
  • 确认FPDI导入的PDF页面尺寸与原文档一致,避免页面缩放导致的坐标偏移。

内容的提问来源于stack exchange,提问作者Mohammad Ali Shuvo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 15:17:08