练习:将图片版PDF(不可复制)通过OCR转换为可编辑的PDF

一 背景

        今天有朋友咨询这个问题,于是在网上搜索了一番,很多方案都是在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'] + '</br>'
        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

 

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dianepure

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值