诀窍是在将图像绘制到其上之前缩放 reportlab 的画布。它似乎没有正确地从文件中提取 DPI 信息。
这个示例代码非常适合我的激光打印机:
from PIL import Image, ImageDraw, ImageFont
import reportlab.pdfgen.canvas
from reportlab.lib.units import mm
# Create an image with 300DPI, 150mm by 105mm.
dpi = 300
mmwidth = 150
mmheight = 105
pixwidth = int(mmwidth / 25.4 * dpi)
pixheight = int(mmheight / 25.4 * dpi)
im = Image.new("RGB", (pixwidth, pixheight), "white")
dr = ImageDraw.Draw(im)
dr.rectangle((0, 0, pixwidth-1, pixheight-1), outline="black")
dr.line((0, 0, pixwidth, pixheight), "black")
dr.line((0, pixheight, pixwidth, 0), "black")
dr.text((100, 100), "I should be 150mm x 105mm when printed, \
with a thin black outline, at 300DPI", fill="black")
# A test patch of 300 by 300 individual pixels,
# should be 1 inch by 1 inch when printed,
# to verify that the resolution is indeed 300DPI.
for y in range(400, 400+300):
for x in range(500, 500+300):
if x & 1 and y & 1:
dr.point((x, y), "black")
im.save("safaripdf.png", dpi=(dpi, dpi))
# Create a PDF with a page that just fits the image we've created.
pagesize = (150*mm, 105*mm)
c = reportlab.pdfgen.canvas.Canvas("safaripdf.pdf", pagesize=pagesize)
c.scale(0.24, 0.24) # Scale so that the image exactly fits the canvas.
c.drawImage("safaripdf.png", 0, 0) # , width=pixwidth, height=pixheight)
c.showPage()
c.save()
您可能需要稍微调整比例值,以使尺寸完全适合您的打印机,但上面的值非常接近。我已经用尺子检查过了;-)