改进拖放PDF转换为图片在转换为TXT文件的程序

前段时间我写了Python识别拖放的PDF文件再转成文本文件-CSDN博客

最近有2点更新,一是有一些pdf文件转换出来的图片是横的,这样也可以识别文字,但是可能会影响效果,另一个是发现有一些文字识别不出来,看了关于提高PaddleOCR识别准确率的一些优化(一)_如何提高paddleocr识别准确率-CSDN博客发现是图片文件的尺寸太大了,为此将其缩小一半再识别。确实提高了识别率。

代码:

python 复制代码
# -*- coding: utf-8 -*-
"""
Created on Sun Aug 25 10:42:39 2024

@author: YBK
"""

import tkinter as tk
import windnd
from tkinter.messagebox import showinfo
import os
from PIL import Image
import fitz
from fitz import Document as openPDF
import time
import re
from paddleocr import PaddleOCR
import subprocess

def dec_to_36(num):
    base = [str(x) for x in range(10)] + [chr(x) for x in range(ord('A'),ord("A")+26)]
    # 前者把 0 ~ 9 转换成字符串存进列表 base 里,后者把 A ~ Z 存进列表
    l = []
    if num<0:
        return "-"+dec_to_36(abs(num))
    while True:
        num,rem = divmod(num,36) # 求商 和 留余数
        l.append(base[rem])
        if num == 0:
            return "".join(l[::-1])
        
def nowtime_to_str():
    #将当前时间戳转化为36进制,约6位字符,减少文件名长度
    unix_timestamp = int(time.time())
    return(dec_to_36(unix_timestamp))

def pdf2pic(path, pic_path):
    '''
    # 从pdf中提取图片
    :param path: pdf的路径
    :param pic_path: 图片保存的路径
    :return:
    '''
    t0 = time.perf_counter()
    # 使用正则表达式来查找图片
    checkXO = r"/Type(?= */XObject)"
    checkIM = r"/Subtype(?= */Image)"

    # 打开pdf
    doc = openPDF(path)
    # 图片计数
    imgcount = 0
    lenXREF = doc.xref_length()

    # 打印PDF的信息
    print("文件名:{}, 页数: {}, 对象: {}".format(path, len(doc), lenXREF - 1))

    # 遍历每一个对象
    for i in range(1, lenXREF):
        # 定义对象字符串
        text = doc.xref_object(i)
        isXObject = re.search(checkXO, text)
        # 使用正则表达式查看是否是图片
        isImage = re.search(checkIM, text)
        # 如果不是对象也不是图片,则continue
        if not isXObject or not isImage:
            continue
        imgcount += 1
        # 根据索引生成图像
        pix = fitz.Pixmap(doc, i)
        # 根据pdf的路径生成图片的名称
        # new_name = path.replace('\\', '_') + "_img{}.png".format(imgcount)
        # new_name = new_name.replace(':', '')
        new_name = os.path.basename(path).replace('.pdf', '_') + "img" + str(imgcount).zfill(3) + ".png"
        # 如果pix.n<5,可以直接存为PNG
        if pix.n < 5:
            pix._writeIMG(os.path.join(pic_path, new_name),1,10)
        # 否则先转换CMYK
        else:
            pix0 = fitz.Pixmap(fitz.csRGB, pix)
            pix0._writeIMG(os.path.join(pic_path, new_name),1,10)
            pix0 = None
        # 释放资源
        pix = None
        image = Image.open(os.path.join(pic_path, new_name))
        #对于尺寸大于2000 * 2000的图像,缩放至(h * 0.5,w * 0.5)识别准确率有所提升
        if image.width > 2000 or image.height > 2000:
            new_image = image.resize((int(image.width * 0.5), int(image.height * 0.5)))
            new_image.save(os.path.join(pic_path, new_name))
            print("缩小图片尺寸")
            new_image.close()
        image = Image.open(os.path.join(pic_path, new_name))
        #对于图片宽度大于高度,左旋转
        if image.width > image.height: 
            rotated_img = image.transpose(Image.ROTATE_90)
            print("左旋转")
            rotated_img.save(os.path.join(pic_path, new_name))           
        image.close()
        t1 = time.perf_counter()
        print("运行时间:{}s".format(t1 - t0))
        print("提取了{}张图片".format(imgcount))
def get_file_size(file_path):
    # 获取文件的大小(单位为字节)
    file_size = os.stat(file_path).st_size
    return file_size
def dragged_files(files):
    fileurl = ''
    if len(files) > 1:
        # print("请拖放一个文件!")
        showinfo("提示","请拖放一个文件!")
    else:
        # print(files[0].decode('gbk'))
        fileurl = files[0].decode('gbk')
        # print(os.path.splitext(fileurl)[1])
    if fileurl != '' and os.path.splitext(fileurl)[1] == '.pdf':
        pdfpath = fileurl
        filename0 = os.path.basename(fileurl).replace('.pdf','') + nowtime_to_str()
        # filename0 用于生成文件夹和文件名,为了不重复,在后面加入编码后的时间戳
        pic_path = f'e:\\临时文件夹\\{filename0}\\'
        if not os.path.exists(pic_path):
            os.mkdir(pic_path)
        m = pdf2pic(pdfpath, pic_path)
        pngpath = pic_path
        outtxtpath = 'e:\\临时文件夹\\'+filename0+'.txt'
        ocr = PaddleOCR(use_angle_cls=True, lang="ch") # need to run only once to download and load model into memory
        lines = []
        for filename in os.listdir(pngpath):
            img_path = pngpath+filename
            result = ocr.ocr(img_path, cls=True)
            print(img_path)
            # image = Image.open(img_path).convert('RGB')
            if result[0] is not None:
                boxes = [detection[0] for line in result for detection in line] # Nested loop added
                txts = [detection[1][0] for line in result for detection in line] # Nested loop added
                scores = [detection[1][1] for line in result for detection in line] # Nested loop added
                for box, txt, score in zip(boxes, txts, scores):
                    if score > 0.7:
                        # lines.append(txt.replace('\n',''))
                        lines.append(txt+'\n')
                # lines.append('\n')
        with open(outtxtpath, 'w', encoding='utf-8') as f:
            f.writelines(line for line in lines)
        subprocess.run(['notepad.exe', outtxtpath], check=True)

 
if __name__ == '__main__':
    rootWindow = tk.Tk()
    rootWindow.title("拖放PDF文件识别文字")
    rootWindow.geometry("300x120")
    windnd.hook_dropfiles(rootWindow , func=dragged_files)
    rootWindow.mainloop()
相关推荐
呼啦啦呼啦啦啦啦啦啦8 小时前
利用pdfjs实现的pdf预览简单demo(包含翻页功能)
android·javascript·pdf
东华果汁哥1 天前
【URL 转换为PDF】HTML转换为PDF
前端·pdf·html
诸葛大钢铁2 天前
Excel转PDF的三种方法
笔记·职场和发展·pdf·excel
爱分享的飘哥2 天前
第二十一 篇 PDF文档自动化:Python一键合并、分割、水印、提取与加密解密!你的PDF全能管家!
python·pdf·python操作pdf·pdf 加解密·pdf 分割和合并
簪花走马过长安3 天前
【PDF识别改名】使用京东云OCR完成PDF图片识别改名,根据PDF图片内容批量改名详细步骤和解决方案
ui·pdf·ocr·excel·京东云·wps·图片区域识别重命名
ComPDFKit3 天前
为什么有些PDF无法复制文字?原理分析与解决方案
人工智能·pdf·ocr
开开心心就好3 天前
电脑桌面整理工具,一键自动分类
运维·服务器·前端·智能手机·pdf·bash·symfony
咖啡色格调3 天前
Java使用itextpdf7生成pdf文档
java·pdf·maven
开开心心_Every3 天前
可增添功能的鼠标右键优化工具
开发语言·pdf·c#·计算机外设·电脑·音视频·symfony
余大侠在劈柴4 天前
pdf.js 开发指南:在 Web 项目中集成 PDF 预览功能
前端·javascript·学习·pdf