pdf图片处理

将pdf中的一页另存为图片
在使用pymupdf时,获取到page对象后,使用page.get_pixmap(dpi=500) 这个方法可以将整页保存为图像。但这里有两种方式,一种是使用dpi参数,这个是代表在一英寸里要包含多少个像素,设置越大,图像的像素就越高,相对应的文件也会越大。 而pdf文件的page是有尺寸的,比如height为8.2英寸,那么图像的hgiht像素就应为 8.2 * 500像素。

另一个方式是使用matrix参数。

Matrix类:pymupdf的变换矩阵

Matrix类是什么?

pymupdf.Matrix是一个3×3的仿射变换矩阵,用于表示二维空间中的线性变换。在计算机图形学中,这种矩阵可以表示缩放、旋转、平移、剪切等变换。

import pymupdf

# Matrix类的基本结构
"""
一个pymupdf.Matrix对象表示如下形式的矩阵:
[ a  b  0 ]
[ c  d  0 ]
[ e  f  1 ]

其中:
- a, b, c, d: 控制线性变换(缩放、旋转、剪切)
- e, f: 控制平移(x轴和y轴的偏移)
- 最后一行总是 [0, 0, 1],用于齐次坐标

常用的变换:
缩放:Matrix(scale_x, 0, 0, scale_y, 0, 0)
旋转:Matrix(cosθ, sinθ, -sinθ, cosθ, 0, 0)
平移:Matrix(1, 0, 0, 1, tx, ty)
"""

Matrix类的主要用途

# 1. 创建常见的变换矩阵
# 缩放
scale_2x = pymupdf.Matrix(2, 0, 0, 2, 0, 0)  # 放大2倍
scale_half = pymupdf.Matrix(0.5, 0, 0, 0.5, 0, 0)  # 缩小一半

# 旋转(角度制)
rotate_90 = pymupdf.Matrix(0, 1, -1, 0, 0, 0)  # 顺时针90度

# 平移
translate_100 = pymupdf.Matrix(1, 0, 0, 1, 100, 100)  # 向右向下各移动100单位

# 组合变换
combined = pymupdf.Matrix(2, 0, 0, 2, 100, 100)  # 放大2倍并平移

使用Matrix直接控制输出像素尺寸

关键公式:Matrix缩放因子与像素尺寸的关系

def calculate_matrix_for_target_size(page, max_pixels=1024):
    """
    计算让图片最长边不超过max_pixels的Matrix
    """
    # PDF页面的尺寸(以点为单位,1点=1/72英寸)
    rect = page.rect
    width_pts = rect.width
    height_pts = rect.height
    
    # 计算缩放比例
    # 我们要让 max(width, height) * scale ≤ max_pixels
    scale = max_pixels / max(width_pts, height_pts)
    
    # 创建缩放矩阵
    # Matrix(sx, 0, 0, sy, 0, 0) 其中sx=sy=scale
    matrix = pymupdf.Matrix(scale, 0, 0, scale, 0, 0)
    
    return matrix

# 使用示例
doc = pymupdf.open("datasheet.pdf")
page = doc[0]

# 计算合适的缩放矩阵
matrix = calculate_matrix_for_target_size(page, 1024)

# 使用matrix参数生成图片
pix = page.get_pixmap(matrix=matrix)
print(f"输出尺寸: {pix.width}×{pix.height}像素")
# 确保不超过1024: assert max(pix.width, pix.height) <= 1024

Matrix参数 vs DPI参数的区别

comparison = {
    "DPI方式": {
        "控制方式": "通过物理密度控制",
        "计算公式": "像素 = (点数 × DPI) / 72",
        "精度": "DPI必须是整数,可能有舍入误差",
        "灵活性": "只能等比例缩放",
        "代码示例": "page.get_pixmap(dpi=300)"
    },
    
    "Matrix方式": {
        "控制方式": "直接数学变换",
        "计算公式": "像素 = 点数 × scale",
        "精度": "scale可以是浮点数,更精确",
        "灵活性": "可以非等比缩放、旋转、平移",
        "代码示例": "page.get_pixmap(matrix=Matrix(2.5, 0, 0, 2.5, 0, 0))"
    }
}

# 两者关系
# 当只进行等比例缩放时:
# DPI = 300 等价于 Matrix(300/72, 0, 0, 300/72, 0, 0)
# 因为:scale = DPI / 72
# 最简实现
import pymupdf

def simple_best_solution(pdf_path, page_num, max_pixels=1024):
    doc = pymupdf.open(pdf_path)
    page = doc[page_num]
    
    # 计算缩放比例
    rect = page.rect
    scale = max_pixels / max(rect.width, rect.height)
    
    # 使用Matrix生成图片
    pix = page.get_pixmap(matrix=pymupdf.Matrix(scale, 0, 0, scale, 0, 0))
    
    # 保存
    pix.save(f"output.png")
    doc.close()
    
    return pix

关键要点:

  1. matrix参数比dpi参数更灵活、更精确
  2. 可以直接控制输出像素尺寸,不需要中间转换
  3. 对于需要精确尺寸控制的训练数据准备,这是最佳选择
  4. Matrix还能实现旋转、平移等高级变换(虽然你目前可能不需要)

这样处理后的datasheet图片既满足模型输入要求,又能保持最大可能的清晰度,特别适合识别封装图中的细小尺寸标注。

posted @ 2025-12-07 19:43  RolandHe  阅读(3)  评论(0)    收藏  举报