在报告实验室中创建一个 4 x 5 的图像网格 - Python

问题描述

我正在尝试使用 ReportLab 从图像目录中创建一个 4 x 5 的图像网格(每页),其方式与摄影联系表类似。我需要保持图像的纵横比,还需要下面每个图像的文件名。

我最初使用 drawimage 并手动添加所有内容,但现在我认为使用表格并将图像和文件添加到每个单元格中可能是更好的方法。任何人都可以给我一些有关执行此操作的最佳方法的指示吗?

我花了几天时间试图解决这个问题,我想我正在绕着这个圈子。提前致谢!

目前的脚本;

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','Helvetica'),('BottOMPADDING',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,y_pos)
             y_pos -= 60
             rows_rendered += 1
    
       pdf.save()
    
    createPDF(path,filename,title)