今天有朋友咨询这个问题,于是在网上搜索了一番,很多方案都是在linux、mac下的,好在找到了windos的,借鉴了博主nightttt7的思路、源码,整合出了一个可用的程序,相关博主在最下方给出。
将原PDF文件 切割为多张 单页图片,利用OCR逐页扫描单页图片获得文本信息,将识别的文本信息输出为新的PDF。最终结果的优劣大程度来自于所使用OCR的识别精准度,其次来源于 切割单页图片的质量、输出新PDF的格式。
根据思路,我们大致可以开始准备实现目标所需的功能模块:
1) 将1个PDF文件 切割 为多张单页图片 的工具
2) 高精准度识别图片的OCR工具
3) 将识别内容封装为PDF文件的工具
jtyoui # 用于将pdf跟图片相互转换,作者亦写有可视化程序可直接使用(此项目git)
pypdf2 # 用于拆分和合并pdf
baidu-aip # 百度OCR识别接口
pdfkit # 将字符串生成pdf
需预先安装软件:
--------wkhtmltopdf :https://wkhtmltopdf.org/downloads.html
--------> 配合 pdfkit模块,用于将字符串生成PDF
from PyPDF2 import PdfFileReader, PdfFileWriter
from aip import AipOcr
import pdfkit
import fitz
import time
import os
time1 = time.time()
# 配置初始参数
path = 'G:\Python\First' # PDF 文件的路径
pdfname = '容斋六笔.pdf' # PDF 文件的文件名
path_wk = r'C:\Python_extend\wkhtmltopdf\bin\wkhtmltopdf.exe' # wkhtmltopdf.exe 文件的安装位置
pdfkit_config = pdfkit.configuration(wkhtmltopdf=path_wk)
pdfkit_options = {'encoding': 'UTF-8', }
# 打开 https://console.bce.baidu.com/#/index/overview (产品服务->人工智能->文字识别->创建应用)中获取以下三个值
APP_ID = 'str'
API_KEY = 'str'
SECRET_KEY = 'str'
def pdf_image():
pdf = fitz.open('{}\{}'.format(path, pdfname))
for pg in range(0, pdf.pageCount):
page = pdf[pg] # 获得每一页的对象
trans = fitz.Matrix(1.0, 1.0).preRotate(0)
pm = page.getPixmap(matrix=trans, alpha=False) # 获得每一页的流对象
pm.writePNG(path + os.sep + pdfname[:-4] + '_' + '{:0>3d}.png'.format(pg + 1)) # 保存图片
page_range = range(pdf.pageCount)
pdf.close()
return page_range
def read_png2api(page_range):
# 读取本地图片的函数
def get_file_content(filePath):
with open(filePath, 'rb') as fp:
return fp.read()
allteststr = []
image_list = []
for page_num in page_range:
# 读取本地图片
image = get_file_content(r'{}\{}_{}.png'.format(path, pdfname[:-4], '%03d' % (page_num + 1)))
image_list.append(image)
# 新建一个AipOcr
client = AipOcr(APP_ID, API_KEY, SECRET_KEY)
# 可选参数
options = {}
options["language_type"] = "CHN_ENG"
options["detect_direction"] = "false"
options["detect_language"] = "false"
options["probability"] = "false"
for image in image_list:
# 通用文字识别,得到的是一个dict
testjson = client.basicGeneral(image, options)
teststr = ''
for x in testjson['words_result']:
teststr = teststr + x['words'] + ''
print('正在调用百度接口:第{}个,共{}个'.format(len(allteststr), len(image_list)))
allteststr.append(teststr)
return allteststr
def str2pdf(page_range, allteststr):
# 字符串写入PDF
for page_num in page_range:
print('正在将字符串写入PDF:第{}个,共{}个'.format((page_num + 1), len(page_range)))
pdfkit.from_string((allteststr[page_num]), '%s.pdf' % (str(page_num + 1)),
configuration=pdfkit_config, options=pdfkit_options)
def pdf_merge(page_range):
# 合并单页PDF
pdf_output = PdfFileWriter()
for page_num in page_range:
print('正在合并单页:第{}个,共{}个'.format((page_num + 1), len(page_range)))
os.chdir(path)
pdf_input = PdfFileReader(open('%s.pdf' % (str(page_num + 1)), 'rb'))
page = pdf_input.getPage(0)
pdf_output.addPage(page)
pdf_output.write(open('new_{}.pdf'.format(pdfname), 'wb'))
if __name__ == '__main__':
range_Count = pdf_image()
all_th = read_png2api(range_Count)
str2pdf(range_Count, all_th)
pdf_merge(range_Count)
time2 = time.time()
print('{}次爬取共消耗时间{}秒'.format('本', round(time2 - time1, 2)))
参考文章:https://blog.csdn.net/sqq513/article/details/79368243