使用带有自定义大小页面和最佳图像分辨率的Reportlab生成PDF

时间:2018-01-31 23:32:06

标签: python django pdf python-imaging-library reportlab

我有一个生成的图像(带有PIL),我必须创建一个特定大小的PDF,它将包含这个(全尺寸)图像。

我从size= 150mm x 105mm开始 我生成了相应的图片1818px x 1287px(边框较小) (mm到px 300dpi) 我用这个代码

pp = 25.4  # 1 pp = 25,4mm
return int((dpi * mm_value) / pp)

现在我必须创建大小为page = 150mm x 105mm的PDF文件 我使用reportlab,我会使用最佳图像质量(打印)。

可以指定吗?

使用以下方法创建PDF页面大小是否正确:

W = ? // inch value??
H = ? // inch value??
buffer = BytesIO()
p = canvas.Canvas(buffer)
p.setPageSize(size=(W, H)) 

并绘制图像:

p.drawImage(img, 0, 0, width=img.width, preserveAspectRatio=True, mask='auto', anchor='c')

1 个答案:

答案 0 :(得分:0)

诀窍是在将图像绘制到其上之前缩放reportlab的Canvas。它似乎没有正确地从文件中获取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()

您可能需要略微调整刻度值,以使尺寸完全适合您的打印机,但上面的值非常接近。我用尺子检查了它; - )