jpg png bmp图片批量转换为pdf格式文件python脚本工具

  • A+
所属分类:编程语言

转存源码:图片批量转换 图片转pdf格式文件,python版支持jpg转pdf,png转pdf以及bmp转pdf

  1. # -*- coding: utf-8 -*-
  2. # -------------------------------------------------------------------------------
  3. # @File     : Convert2PDF.py
  4. # @Created  : 2017/12/25 下午3:03
  5. # @Software : PyCharm
  6. # @Author   : Liu.Qi
  7. # @Contact  : liuqi_0725@aliyun.com
  8. # @Desc     : 目的?
  9. # -------------------------------------------------------------------------------
  10. import os
  11. from reportlab.platypus import SimpleDocTemplate,Image, PageBreak
  12. from reportlab.lib.pagesizes import A4, landscape
  13. import time
  14. from PIL import Image as pilImage
  15. # 支持的图片类型
  16. __allow_type = [".jpg", ".jpeg", ".bmp", ".png"]
  17. __rootDir = ""
  18. def convert_images2PDF_one_dir(file_dir,save_name=None ,filename_sort_fn=None):
  19.     '''
  20.     转换一个目录文件夹下的图片至 PDF
  21.     :param file_dir:
  22.     :param file_name: 如果为空,则以当前文件夹的名称命名, 必须是.pdf结尾
  23.     :param filename_sort_fn:
  24.     文件名排序的回调函数,当此回调函数有值时,在文件名排序时,会回调,并将 file 的完整路径返回。
  25.     回调函数需要返回一个可转换整形的内容,函数根据此回调函数的返回值,对文件名排序
  26.     比如:
  27.         现实中,文件名会是
  28.         test_01_doc_0.png、
  29.         test_01_doc_1.png、
  30.         test_01_doc_2.png、
  31.         test_01_doc_3.png、
  32.         test_01_doc_11.png、
  33.         test_01_doc_21.png
  34.         等等,我们也希望读取出来的顺序如此,但是 mac、win 下,包括sort 排序出来的结果都不理想。
  35.         结果为
  36.         test_01_doc_0.png、
  37.         test_01_doc_1.png、
  38.         test_01_doc_11.png、
  39.         test_01_doc_2.png、
  40.         test_01_doc_21.png、
  41.         test_01_doc_3.png
  42.         不是我们想要得到的。
  43.         通过 filename_sort_fn(filename) 返回的整形数字,对齐正确的排序
  44.     '''
  45.     book_pages = []
  46.     for parent, dirnames ,filenames in os.walk(file_dir):
  47.         # 只遍历最顶层
  48.         if parent != file_dir :
  49.             continue
  50.         # 过滤文件中所有的图片
  51.         for file_name in filenames:
  52.             file_path = os.path.join(parent, file_name)
  53.             # 是否图片
  54.             if __isAllow_file(file_path) :
  55.                 book_pages.append(file_path)
  56.         # 取当前目录的文件名为书名
  57.         if save_name == None :
  58.             save_name = os.path.join(file_dir,(os.path.basename(file_dir) + ".pdf"))
  59.         else :
  60.             save_name = os.path.join(file_dir,save_name)
  61.         if len(book_pages) > 0 :
  62.             # 开始转换
  63.             print("[*][转换PDF] : 开始. [保存路径] > [%s]" % (save_name))
  64.             beginTime = time.clock()
  65.             __converted(save_name , book_pages ,filename_sort_fn)
  66.             endTime = time.clock()
  67.             print("[*][转换PDF] : 结束. [保存路径] > [%s] , 耗时 %f s " % (save_name, (endTime - beginTime)))
  68.         else :
  69.             print("该目录下没有找到任何图片文件.如果是多重目录,尝试使用 convert_images2PDF_more_dirs 函数")
  70. def convert_images2PDF_more_dirs(dirPath):
  71.     """
  72.     转换一个目录文件夹下的图片至 PDF
  73.     :param file_dir:
  74.     :param filename_sort_fn:
  75.     """
  76.     # 已经找到目录
  77.     __dirs = {}
  78.     for parent, dirnames, filenames in os.walk(dirPath):
  79.         for dirname in dirnames:
  80.             # 假设每个文件夹下都有图片,都是一本书
  81.             dirData = {"name": "", "pages": [], "isBook": False}
  82.             dirName = dirname.split('/')[0]
  83.             dirData['name'] = dirName
  84.             __dirs[dirName] = dirData
  85.         # 查找有无图片
  86.         for filename in filenames:
  87.             real_filename = os.path.join(parent, filename)
  88.             # 取父文件夹名称为书名
  89.             parentDirName = real_filename.split('/')[-2]
  90.             if parentDirName in __dirs.keys():
  91.                 dirJsonData = __dirs[parentDirName]
  92.             else:
  93.                 continue
  94.             # 检查是否图片
  95.             if __isAllow_file(real_filename) :
  96.                 # 将图片添加至书本
  97.                 dirJsonData['pages'].append(real_filename)
  98.                 # 如果该书的isbook 是false 改为true
  99.                 if not dirJsonData['isBook']:
  100.                     dirJsonData['isBook'] = True
  101.     index = 1
  102.     for dirName in __dirs.keys():
  103.         dirData = __dirs[dirName]
  104.         if dirData['isBook']:
  105.             print("[*][转换PDF] : 开始. [名称] > [%s]" % (dirName))
  106.             beginTime = time.clock()
  107.             __converted(os.path.join(dirPath,(dirData['name'] + ".pdf")) , dirData['pages'])
  108.             endTime = time.clock()
  109.             print("[*][转换PDF] : 结束. [名称] > [%s] , 耗时 %f s " % (dirName, (endTime - beginTime)))
  110.             index += 1
  111.     print("[*][所有转换完成] : 本次转换检索目录数 %d 个,共转换的PDF %d 本 " % (len(__dirs), index - 1))
  112. def __isAllow_file(filepath):
  113.     """
  114.     是否允许的文件
  115.     :param file:
  116.     :return:
  117.     """
  118.     if filepath and (os.path.splitext(filepath)[1] in __allow_type):
  119.         return True
  120.     return False
  121. def __converted(save_book_name,book_pages=[],filename_sort_fn=None):
  122.     """
  123.     开始转换
  124.     :param book_name: 保存的文件名(包含路径)
  125.     :param book_pages: 图片数组
  126.     :param filename_sort_fn: 文件名排序规则
  127.     :return:
  128.     """
  129.     # A4 纸的宽高
  130.     __a4_w, __a4_h = landscape(A4)
  131.     # 对数据进行排序
  132.     if (filename_sort_fn == None):
  133.         # 将按图片按名称的ASCII排序以避免错乱问题
  134.         book_pages.sort()
  135.     else:
  136.         # lambda 匿名函数, 第一个参数定义函数入参,第二个为参数的处理表达式
  137.         # 这样理解
  138.         # def getName(name):
  139.         #   return name.split("-")[1]
  140.         #
  141.         # 用匿名函数就这么表示
  142.         # name = lambda name:name.split("-")[1]
  143.         # xname = name("haha-dd-23")
  144.         #
  145.         # 支持多个参数
  146.         #
  147.         book_pages = sorted(book_pages, key=lambda name: int(filename_sort_fn(name)))
  148.     bookPagesData = []
  149.     bookDoc = SimpleDocTemplate(save_book_name, pagesize=A4, rightMargin=72, leftMargin=72, topMargin=72, bottomMargin=18)
  150.     for page in book_pages:
  151.         img_w, img_h = ImageTools().getImageSize(page)
  152.         # img_w = img.imageWidth
  153.         # img_h = img.imageHeight
  154.         if __a4_w / img_w < __a4_h / img_h:
  155.             ratio = __a4_w / img_w
  156.         else:
  157.             ratio = __a4_h / img_h
  158.         data = Image(page, img_w * ratio, img_h * ratio)
  159.         bookPagesData.append(data)
  160.         bookPagesData.append(PageBreak())
  161.     try:
  162.         bookDoc.build(bookPagesData)
  163.         # print("已转换 >>>> " + bookName)
  164.     except Exception as err:
  165.         print("[*][转换PDF] : 错误. [名称] > [%s]" % (save_book_name))
  166.         print("[*] Exception >>>> ", err)
  167. class ImageTools:
  168.     def getImageSize(self, imagePath):
  169.         img = pilImage.open(imagePath)
  170.         return img.size
weinxin
我的微信公众号
爱真理,得永生!          爱在灵灵久博客,网罗天下,福利大家!

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: