使用Reportlab在PDF中添加图片后旋转的问题及旋转轴疑问
关于Reportlab中PDF图片旋转的坐标与实现方案
首先直接回答你的核心问题:Reportlab Canvas的默认坐标原点是PDF的左下角(0,0),而旋转操作默认是围绕当前画布的原点(也就是你当前设置的坐标原点,默认是(0,0))进行的。这也是你旋转图片时出问题的关键——如果直接旋转,图片会围绕左下角转,而不是你预期的图片自身中心。
要实现围绕图片自身中心(或任意指定点)旋转,需要遵循「平移-旋转-平移」的坐标变换逻辑,具体步骤如下:
关键原理
Reportlab的坐标变换是基于当前原点的:
translate(dx, dy):把当前原点移动到(dx, dy)的位置rotate(angle):围绕当前原点旋转指定角度(角度是顺时针方向,单位是度)
所以要让图片围绕自身中心旋转,你需要:
- 先把原点移到图片的中心位置
- 执行旋转操作
- 再把原点移回图片左上角相对于中心的偏移位置(这样绘制图片时,左上角的坐标就对应旋转后的正确位置)
完整代码示例
假设你要把一张图片放在画布的(x, y)位置,图片宽度为img_w,高度为img_h,旋转角度为rotate_angle:
from reportlab.pdfgen import canvas from io import BytesIO output = BytesIO() c = canvas.Canvas(output) # 假设你的图片路径、位置、尺寸和旋转角度 img_path = "your_image.png" x_pos = 100 # 图片原始左上角的x坐标 y_pos = 100 # 图片原始左上角的y坐标 img_w = 200 img_h = 150 rotate_angle = 45 # 顺时针旋转45度 c.saveState() # 保存当前画布状态,之后可以恢复 # 第一步:平移到图片的中心位置 c.translate(x_pos + img_w/2, y_pos + img_h/2) # 第二步:执行旋转 c.rotate(rotate_angle) # 第三步:平移回图片左上角相对于中心的偏移(这样绘制时,图片中心就是刚才的旋转中心) c.translate(-img_w/2, -img_h/2) # 绘制图片,此时图片已经是旋转后的状态 c.drawImage(img_path, 0, 0, width=img_w, height=img_h) c.restoreState() # 恢复画布状态,不影响后续绘制 c.save() output.seek(0)
常见问题说明
- 如果想围绕图片的其他点旋转(比如左上角),只需要调整第一次
translate的目标坐标即可:比如围绕左上角旋转,就直接translate(x_pos, y_pos),然后旋转,之后不需要第二次translate,直接drawImage(img_path, 0, 0, ...)就行。 - 旋转角度是顺时针方向的,如果需要逆时针旋转,传入负数角度即可(比如
rotate(-45))。
内容的提问来源于stack exchange,提问作者Cyril N.




