From ff70b617ffb0687c9382c35b3a0901b7fc300de4 Mon Sep 17 00:00:00 2001 From: 周伟奇 <zhouweiqi@situdata.com> Date: Thu, 6 Aug 2020 14:27:27 +0800 Subject: [PATCH] update extract model --- README.md | 22 ++++++++++++++-------- pdf_to_img.py | 34 +++++++++++++++++++--------------- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 4b24e2f..eaa4c5b 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,28 @@ # PDF转图片脚本 -## 主要处理逻辑 +## 2种转化方式 +- 保存整个页面为png图片 - 提取PDF页面中的图片对象 - 图片对象数目为0(如电子账单),保存整个页面为png图片 - 图片对象数目为1 - 大图,保存图片对象 - 小图(如电子账单盖章),保存整个页面为png图片 - 图片对象数目大于1 - - 多大图,保存图片对象 + - 多整图,保存图片对象 - 多碎图,根据宽高突变位置分组,拼接合并后保存 - 其他特殊情况:保存整个页面为png图片 +## 已知问题 +- 提取图片对象方式下,整图与碎图通过宽高阈值区分,无法满足所有PDF。个别PDF中,整图很小时会被当做碎图合并,碎图很大时会被当做整图不合并 + ## 用法 - python3.6+ - `pip install -r requirements.txt` - - `python pdf_to_img.py pdf_path [img_path]` - - | 参数 | 是否必须 | 说明 | 缺省值 | - | ---- | ---- | ---- | ---- | - | pdf_path | 是 | PDF文件或目录路径 | - | - | img_path | 否 | 图片保存路径 | PDF文件路径 | \ No newline at end of file + - `python pdf_to_img.py [-h] -i INPUT [-o OUTPUT] [-e]` + ``` + 可选参数: + -h, --help 查看帮助信息并退出 + -i INPUT, --input INPUT PDF文件或目录路径,必要参数 + -o OUTPUT, --output OUTPUT 输出图片保存路径,非必要参数,缺省值为PDF文件路径 + -e, --extract 默认采用整个页面保存png图片的方式,增加该选项选择提取图片方式转化图片 + ``` \ No newline at end of file diff --git a/pdf_to_img.py b/pdf_to_img.py index 4c1b37c..3715038 100644 --- a/pdf_to_img.py +++ b/pdf_to_img.py @@ -1,17 +1,18 @@ import os import sys import fitz +import argparse from PIL import Image from io import BytesIO if sys.version_info[0] < 3: raise Exception("This program requires at least python3.6") -if len(sys.argv) < 2: - print('用法:python pdf_to_img.py PDF文件或目录路径 [图片保存路径]') - sys.exit(0) -if not os.path.exists(sys.argv[1]): - print('PDF文件或目录不存在: {0}'.format(sys.argv[1])) - sys.exit(0) + +parser = argparse.ArgumentParser(description='PDF转图片') +parser.add_argument('-i', '--input', help='PDF文件或目录路径,必要参数', required=True) +parser.add_argument('-o', '--output', help='输出图片保存路径,非必要参数,缺省值为PDF文件路径') +parser.add_argument('-e', '--extract', help='默认采用整个页面保存png图片的方式,增加该选项选择提取图片方式转化图片', action="store_true") +args = parser.parse_args() LOG_BASE = '[pdf to img]' @@ -190,13 +191,13 @@ class PDFHandler: page = pdf.loadPage(pno) self.page_to_png(page) - def extract_image(self): + def extract_image(self, is_extract): os.makedirs(self.img_dir_path, exist_ok=True) with fitz.Document(self.path) as pdf: print('++++++++++' * 5) print('{0} [start] [pdf_path={1}] [metadata={2}]'.format(LOG_BASE, self.path, pdf.metadata)) for pno in range(pdf.pageCount): - il = pdf.getPageImageList(pno) # 获取页面图片对象 + il = pdf.getPageImageList(pno) if is_extract else [] # 获取页面图片对象 # (xref, smask, width, height, bpc, colorspace, alt.colorspace, name, filter, invoker) print('---------- page: {0} ----------'.format(pno)) print('img_object_list: {0}'.format(il)) @@ -230,26 +231,29 @@ class PDFHandler: self.merge_il(pdf, pno, il) -def extract_image(pdf_path, target_path): +def extract_image(pdf_path, target_path, is_extract): pdf_handler = PDFHandler(pdf_path, target_path) - pdf_handler.extract_image() + pdf_handler.extract_image(is_extract) def main(): - pdf_path = os.path.realpath(sys.argv[1]) + if not os.path.exists(args.input): + print('PDF文件或目录不存在: {0}'.format(args.input)) + return + pdf_path = os.path.realpath(args.input) # 目录:遍历处理所有pdf文件 if os.path.isdir(pdf_path): completed_count = 0 failed_list = [] for parent, dirnames, filenames in os.walk(pdf_path): # 图片保存目录 - target_path = os.path.realpath(sys.argv[2]) if len(sys.argv) > 2 else parent + target_path = os.path.realpath(args.output) if args.output else parent for pdf_file in filenames: if not pdf_file.endswith('pdf') and not pdf_file.endswith('PDF'): continue pdf_file_path = os.path.join(parent, pdf_file) try: - extract_image(pdf_file_path, target_path) + extract_image(pdf_file_path, target_path, args.extract) except Exception as e: print('{0} [failed] [err={1}] [pdf_path={2}]'.format(LOG_BASE, e, pdf_file_path)) failed_list.append(pdf_file_path) @@ -261,9 +265,9 @@ def main(): # 文件:处理pdf文件 else: # 图片保存目录 - target_path = os.path.realpath(sys.argv[2]) if len(sys.argv) > 2 else os.path.dirname(pdf_path) + target_path = os.path.realpath(args.output) if args.output else os.path.dirname(pdf_path) try: - extract_image(pdf_path, target_path) + extract_image(pdf_path, target_path, args.extract) except Exception as e: print('{0} [failed] [err={1}] [pdf_path={2}]'.format(LOG_BASE, e, pdf_path)) else: -- libgit2 0.24.0