在 Report Lab 中创建 4 x 5 的图像网格 - Python
Creating a 4 x 5 grid of images within Report Lab - Python
我正在尝试使用 ReportLab 从图像目录创建一个 4 x 5 图像网格(每页),其方式类似于照相联系表。我需要保持图像的纵横比,还需要下面每个图像的文件名。
我最初使用 drawimage 并手动添加所有内容,但现在我认为 table 并将图像和文件名添加到每个单元格中可能是更好的方法。谁能给我一些关于执行此操作的最佳方法的指示?
我花了几天时间试图解决这个问题,我想我正在绕圈子。提前致谢!
截至目前的脚本;
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle
from reportlab.lib.pagesizes import A4
from PIL import Image
import os
def rowGen(lst, n):
for i in range(0, len(lst), n):
yield lst[i:i + n]
def makePDF(document_title, data):
pdf = SimpleDocTemplate(
document_title,
pagesize = A4
)
style = TableStyle([
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('FONTNAME', (0, 0), (-1, -1), 'Helvetica'),
('BOTTOMPADDING', (0, 0), (-1, -1), 12),
])
table = Table(data) #Creates and adds the data to the table
table.setStyle(style) #Sets style to the above defined style
elements = [] #Creates an empty elements list
elements.append(table) #Lays out the elements
pdf.build(elements)
path = 'Images/'
image_list = [i for i in os.listdir(path) if i.endswith('.jpg')] #list of images in selected directory
data = [i for i in rowGen(image_list, 4)]
makePDF('Test.pdf', data)
因此,经过几天的思考,我得出了以下想法。我对此很陌生,我相信有更好的方法,但如果它对任何人有帮助:
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import mm
from reportlab.lib.utils import ImageReader
from PIL import Image
import os
path = 'path/to/my/images/'
filename = 'test.pdf'
title = 'Test'
def createPDF(path_to_images, document_name, document_title):
def rowGen(list_of_images): #Creates a list of 4 image rows
for i in range(0, len(list_of_images), 4):
yield list_of_images[i:i + 4]
def renderRow(path_to_images, row, y_pos): #Renders each row to the page
x_pos = 5 #starting x position
thumb_size = 180, 180 #Thumbnail image size
for i in row:
image_filename = i #Saves the filename for use in the draw string operation below
img = Image.open(os.path.join(path_to_images, i)) #Opens image as a PIL object
img.thumbnail(thumb_size) #Creates thumbnail
img = ImageReader(img) #Passes PIL object to the Reportlab ImageReader
#Lays out the image and filename
pdf.drawImage(img, x_pos * mm , y_pos * mm, width = 125, height = 125, preserveAspectRatio=True, anchor='c')
pdf.drawCentredString((x_pos + 22) * mm, (y_pos - 7) * mm, image_filename)
x_pos += 51 #Increments the x position ready for the next image
images = [i for i in os.listdir(path_to_images) if i.endswith('.jpg')] #Creates list of images filtering out non .jpgs
row_layout = list(rowGen(images)) #Creates the layout of image rows
pdf = canvas.Canvas(document_name, pagesize=A4, pageCompression=1)
pdf.setTitle(document_title)
rows_rendered = 0
y_pos = 250 #Sets starting y pos
pdf.setFont('Helvetica', 10)
for row in row_layout: #Loops through each row in the row_layout list and renders the row. For each 5 rows, makes a new page
if rows_rendered == 5:
pdf.showPage()
pdf.setFont('Helvetica', 10)
y_pos = 250
rows_rendered = 0
else:
renderRow(path_to_images, row, y_pos)
y_pos -= 60
rows_rendered += 1
pdf.save()
createPDF(path, filename, title)
我正在尝试使用 ReportLab 从图像目录创建一个 4 x 5 图像网格(每页),其方式类似于照相联系表。我需要保持图像的纵横比,还需要下面每个图像的文件名。
我最初使用 drawimage 并手动添加所有内容,但现在我认为 table 并将图像和文件名添加到每个单元格中可能是更好的方法。谁能给我一些关于执行此操作的最佳方法的指示?
我花了几天时间试图解决这个问题,我想我正在绕圈子。提前致谢!
截至目前的脚本;
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle
from reportlab.lib.pagesizes import A4
from PIL import Image
import os
def rowGen(lst, n):
for i in range(0, len(lst), n):
yield lst[i:i + n]
def makePDF(document_title, data):
pdf = SimpleDocTemplate(
document_title,
pagesize = A4
)
style = TableStyle([
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('FONTNAME', (0, 0), (-1, -1), 'Helvetica'),
('BOTTOMPADDING', (0, 0), (-1, -1), 12),
])
table = Table(data) #Creates and adds the data to the table
table.setStyle(style) #Sets style to the above defined style
elements = [] #Creates an empty elements list
elements.append(table) #Lays out the elements
pdf.build(elements)
path = 'Images/'
image_list = [i for i in os.listdir(path) if i.endswith('.jpg')] #list of images in selected directory
data = [i for i in rowGen(image_list, 4)]
makePDF('Test.pdf', data)
因此,经过几天的思考,我得出了以下想法。我对此很陌生,我相信有更好的方法,但如果它对任何人有帮助:
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import mm
from reportlab.lib.utils import ImageReader
from PIL import Image
import os
path = 'path/to/my/images/'
filename = 'test.pdf'
title = 'Test'
def createPDF(path_to_images, document_name, document_title):
def rowGen(list_of_images): #Creates a list of 4 image rows
for i in range(0, len(list_of_images), 4):
yield list_of_images[i:i + 4]
def renderRow(path_to_images, row, y_pos): #Renders each row to the page
x_pos = 5 #starting x position
thumb_size = 180, 180 #Thumbnail image size
for i in row:
image_filename = i #Saves the filename for use in the draw string operation below
img = Image.open(os.path.join(path_to_images, i)) #Opens image as a PIL object
img.thumbnail(thumb_size) #Creates thumbnail
img = ImageReader(img) #Passes PIL object to the Reportlab ImageReader
#Lays out the image and filename
pdf.drawImage(img, x_pos * mm , y_pos * mm, width = 125, height = 125, preserveAspectRatio=True, anchor='c')
pdf.drawCentredString((x_pos + 22) * mm, (y_pos - 7) * mm, image_filename)
x_pos += 51 #Increments the x position ready for the next image
images = [i for i in os.listdir(path_to_images) if i.endswith('.jpg')] #Creates list of images filtering out non .jpgs
row_layout = list(rowGen(images)) #Creates the layout of image rows
pdf = canvas.Canvas(document_name, pagesize=A4, pageCompression=1)
pdf.setTitle(document_title)
rows_rendered = 0
y_pos = 250 #Sets starting y pos
pdf.setFont('Helvetica', 10)
for row in row_layout: #Loops through each row in the row_layout list and renders the row. For each 5 rows, makes a new page
if rows_rendered == 5:
pdf.showPage()
pdf.setFont('Helvetica', 10)
y_pos = 250
rows_rendered = 0
else:
renderRow(path_to_images, row, y_pos)
y_pos -= 60
rows_rendered += 1
pdf.save()
createPDF(path, filename, title)