python | 将照片按顺序制作成PDF
把图片按照顺序合成PDF。
需求分析:
- 要保证图片的顺序,只能从文件命名上下手,所以可以把图片命名成数字,数字小的排前面,数字大的排后面,类似这样:
- 这样命名完后,全是数字,又不好分辨,需要给文件加个备注,可以用一个特殊符号来分割数字和备注,类似这样:
- 如果顺序整理好过后,发现有点问题,需要在某处插入一张照片怎么办?可以用小数来解决,类似这样:
大体需求就这样了,现在开始写代码实现。
网上查了一下,python的PDF库 FPDF 可以实现图片插入的功能,先pip install FPDF 一波。
先把图片排好序:
def get_ordered_file_list(): tmp_file_list = [] for file in os.listdir(dir): file_name, suffix = os.path.splitext(file) if suffix[1:].lower() in ['jpg', 'jpeg', 'png', 'bmp']: try: num = float(file_name.split('-')[0]) tmp_file_list.append((num, os.path.join(dir, file))) except: print(file, '提取顺序失败,未加入PDF,可重新将图片命名,重新运行程序') return [a[1] for a in sorted(tmp_file_list, key=lambda x: x[0])]
制作PDF的操作也很简单:
pdf = FPDF(unit="pt") # 第一步,创建PDF对象 pdf.add_page() # 第二步,增加一页 pdf.image(img_path) # 第三步,加照片 pdf.output('XXX.pdf', 'F') # 第四步,保存
期间参照源码,做了些许改动:对图片进行缩放,对页面的横板竖版进行调整,增加了页码。
完整代码如下:
from fpdf import FPDF from PIL import Image import os import sys class PDFTool(): def __init__(self, dir_path): self.pdf = FPDF(unit="pt") self.pdf.set_font('arial',size=16) self.dir = dir_path self.img_type = ['jpg', 'jpeg', 'png', 'bmp'] self.file_list = self.get_ordered_file_list() def get_ordered_file_list(self): tmp_file_list = [] for file in os.listdir(self.dir): file_name, suffix = os.path.splitext(file) if suffix[1:].lower() in self.img_type: try: num = float(file_name.split('-')[0]) tmp_file_list.append((num, os.path.join(self.dir, file))) except: print(file, '提取顺序失败,未加入PDF,可重新将图片命名,重新运行程序') return [a[1] for a in sorted(tmp_file_list, key=lambda x: x[0])] def makePdf(self): if not self.file_list: print('没有满足条件的照片') return for file in self.file_list: img = Image.open(file) img_width, img_height = img.size # 595.28,841.89 rate = 0.95 if img_width > img_height: self.pdf.add_page('L') if (img_width / img_height) > (841.89 / 595.28): rate *= 841.89 / img_width else: rate *= 595.28 / img_height self.pdf.image(file, 20, 20, int(img_width * rate), int(img_height * rate)) self.pdf.text(841//2-10,595-10,str(self.pdf.page_no())) else: self.pdf.add_page('P') if (img_width / img_height) > (595.28 / 841.89): rate *= 595.28 / img_width else: rate *= 841.89 / img_height self.pdf.image(file, 20, 20, int(img_width * rate), int(img_height * rate)) self.pdf.text(595 // 2 - 10, 841 - 10, str(self.pdf.page_no())) self.pdf.output(os.path.join(self.dir, os.path.split(self.dir)[-1]) + '.pdf', "F") print(self.dir, '下面有个和文件夹同名的PDF 打开看看') if __name__ == '__main__': tool = PDFTool(sys.argv[1]) tool.makePdf()
最终效果图:
原文链接:https://blog.csdn.net/qq_40310224/article/details/108964839