Python识别拖放的PDF文件再转成文本文件

news2025/1/12 12:20:16

日常工作中经常用到PDF文件,有些PDF文件的文字是不能复制的,为了复制这些文字,我们需要转化PDF文件,或者采用微信的OCR图片识别文字,这样非常不方便。为此,我编写了一个Python小程序,利用Tkinter的拖放小窗口供平时拖放PDF文件到里面,等待paddle ocr识别PDF图片的文字,再转化为TXT文件,启动系统自带的记事本打开,复制要复制的文字后,再关闭记事本,就可以关闭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

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
        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.75:
                        # 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()

这里面我有个得意之作,就是将时间戳转化为36进制的6位字符,用了避免重复文件名。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2131169.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于51单片机的多功能台灯Protues仿真设计

目录 一、设计背景 二、设计要求 三、仿真演示 四、程序展示 一、设计背景 随着科技的飞速发展和智能家居的普及&#xff0c;传统的台灯已经难以满足现代消费者对照明设备的多样化需求。传统台灯的功能主要集中在提供基本的照明效果&#xff0c;其操作方式通常是通过手动调…

Langchain.js你必须要知道的核心组件

关于Langchain.js Langchain.js&#xff0c;在github上截止到今日已经有92k的start。之前一直偶有耳闻&#xff0c;但没有深入了解。今天看完后&#xff0c;真的是可以堪称大模型里的瑞士军刀。 LangChain由Harrison Chase于2022年10月作为开源软件项目推出&#xff0c;用于连…

抗菌肽;Parasin I;KGRGKQGGKVRAKAKTRSS;CAS号:219552-69-9

【Parasin I 简介】 Parasin I是一种抗菌肽&#xff0c;由19个氨基酸组成&#xff0c;最初从鲶鱼的皮肤粘液中分离得到。它具有广谱的抗菌活性&#xff0c;能够有效对抗革兰氏阳性菌和革兰氏阴性菌&#xff0c;包括一些对传统抗生素具有耐药性的菌株。 【中文名称】抗菌肽 Par…

C语言 11 字符串

前面学习了数组&#xff0c;而对于字符类型的数组&#xff0c;比较特殊&#xff0c;它实际上可以作为一个字符串&#xff08;String&#xff09;表示&#xff0c;字符串就是一个或多个字符的序列&#xff0c;比如在一开始认识的"Hello World"&#xff0c;像这样的多个…

如何编写智能合约——基于长安链的Go语言的合约开发

场景设计&#xff1a;文件存证系统 在数字化时代&#xff0c;文件存证和版本追踪变得越来越重要。设想一个场景&#xff1a;在一个法律事务管理系统中&#xff0c;用户需要提交和管理各种文件的版本记录&#xff0c;以确保每个文件在不同时间点的状态可以被准确追踪。文件可能经…

抖音生活服务是干什么的?很多人都不知道的入局途径曝光!

近年来&#xff0c;作为国内两大头部短视频平台之一的抖音一直在大力布局其生活服务业务&#xff0c;壮大自身实力的同时&#xff0c;也让不少人开始好奇抖音生活服务的概念&#xff0c;以抖音生活服务是干什么的和如何做抖音生活服务为代表多个相关话题因此成为了多个互联网社…

客户端负载均衡Ribbon实例

文章目录 一&#xff0c;概述二&#xff0c;实现过程三&#xff0c;项目源码1. 源码放送&#xff1a;2. 部署方式 四&#xff0c;功能演示五&#xff0c;其他 一&#xff0c;概述 一般来说&#xff0c;提到负载均衡&#xff0c;大家一般很容易想到浏览器 -> NGINX -> 反…

记一次 FastDFS 存储节点迁移:基于 scp 的实践与经验分享

一、背景 某某项目&#xff0c;机房到期&#xff0c;需要迁移至其他机房&#xff1b; 此项目已经运行了3年多&#xff0c;fastdfs累计数据大概在250G 左右&#xff0c;现需要把旧的fastdfs数据迁移到新的fastdfs上&#xff1b; 采用scp物理迁移数据的方式&#xff0c;停机迁移…

技术分享 | RK3568修改eMMC分区大小

我司IAC-RK3568-CM根据eMMC大小的不同&#xff0c;有着不同规格的产品&#xff0c;不论eMMC大小如何改变&#xff0c;其分区的配置大同小异&#xff0c;除了eMMC厂商所使用的区域无法变更外&#xff0c;留给用户的区域可自由写入。 我司产品默认eMMC启动&#xff0c;所以eMMC用…

【AI-18】Adam和SGD优化算法比较

Adam&#xff08;Adaptive Moment Estimation&#xff09;和 SGD&#xff08;Stochastic Gradient Descent&#xff0c;随机梯度下降&#xff09;是两种常见的优化算法&#xff0c;它们在不同方面有各自的特点。 一、算法原理 SGD&#xff1a; 通过计算损失函数关于每个样本的…

干货分享 | 激光测风雷达中准确监测温度、湿度和气压的重要性

前言 风场信息的测量是气象或空气动力学领域的重要工作内容之一&#xff0c;其测量的精确性对于气象研究尤为重要。 激光测风雷达作为新型测风技术&#xff0c;利用多普勒&#xff08;Doppler&#xff09;原理获取风向、风速信息&#xff0c;具有能够探测晴空风场、测风范围广…

element select + tree

element select tree的使用 <template slot"action1" slot-scope"text, record, index"><el-select v-model"record.tagValue" multiple placeholder"请选择":filter-method"(e) > filterTree(e, index)" filt…

5分钟配置Nginx?(二)

前言: 此文章分为两个部分。 5分钟搞懂什么是Nginx?(一)-CSDN博客文章浏览阅读82次。2.、那么此时入口的安全性则格外重要,同时因为加强了入口的安全性,后端的web server的安全则可以不用做额外安全工作。因为入口如果破防,后端web server一定破防,如果不…

支付宝开放平台-开发者社区——AI 日报「9 月 13 日」

1 OpenAl推出了一个新的大语言模型一 OpenAl o1 前沿技术瞭望官&#xff5c;阅读原文 新的模型主要体现在下面几个方面&#xff0c;思维链&#xff1a;o1在回答问题前会产生一个内部的思维链&#xff0c;这使得它能够进行更深入的推理。强化学习&#xff1a;通过大规模强化学…

Linux操作系统入门(一)

Linux操作系统是开源的类Unix操作系统内核&#xff0c;由林纳斯托瓦兹在1991年创建。 Linux操作系统以其强大的性能、稳定性和开放性&#xff0c;赢得了全球用户的广泛认可&#xff0c;从服务器到个人电脑&#xff0c;从超级计算机到嵌入式设备&#xff0c;都有它的身影。作为…

停止向供应商提供您的数据

组织管理其数据基础设施的方式正在发生重大转变。越来越多的公司认识到存储和计算分离的优势&#xff0c;从而获得更好的性能、成本节约和可扩展性。这一趋势是由 AI 和 ML 工作负载日益复杂所推动的&#xff0c;这些工作负载需要灵活、高性能的系统。Databricks 首席执行官 Al…

自定义Spring-start学习笔记

Spring Boot Start的创建和使用 start的工作原理(网图) 1. 设置Maven项目&#xff1a; 创建一个新的Maven或Gradle项目&#xff0c;并在项目的pom.xml文件中添加必要的Spring Boot依赖项和插件。下面以maven项目为例&#xff1a; 创建Spring Boot项目 &#xff0c;并在项目的…

私域流量的价值探索:开源链动 2+1 模式、AI 智能名片与 S2B2C 商城小程序的助力

摘要&#xff1a;本文从渠道视角深入剖析私域流量的特殊价值&#xff0c;探讨其作为一种新的销售渠道所具有的重要意义。同时引入开源链动 21 模式、AI 智能名片和 S2B2C 商城小程序等创新元素&#xff0c;阐述它们如何为私域流量的发展提供新的动力和机遇&#xff0c;进一步提…

UE5安卓项目打包安装

Android studio安装 参考&#xff1a;https://docs.unrealengine.com/5.2/zh-CN/how-to-set-up-android-sdk-and-ndk-for-your-unreal-engine-development-environment/ 打开android studio的官网&#xff1a;Download Android Studio & App Tools - Android Developers …

浅谈电动汽车火灾特点及扑救对策研究

0引言 电动汽车火灾事件增多&#xff0c;其特点包括电池高能量密度、快速热释放和烟雾毒性。本文提出应对策略&#xff1a;加强火灾预防&#xff0c;完善电池管理系统&#xff0c;提高电池安全性能&#xff1b;使用干粉灭火器、气溶胶灭火系统等灭火剂&#xff1b;对严重火灾采…