ff70b617 by 周伟奇

update extract model

1 parent 77026d8c
1 # PDF转图片脚本 1 # PDF转图片脚本
2 2
3 ## 主要处理逻辑 3 ## 2种转化方式
4 - 保存整个页面为png图片
4 - 提取PDF页面中的图片对象 5 - 提取PDF页面中的图片对象
5 - 图片对象数目为0(如电子账单),保存整个页面为png图片 6 - 图片对象数目为0(如电子账单),保存整个页面为png图片
6 - 图片对象数目为1 7 - 图片对象数目为1
7 - 大图,保存图片对象 8 - 大图,保存图片对象
8 - 小图(如电子账单盖章),保存整个页面为png图片 9 - 小图(如电子账单盖章),保存整个页面为png图片
9 - 图片对象数目大于1 10 - 图片对象数目大于1
10 -图,保存图片对象 11 -图,保存图片对象
11 - 多碎图,根据宽高突变位置分组,拼接合并后保存 12 - 多碎图,根据宽高突变位置分组,拼接合并后保存
12 - 其他特殊情况:保存整个页面为png图片 13 - 其他特殊情况:保存整个页面为png图片
13 14
15 ## 已知问题
16 - 提取图片对象方式下,整图与碎图通过宽高阈值区分,无法满足所有PDF。个别PDF中,整图很小时会被当做碎图合并,碎图很大时会被当做整图不合并
17
14 ## 用法 18 ## 用法
15 - python3.6+ 19 - python3.6+
16 - `pip install -r requirements.txt` 20 - `pip install -r requirements.txt`
17 - `python pdf_to_img.py pdf_path [img_path]`
18
19 | 参数 | 是否必须 | 说明 | 缺省值 |
20 | ---- | ---- | ---- | ---- |
21 | pdf_path | 是 | PDF文件或目录路径 | - |
22 | img_path | 否 | 图片保存路径 | PDF文件路径 |
...\ No newline at end of file ...\ No newline at end of file
21 - `python pdf_to_img.py [-h] -i INPUT [-o OUTPUT] [-e]`
22 ```
23 可选参数:
24 -h, --help 查看帮助信息并退出
25 -i INPUT, --input INPUT PDF文件或目录路径,必要参数
26 -o OUTPUT, --output OUTPUT 输出图片保存路径,非必要参数,缺省值为PDF文件路径
27 -e, --extract 默认采用整个页面保存png图片的方式,增加该选项选择提取图片方式转化图片
28 ```
...\ No newline at end of file ...\ No newline at end of file
......
1 import os 1 import os
2 import sys 2 import sys
3 import fitz 3 import fitz
4 import argparse
4 from PIL import Image 5 from PIL import Image
5 from io import BytesIO 6 from io import BytesIO
6 7
7 if sys.version_info[0] < 3: 8 if sys.version_info[0] < 3:
8 raise Exception("This program requires at least python3.6") 9 raise Exception("This program requires at least python3.6")
9 if len(sys.argv) < 2: 10
10 print('用法:python pdf_to_img.py PDF文件或目录路径 [图片保存路径]') 11 parser = argparse.ArgumentParser(description='PDF转图片')
11 sys.exit(0) 12 parser.add_argument('-i', '--input', help='PDF文件或目录路径,必要参数', required=True)
12 if not os.path.exists(sys.argv[1]): 13 parser.add_argument('-o', '--output', help='输出图片保存路径,非必要参数,缺省值为PDF文件路径')
13 print('PDF文件或目录不存在: {0}'.format(sys.argv[1])) 14 parser.add_argument('-e', '--extract', help='默认采用整个页面保存png图片的方式,增加该选项选择提取图片方式转化图片', action="store_true")
14 sys.exit(0) 15 args = parser.parse_args()
15 16
16 LOG_BASE = '[pdf to img]' 17 LOG_BASE = '[pdf to img]'
17 18
...@@ -190,13 +191,13 @@ class PDFHandler: ...@@ -190,13 +191,13 @@ class PDFHandler:
190 page = pdf.loadPage(pno) 191 page = pdf.loadPage(pno)
191 self.page_to_png(page) 192 self.page_to_png(page)
192 193
193 def extract_image(self): 194 def extract_image(self, is_extract):
194 os.makedirs(self.img_dir_path, exist_ok=True) 195 os.makedirs(self.img_dir_path, exist_ok=True)
195 with fitz.Document(self.path) as pdf: 196 with fitz.Document(self.path) as pdf:
196 print('++++++++++' * 5) 197 print('++++++++++' * 5)
197 print('{0} [start] [pdf_path={1}] [metadata={2}]'.format(LOG_BASE, self.path, pdf.metadata)) 198 print('{0} [start] [pdf_path={1}] [metadata={2}]'.format(LOG_BASE, self.path, pdf.metadata))
198 for pno in range(pdf.pageCount): 199 for pno in range(pdf.pageCount):
199 il = pdf.getPageImageList(pno) # 获取页面图片对象 200 il = pdf.getPageImageList(pno) if is_extract else [] # 获取页面图片对象
200 # (xref, smask, width, height, bpc, colorspace, alt.colorspace, name, filter, invoker) 201 # (xref, smask, width, height, bpc, colorspace, alt.colorspace, name, filter, invoker)
201 print('---------- page: {0} ----------'.format(pno)) 202 print('---------- page: {0} ----------'.format(pno))
202 print('img_object_list: {0}'.format(il)) 203 print('img_object_list: {0}'.format(il))
...@@ -230,26 +231,29 @@ class PDFHandler: ...@@ -230,26 +231,29 @@ class PDFHandler:
230 self.merge_il(pdf, pno, il) 231 self.merge_il(pdf, pno, il)
231 232
232 233
233 def extract_image(pdf_path, target_path): 234 def extract_image(pdf_path, target_path, is_extract):
234 pdf_handler = PDFHandler(pdf_path, target_path) 235 pdf_handler = PDFHandler(pdf_path, target_path)
235 pdf_handler.extract_image() 236 pdf_handler.extract_image(is_extract)
236 237
237 238
238 def main(): 239 def main():
239 pdf_path = os.path.realpath(sys.argv[1]) 240 if not os.path.exists(args.input):
241 print('PDF文件或目录不存在: {0}'.format(args.input))
242 return
243 pdf_path = os.path.realpath(args.input)
240 # 目录:遍历处理所有pdf文件 244 # 目录:遍历处理所有pdf文件
241 if os.path.isdir(pdf_path): 245 if os.path.isdir(pdf_path):
242 completed_count = 0 246 completed_count = 0
243 failed_list = [] 247 failed_list = []
244 for parent, dirnames, filenames in os.walk(pdf_path): 248 for parent, dirnames, filenames in os.walk(pdf_path):
245 # 图片保存目录 249 # 图片保存目录
246 target_path = os.path.realpath(sys.argv[2]) if len(sys.argv) > 2 else parent 250 target_path = os.path.realpath(args.output) if args.output else parent
247 for pdf_file in filenames: 251 for pdf_file in filenames:
248 if not pdf_file.endswith('pdf') and not pdf_file.endswith('PDF'): 252 if not pdf_file.endswith('pdf') and not pdf_file.endswith('PDF'):
249 continue 253 continue
250 pdf_file_path = os.path.join(parent, pdf_file) 254 pdf_file_path = os.path.join(parent, pdf_file)
251 try: 255 try:
252 extract_image(pdf_file_path, target_path) 256 extract_image(pdf_file_path, target_path, args.extract)
253 except Exception as e: 257 except Exception as e:
254 print('{0} [failed] [err={1}] [pdf_path={2}]'.format(LOG_BASE, e, pdf_file_path)) 258 print('{0} [failed] [err={1}] [pdf_path={2}]'.format(LOG_BASE, e, pdf_file_path))
255 failed_list.append(pdf_file_path) 259 failed_list.append(pdf_file_path)
...@@ -261,9 +265,9 @@ def main(): ...@@ -261,9 +265,9 @@ def main():
261 # 文件:处理pdf文件 265 # 文件:处理pdf文件
262 else: 266 else:
263 # 图片保存目录 267 # 图片保存目录
264 target_path = os.path.realpath(sys.argv[2]) if len(sys.argv) > 2 else os.path.dirname(pdf_path) 268 target_path = os.path.realpath(args.output) if args.output else os.path.dirname(pdf_path)
265 try: 269 try:
266 extract_image(pdf_path, target_path) 270 extract_image(pdf_path, target_path, args.extract)
267 except Exception as e: 271 except Exception as e:
268 print('{0} [failed] [err={1}] [pdf_path={2}]'.format(LOG_BASE, e, pdf_path)) 272 print('{0} [failed] [err={1}] [pdf_path={2}]'.format(LOG_BASE, e, pdf_path))
269 else: 273 else:
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!