Python合并多张图片成PDF


Posted in Python onJune 09, 2021

前言

最近需要将记的笔记整理成一个 pdf 进行保存,所以就研究了一下如何利用 Python 代码将拍下来的照片整个合并成一个 pdf

过程

拿到一个需求最重要的就是将大块任务拆分成一个个小模块,逐个击破。

拍照

这一步首先是将所有的书页拍好,需要注意的是要按照书的页码来拍,因为后面的排序是按照文件名进行排序的,拍照的文件名基本上是按照时间生成的,如果拍的时候乱了,到时候生成的 pdf 里面的页码也会乱掉。

用到的Python 操作库

Python 最好的地方就是有大量的第三方库能帮我们快速实现我们想要的方法,搜索到了两个库,
PyFPDF 和img2pdf,我们这里选择img2pdf来完成我们的需求

pip install img2pdf

Python遍历文件夹获取图片

dirname = "f:/wlzcool"
    imgs = []
    for fname in os.listdir(dirname):
        if not fname.endswith(".jpg"):
            continue
        path = os.path.join(dirname, fname)
        if os.path.isdir(path):
            continue
        imgs.append(path)

需要注意图片的文件名如果是纯数字且位数不一样,排序会为1之后是10而不是2,需要进行一个排序,如果是手机拍的文件就没有这个问题。

files.sort(key=lambda x: int(x[:-4]))

旋转图片展示方向并压缩像素

有的时候手机拍出来的图片是水平的,需要将其改为竖直的
用rotate旋转方向的时候需要注意加上expand=True 这个参数,否则会有黑边出现。
手机的照片像素太高,有的需要进行压缩以保证最后生成的pdf的大小适中。

img = Image.open(path)    
    if img.size[0] > img.size[1]:
        im_rotate = img.rotate(90, expand=True)
        size = (int(im_rotate.size[0] / 3), int(im_rotate.size[1] / 3))
        im_rotate = im_rotate.resize(size)
        im_rotate.save(savepath, quality=95)
    else:
        size = (int(img.size[0] / 3), int(img.size[1] / 3))
        img = img.resize(size)
        img.save(savepath, quality=95)

整体代码

写成脚本需要考虑的有很多,为了方便使用,需要将各种参数改为允许用户输入的。比如图片文件夹所在的路径,压缩比之类的

from PIL import Image
import os
import img2pdf

flag = False
while not flag:
    dirname = input("请输入图片文件夹所在路径(例如d:/wlzcool):")
    flag = os.path.exists(dirname)
    if not flag:
        print("图片文件夹所在路径不存在!")
saveflag = False
while not saveflag:
    savedirname = input("请输入目标图片文件夹所在路径(例如d:/wlzcool2):")
    saveflag = os.path.exists(savedirname)
    if not saveflag:
        print("图片文件夹所在路径不存在!")
        automakedir = input("是否自动创建对应文件夹?(是Y/否N):")
        if automakedir.strip().upper() == "Y":
            os.makedirs(savedirname)
            saveflag = True
files = os.listdir(dirname)
reductionFactor = int(input("请输入长宽压缩比(例如3):"))
if reductionFactor <= 0:
    reductionFactor = 3
isConvertBlack = input("是否输出黑白版本?(是Y/否N):").strip().upper() == "Y"
for fname in files:
    if not fname.endswith(".jpg"):
        continue
    path = os.path.join(dirname, fname)
    savePath = os.path.join(savedirname, fname)
    if os.path.isdir(path):
        continue
    img = Image.open(path)    
    if img.size[0] > img.size[1]:
        im_rotate = img.rotate(90, expand=True)
        size = (int(im_rotate.size[0] / reductionFactor), int(im_rotate.size[1] / reductionFactor))
        im_rotate = im_rotate.resize(size)
        if isConvertBlack:
            im_rotate = im_rotate.convert("L")
        im_rotate.save(savePath, quality=95)
    else:
        size = (int(img.size[0] / reductionFactor), int(img.size[1] / reductionFactor))
        img = img.resize(size)
        if isConvertBlack:
            img = img.convert("L")
        img.save(savePath, quality=95)
filename = input("请输入输出文件名(例如:第一章):")
with open(filename + ".pdf", "wb") as f:
    imgs = []
    files = os.listdir(savedirname)
    for fname in files:
        if not fname.endswith(".jpg"):
            continue
        path = os.path.join(savedirname, fname)
        if os.path.isdir(path):
            continue
        imgs.append(path)
    f.write(img2pdf.convert(imgs))

将脚本打包成exe

不是所有的电脑都有Python环境,我们需要将脚本打包成exe方便在任意一台电脑上使用。
使用 PyInstaller 来进行脚本的打包

安装 PyInstaller

pip install pyinstaller

打包脚本

在脚本所在的路径的cmd中执行以下命令即可

pyinstaller -F yourprogram.py

总结

到此这篇关于Python实现图片合并pdf的方法的文章就介绍到这了,更多相关Python 图片合并pdf内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python判断一个集合是否包含了另外一个集合中所有项的方法
Jun 30 Python
使用Python的Twisted框架构建非阻塞下载程序的实例教程
May 25 Python
深入了解Python中pop和remove的使用方法
Jan 09 Python
python SSH模块登录,远程机执行shell命令实例解析
Jan 12 Python
如何用Python合并lmdb文件
Jul 02 Python
浅谈dataframe中更改列属性的方法
Jul 10 Python
python dataframe向下向上填充,fillna和ffill的方法
Nov 28 Python
Python 获取主机ip与hostname的方法
Dec 17 Python
代码详解django中数据库设置
Jan 28 Python
Python实现的读取文件内容并写入其他文件操作示例
Apr 09 Python
python使用 __init__初始化操作简单示例
Sep 26 Python
tensorflow 自定义损失函数示例代码
Feb 05 Python
Python3 多线程(连接池)操作MySQL插入数据
jupyter notebook保存文件默认路径更改方法汇总(亲测可以)
Django rest framework如何自定义用户表
Jun 09 #Python
如何使用Python提取Chrome浏览器保存的密码
Jun 09 #Python
python缺失值的解决方法总结
Jun 09 #Python
Python提取PDF指定内容并生成新文件
Python激活Anaconda环境变量的详细步骤
Jun 08 #Python
You might like
PHP 二维数组根据某个字段排序的具体实现
2014/06/03 PHP
php防止用户重复提交表单
2015/11/02 PHP
使用ThinkPHP的自动完成实现无限级分类实例详解
2016/09/02 PHP
php下载文件超时时间的设置方法
2016/10/06 PHP
PHP使用strrev翻转中文乱码问题的解决方法
2017/01/13 PHP
Javascript中eval函数的使用方法与示例
2007/04/09 Javascript
javascript prototype原型操作笔记
2009/12/07 Javascript
基于jquery的无限级联下拉框js插件
2011/10/29 Javascript
跨浏览器的事件对象介绍
2012/06/27 Javascript
javascript 使用 NodeList需要注意的问题
2013/03/04 Javascript
对之前写的jquery分页做下升级
2014/06/19 Javascript
使用nodejs、Python写的一个简易HTTP静态文件服务器
2014/07/18 NodeJs
JavaScript数据推送Comet技术详解
2016/04/07 Javascript
微信小程序教程之本地图片上传(leancloud)实例详解
2016/11/16 Javascript
JavaScript ES6中export、import与export default的用法和区别
2017/03/14 Javascript
JS异步加载的三种实现方式
2017/03/16 Javascript
微信小程序商城项目之商品属性分类(4)
2017/04/17 Javascript
详解Angular的8个主要构造块
2017/06/20 Javascript
在React 组件中使用Echarts的示例代码
2017/11/08 Javascript
Angularjs实现页面模板清除的方法
2018/07/20 Javascript
webpack4.x开发环境配置详解
2018/08/04 Javascript
Vue绑定内联样式问题
2018/10/17 Javascript
基于JavaScript canvas绘制贝塞尔曲线
2018/12/25 Javascript
微信小程序云开发之模拟后台增删改查
2019/05/16 Javascript
在Layui 的表格模板中,实现layer父页面和子页面传值交互的方法
2019/09/10 Javascript
[01:10:24]DOTA2-DPC中国联赛 正赛 VG vs Aster BO3 第一场 2月28日
2021/03/11 DOTA
Python动态加载模块的3种方法
2014/11/22 Python
python字典键值对的添加和遍历方法
2016/09/11 Python
多个应用共存的Django配置方法
2018/05/30 Python
VS2019+python3.7+opencv4.1+tensorflow1.13配置详解
2020/04/16 Python
Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现
2020/04/22 Python
利用python清除移动硬盘中的临时文件
2020/10/28 Python
什么是聚集索引和非聚集索引
2012/01/17 面试题
自荐信的五个重要部分
2013/10/29 职场文书
演讲比赛获奖感言
2014/02/02 职场文书
岗位标兵事迹材料
2014/05/17 职场文书