简体   繁体   中英

Generate PDF using Reportlab with custom size page and best image resolution

I have a generated Image (with PIL) and I have to create a PDF with specific size that it will contains this (full size) image.

I start from size= 150mm x 105mm I generated the corresponding image 1818px x 1287px (with small border) (mm to px with 300dpi ) I use this code

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

Now I have to create the PDF file with size page = 150mm x 105mm I use reportlab and I would a pdf with the best image quality (to print).

Is possible to specify this?

Is correct to create the PDF page size with this:

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

and to draw the image:

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

The trick is to scale reportlab's Canvas before drawing the image onto it. It doesn't seem to pick up correctly the DPI information from the file.

This example code works pretty well for my laserprinter:

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()

You might want to tweak the scale values a little bit so that the dimensions fit exactly your printer, but the values above come pretty close. I've checked it with a ruler ;-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM