为每一个文件夹内的图片生成 PDF

需求

有很多文件夹,这些文件夹内存有若干图片。现在需要按文件夹来生成这些图片的 PDF 文件。

思路

工具

通过 Python 进行实现

方法

使用 Pillow 来打开、存储为PDF

其他细节

  • 生成的文件保存在 pdf 文件夹中,该文件夹已提前创建
  • 只处理 jpgpng 格式的文件
  • 同一个 PDF 中图片的顺序按文件名的顺序进行排序
  • 同一个文件夹内图片数量有限,但文件夹内图片总大小不超过 100 M,无需考虑内存优化
  • 没有空文件夹

实现

from PIL import Image
import os

for root, dirs, files in os.walk("."):
    for dir in dirs:
        
        flist = []
        for file in os.listdir(os.path.join(root, dir)):
            if file.endswith(".jpg"):
                flist.append(file)
        
        # 忽略空文件夹
        if len(flist) == 0:
            continue
        
        # 如果需要调整图片排序方法,在这里进行处理
        flist.sort()

        # 使用 Pillow 库打开图片
        images = []
        for file in flist:
            images.append(Image.open(os.path.join(root, dir, file)))

        # 保存 PDF 文件
        pdf_file = os.path.join(root, "pdf", dir + ".pdf")
        images[0].save(pdf_file, save_all=True, append_images=images[1:])
本文转载于网络 如有侵权请联系删除

相关文章

  • python torch.utils.data.DataLoader使用方法

    PyTorch中数据读取的一个重要接口是torch.utils.data.DataLoader,该接口定义在dataloader.py脚本中,只要是用PyTorch来训练模型基本都会用到该接口,该接口主要用来将自定义的数据读取接口的输出或者PyTorch已有的数据读取接口的输入按照batchsize封装成Tensor,后续只需要再包装成Variable即可作为模型的输入,因此该接口有点承上启下的作用,比较重要。数据加载器,结合了数据集和取样器,并且可以提供多个线程处理数据集。在训练模型时使用到此函数,用来把训练数据分成多个小组,此函数每次抛出一组数据。直至把所有的数据都抛出。就是做一个数据的初始化。生成迭代数据非常方便,请看如下示例:""" 批训练,把数据变成一小批一小批数据进行训练。 DataLoader就是用来包装所使用的数据,每次抛出一批数据 """ importtorch importtorch.utils.dataasData BATCH_SIZE=5 x=torch.linspace(1,10,10) y=to

  • 产业安全观智库访谈 | 疫情和“新基建”双重驱动,安全产业发展按下“加速键”

    「产业安全观智库访谈」栏目简介:在中国产业互联网发展联盟的指导下,腾讯安全联合安在新媒体共同启动了「产业安全观智库访谈」。围绕产业安全的发展趋势,结合当前实事热点,诚邀业界专家、学者及意见领袖倾情分享。希望借此启发思考、引导讨论、催生行动,为中国产业互联网及产业安全在新形势下的应变和发展寻求思路。2003年的“非典”疫情掀起了中国电子商务的第一波发展热潮。在线购物、在线支付和现代化物流快速普及,腾讯、阿里、百度、京东等巨头企业迅猛发展,消费互联网由此启蒙。“非典”的危机无疑加速了中国互联网发展,在此后的17年间,国内互联网产业逐步升级成为新的基础设施,并为中国经济的增长提供了重要动力。但随着“人口红利”的消退,云计算、人工智能、大数据等技术的融合应用,“产业互联网”成为了互联网产业第二次大发展的全新标识。在这个关键的窗口期,“新冠”疫情的突然出现使传统产业受到巨大冲击:大量工厂和制造停工、春节假期和全民抗疫严重影响终端触达、餐饮娱乐等线下服务全面停滞……为了能够“活下去”,大量传统行业将线下业务转至线上,开启了数字化升级的道路。与此同时,包括远程办公、远程教育、社区管理等应用需求的暴增

  • Python-100例(5-6) 排序&斐波那契数列

    2019年第23篇,总47篇文章 本文大于2500字,阅读大约需要10分钟前面分享的四道题目如下:Python-100|练习题01&列表推导式Python-100练习题02Python-100练习题03完全平方数Python-100练习题04判断天数这次是分享Python-100例的第五和第六题,分别是排序和斐波那契数列问题,这两道题目其实都是非常常见的问题,特别是后者,一般会在数据结构的教程中,讲述到递归这个知识点的时候作为例题进行介绍的。Example-5排序题目:输入三个整数x,y,z,请把这三个数由小到大输出。思路考虑令x保存最小的数值,即先令x分别和y,z作比较,通过比较后,x变成最小值,接着y和z比较,即可完成排序代码实现代码实现上有两种,一种就是手动实现排序过程,另一种就是采用内置函数。defsort_numbers_1(): x=int(input('integer:\n')) y=int(input('integer:\n')) z=int(input('integer:\n')) print(&#x

  • 能进互联网公司的个个都是人才

    互联网公司近年来发展飞快, 越来越多年轻人想要或者选择投入其中。不过,想进来必须通过面试,尤其是某些公司,对于员工的筛选就像千军万马过独木桥......想要脱颖而出,就必须得合拍。时刻会心一击,就是公司想要的人!请看下面的示例——1.程序员----错误示范-2.产品经理----错误示范-3.新媒体运营----错误示范-4.商务---错误示范-5.设计师 -- -错误示范-......--

  • 实现导航栏下拉菜单列表页面

    版权声明:本文为博主原创文章,未经博主允许不得转载。https://blog.csdn.net/linzhiqiang0316/article/details/798588181.wxml页面代码:<!--选项卡--><viewclass="tabTitboxtcbg_f"><viewclass="flex1{{tab[index]?'active':''}}"wx:for="{{tabTxt}}"wx:key=""data-index="{{index}}"bindtap="filterTab"><text>{{item}}</text><imagewx:if="{{index===tabTxt.length-1}}"src="/images/arrow.png"></image></view>

  • Ignatius and the Princess II

    IgnatiusandthePrincessII TimeLimit:2000/1000MS(Java/Others)    MemoryLimit:65536/32768K(Java/Others) TotalSubmission(s):10018    AcceptedSubmission(s):5839 ProblemDescriptionNowourherofindsthedoortotheBEelzebubfeng5166.Heopensthedoorandfindsfeng5166isabouttokillourprettyPrincess.ButnowtheBEelzebubhastobeatourherofirst.feng5166says,"Ihavethreequestionforyou,ifyoucanworkthemout,IwillreleasethePrincess,oryouwillbemydinner,too."Ignatiussaysconfidently,"OK,atlast,IwillsavethePrincess

  • 自绘制HT For Web ComboBox下拉框组件

    传统的HTML5的下拉框select只能实现简单的文字下拉列表,而HTforWeb通用组件中ComboBox不仅能够实现传统HTML5下拉框效果,而且可以在文本框和下拉列表中添加自定义的小图标,让整个组件看起来更直观,今天我就如何制定ComboBox自定义下拉框做一番探讨。首先我们先来目睹下效果:看起来跟普通的ComboBox好像也没什么特殊的,是的,按照规范的ComboBox设计,完全可以实现同样的效果,但是今天的主要任务并不是讨论有多少实现方案,今天的首要任务是介绍HTforWeb的ComboBox自定义下拉列表的用法。那么接下来就开始具体的方案介绍,废话不多说,上代码:functioncreateGradientComboBox(dataModel){ varsm=dataModel.sm(), gradientComboBox=newht.widget.ComboBox(), gradients=['linear.southwest','linear.southeast','linear.northwest',

  • 在浏览器地址栏按回车、F5、Ctrl+F5刷新网页的区别

    不少同学问,不都是刷新吗?还有什么区别?其实,还是有的。其中,在地址栏按回车又分为两种情况。一是请求的URI在浏览器缓存中未过期,此时,使用Firefox的firebug插件在浏览器里显示的HTTP请求消息头如下:Host   192.168.3.174:8080User-Agent   Mozilla/5.0(WindowsNT5.1;rv:5.0)Gecko/20100101Firefox/5.0Accept   text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language   zh-cn,zh;q=0.5Accept-Encoding   gzip,deflateAccept-Charset   GB2312,utf-8;q=0.7,*;q=0.7Connection   kee

  • 【CF455A Boredom】题解

    题目链接 题目 Alexdoesn'tlikeboredom.That'swhywheneverhegetsbored,hecomesupwithgames.Onelongwintereveninghecameupwithagameanddecidedtoplayit. Givenasequence$a$consistingof$n$integers.Theplayercanmakeseveralsteps.Inasinglestephecanchooseanelementofthesequence(let'sdenoteit$a_{k}$)anddeleteit,atthatallelementsequalto$a_{k}+1$and$a_{k}-1$alsomustbedeletedfromthesequence.Thatstepbrings$a_{k}$pointstotheplayer. Alexisaperfectionist,sohedecidedtogetasmanypointsaspossible.Helphim. 力克斯不喜欢无聊。 所以每当他感到无聊他就会想出一些游

  • Oracle对中文内容排序

    一、需求说明 目前需要开发的Oracle数据库中有些表记录的内容是中文的,需要按照中文的方式进行排序。 二、分析思路如果查询的结果字符集为ZHS16GBK/ZH16GBK,则使用orderby默认是按照汉字的拼音顺序进行排序的;否则为其他(如UTF8等字符集),那么汉字的排序是按照BINARY(二进制)排序的,那么此时可以使用Oracle提供的NLS_SORT进行排序。 --查看当前数据库使用的字符集(语法) SELECTuserenv('language')FROMdual; --查看整个数据库的NLS_SORT排序规则(语法) selectvaluefromnls_database_parameterswhereparameter='NLS_SORT'; --查看当前会话的NLS_SORT排序规则(语法) selectvaluefromnls_session_parameterswhereparameter='NLS_SORT';复制 三、解决方法 这是人员表中的原内容:    3.1、按照拼音排序 --按照拼音排序(语法) SELECT字段名FRO

  • Java使用Log日志系统(common-logging和log4j)

    使用common-logging和log4j 准备开一大项目的话,日志系统必不可少。Apache为了让众多的日志工具有一个相同操作方式,实现了一个通用日志工具包:commons-logging。而Log4j基本上是Java平台上最好的日志组件了。 使用ommons-logging的Log接口,并由commons-logging在运行时决定使用哪种日志架构(如Log4j)。现在,Apache通用日志工具commons-logging和Log4j已经成为Java日志的标准工具。 日志级别 log4j主要有如下的信息级别: fatal:非常严重的错误,导致系统中止。期望这类信息能立即显示在状态控制台上。 error:其它运行期错误或不是预期的条件。期望这类信息能立即显示在状态控制台上。 warn:使用了不赞成使用的API、非常拙劣使用API,‘几乎就是’错误,其它运行时不合需要和不合预期的状态但还没必要称为“错误”。期望这类信息能立即显示在状态控制台上。 info:运行时产生的有意义的事件。期望这类信息能立即显示在状态控制台上。 debug:系统流程中的细节信息。期望这类信

  • 2022.7.31周学习总结

    一.本周学习进度   1.差分约束看完了,并且完成了几道练习题   2.Dp题刷了12道   3.牛客打了两场 二.下周学习计划   1.继续练习Dp习题   2.补一下牛客的Dp题   3.cf的数据结构的题每天一道   4.练习一下三分题目 三.本周列题总结  1.差分约束   AcWing1169.糖果-AcWing   AcWing362.区间-AcWing   AcWing1170.排队布局-AcWing   AcWing393.雇佣收银员-AcWing   P5960【模板】差分约束算法-洛谷|计算机科学教育新生态(luogu.com.cn)   P4926[1007]倍杀测量者-洛谷|计算机科学教育新生态(luogu.com.cn)   2.Dp   CF2BTheleastroundway-洛谷|计算机科学教育新生态(luogu.com.cn)   CF3BLorry-洛谷|计算机科学教育新生态(luogu.com.cn)   CF4DMysteriousPresent-洛谷|计算机科学教育新生态(luogu.com.cn)   CF5CLongestRegularBr

  • css_水平格式化,margin设置为auto

    目录当不设置auto值且七个属性值加在一起小于包含块宽度当只有一个值设置为auto时当有两个值设置为auto时当有三个值设置为auto时 水平格式化有七个属性,分别是:margin-left,border-left,padding-left,width,padding-right,border-right,margin-right七个。其中只有margin-left,width,margin-right三个属性允许被设置为auto。 水平格式化七个属性的值加在一起必须等于元素包含块的宽度,这也是允许其中三个属性设置为auto的前提。 当不设置auto值且七个属性值加在一起小于包含块宽度 这种时候用户代理会强制把margin-right设置为auto(仅限从左到右读的语言)。但是通过getComputedStyle()来获取margin-right依然得到的是开发者的设定值。 当只有一个值设置为auto时 当只有一个值设置为auto时,它可以是width,margin-left,margin-right三个中的任一个。只有这个一个未知数时,用户代理会计算得出auto的值以保证七个

  • 浏览器指纹 fingerprintjs

    使用示例: <!DOCTYPEhtml> <htmllang="en"> <head> <metacharset="UTF-8"> <metahttp-equiv="X-UA-Compatible"content="IE=edge"> <metaname="viewport"content="width=device-width,initial-scale=1.0"> <title>Document</title> </head> <body> <inputvalue=""id="input"style="width:300px;"/> <divid="user"></div> <script> constfpPromise=import('https://openfpcdn.io/fingerprintjs/v3') .then(e=>e.load()) fpPromise .then(fp=>fp.

  • maxwell源码分析

    ====

  • 算法练习-有序数查找

    练习问题来源 https://wizardforcel.gitbooks.io/the-art-of-programming-by-july/content/04.01.html 要求 给定一个有序的数组,查找某个数是否在数组中,请编程实现。 解法 在有序数组中查找,采用二分查找。 要准确实现二分查找,首先要把握下面几个要点: 关于right的赋值 right=n-1=>while(left<=right)=>right=middle-1; right=n=>while(left<right)=>right=middle; middle的计算不能写在while循环外,否则无法得到更新。 复制 代码实现 intBinarySearch(intarray[],intn,intvalue) { intleft=0; intright=n-1; while(left<=right) { intmiddle=left+((right-left)>>1);//防止溢出 if(array[middle]>value) { right=mid

  • Mysql语句 explain命令性能分析

    在工作中,我们需要对select语句进行优化,以便节约资源与性能,提升查询速度。但是,我们应该怎么查询一个sql语句的性能呢?这里记录一种mysql自带的性能查询命令:EXPLAIN。 博客主要参照:https://www.cnblogs.com/gomysql/p/3720123.html的命令详解 一般情况下使用explain命令格式为:explainselect…from…[where…]    这条命令会返回以下基本结果:当然复杂的语句会返回更多的字段。        网络上关于这些字段的描述有很多,但是我关心的只有几个重要的字段: 1.type:  这列最重要,显示了连接使用了哪种类别,是使用Explain命令分析性能瓶颈的关键项之一。  结果值从好到坏依次是:system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_su

  • Oracle数据库表被锁了,如何解锁

    1.首先查看数据库中哪些表被锁了,找到sessionID: 使用sql: selectb.owner,b.object_name,a.session_id,a.locked_modefromv$locked_objecta,dba_objectsbwhereb.object_id=a.object_id; OWNER:数据表的所有者用户 OBJECT_NAME:被锁住的表名 SESSION_ID:会话ID LOCKED_MODE:锁级别 锁级别分为6级: 1级锁有:Select 2级锁有:Selectforupdate,LockForUpdate,LockRowShare 3级锁有:Insert,Update,Delete,LockRowExclusive 4级锁有:CreateIndex,LockShare 5级锁有:LockShareRowExclusive  6级锁有:Altertable,Droptable,DropIndex,Truncatetable,LockExclusive 2.再执行该语句,查看会话id select b.username,b.si

  • 推荐几个Mac/Linux下比较好用的工具

    1、Tmux,连接开发机可以让在任务在开发机一直执行,不用nohup&这种了也相对稳定,还有session可以记录当时的状态。 常用命令: tmuxnew-sname指定名字开启一个tmuxsession   tmuxls显示sessions   tmuxa-tname指定name连接到session   Ctrl+b,D断开一个session   Ctrl+b,x关闭一个session   2、mosh,https://mosh.org/,替代ssh,用法跟ssh一样,使用udp,无论断网还是更换IP都不会断开跟开发机的连接   3、spaceVim,绑定了一些插件的vim,适合我这种懒人,https://github.com/SpaceVim/SpaceVim   4、tldr,cheat,命令使用示例   5、z,根据目录使用历史,直接跳到对应目录,安装步骤:1、gitclone https://github.com/rupa/z.git 2、编辑.zshrc,增加一行.$

  • 【原】Mongodb相关资料

    Mongodb与关系型数据库对比 Mongodb与关系型数据库对比 由于之前主要接触的是关系型数据库,所以主要将Mongodb与关系型数据库进行对比:主要从术语、Server与Client、数据定义语言和操作语言四个方面进行比较。 1.术语 Mongodb与关系型数据库的术语对比如下图 关系型数据库术语 MongoDB术语 database database table collection row document or BSON document column field index index tablejoins embeddeddocumentsandlinking primarykeySpecifyanyuniquecolumnorcolumncombinationasprimarykey. primarykeyInMongoDB,theprimarykeyisautomaticallysettothe _idfield. aggregation(e.g.groupby) aggregatio

  • js闭包

    functionfoo(){vara=2;functionbar(){console.log(a);}returnbar;}varbaz=foo();baz();//2——朋友,这就是闭包的效果。 函数bar()的词法作用域能够访问foo()的内部作用域,然后我们将bar()函数本身当做一个值类型进行传递,在这个例子中,我们将bar所引用的函数对象本身当做返回值. 在foo()执行完成之后,其返回值(),也就是内部的bar()函数,复制给变量baz并调用baz(),世纪上只是通过不同的标识符引用调用了内部的函数bar(). bar()显然可以被正常执行.但是在这个例子中,它在自己定义的词法作用域之外的地方执行. 在foo()执行完之后,通常会期待foo()的整个内部作用域被销毁,因为我们知道引擎,有垃圾回收器来释放不再使用的内存空间.由于看上去foo()的内容不会再被使用,所以很自然地会考虑对齐进行垃圾回收.而闭包的神奇之处真在于此,他们阻止这件事情的发生.事实上内部作用域毅然存在,因此没有被回收,谁在使用这个内部作用域,原来是bar()本身.bar()涵盖foo()内部作用域的闭包,

相关推荐

推荐阅读