欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

荐 图像转文本、PDF 转文字(包括html、xml)、关键句提取 软件开发手记

程序员文章站 2022-06-26 08:40:02
文章目录准备工作所需模块:模块简介安装方法:软件开发图像转文本API 使用代码其他PDF 转文字代码Tooltip关键句提取截图古文排版软件使用关于界面国际化效果展示国际化实现使用指南图像转文本PDF 转文字关键句提取古文排版准备工作所需模块:模块简介Tkinter:主要是 GUI 模块pytesseract:图像转文字 API 接口pdfminter3:读取 PDF 并转换成其他格式pyhanlp:进行关键句提取安装方法:清华源 pip 走起:pip install -i https:...

准备工作

声明

要源码的请关注后留言
软件效果请看使用指南

所需模块:

模块简介

Tkinter:主要是 GUI 模块
pytesseract:图像转文字 API 接口
pdfminter3:读取 PDF 并转换成其他格式
pyhanlp:进行关键句提取

安装方法:

清华源 pip 走起:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pytesseract

软件开发

图像转文本

图像转文本 软件中,需要首先下载一个 tesseract 的开源,文本转图像工具。然后,通过 pytesseract 调用其 API,来实现图像识别文本(OCR)

tesseract 的下载地址

可以下载任意版本,这里推荐下载最新版本

API 使用代码

# coding: utf-8
import pytesseract
from PIL import Image
from tkinter import messagebox as mBox
import tkinter as tk
import os

def img2text(engine_path,img_path,text_path,Widget,lang):
    pytesseract.pytesseract.tesseract_cmd = engine_path
    mBox.showinfo('提示', '运行中,请耐心等待\n 文件越复杂,运行时间越久哦(关了吧,没关系的)')
    text = pytesseract.image_to_string(Image.open(img_path),lang=lang)

    with open(text_path+r'\output.txt', "w", encoding='utf-8') as f:
        f.write(text)
        f.close()
    mBox.showinfo('提示', '运行完毕')
    Widget.insert(tk.INSERT,text)
 
def img2text_TEST(engine_path,img_path,text_path):
    pytesseract.pytesseract.tesseract_cmd = engine_path  
    text = pytesseract.image_to_string(Image.open(img_path),lang='chi_sim')

    with open(text_path+r'\output.txt', "w", encoding='utf-8') as f:
        f.write(text)
        f.close()
    mBox.showinfo('提示', '运行完毕')

if __name__ == '__main__':    
    engine_path = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
    img_path = r'E:\java-2020-03\eclipse\workspace\Img2Txt\Input\test_math.jpg'
    text_path = r'E:\java-2020-03\eclipse\workspace\Img2Txt\Output'
    img2text_TEST(engine_path,img_path,text_path) 

其他

可以尝试使用百度识图,里面也有相应的 API,不过一天只能使用有限次,所以这里不再采用。详细地,可以参照这篇博文:
https://blog.csdn.net/qq_38144563/article/details/96138470

其实,对于公式的识别,把他转成 latex,还有一个工具,具体是什么,请在评论区提问吧。不过,也是一个有限次使用的主。他的 API,因为某些无聊的原因,现在不对我国开放了,实在可惜。!!!!!

PDF 转文字

pdf 转文字用的是 pdfminer3,最近开发了 python3 版本。所以,网上的那些,都是用不了的,大家大可不一试,因为我试过了。有些模块已经被改了,所以也用不了。因此,就看我怎么写吧?

代码

# coding: utf-8
import argparse
import logging
import sys
import pdfminer3.settings
pdfminer3.settings.STRICT = False
import pdfminer3.high_level
import pdfminer3.layout
from pdfminer3.image import ImageWriter
import tkinter as tk
from tkinter import messagebox as mBox


def extract_text(files=[], outfile='-',
            _py2_no_more_posargs=None,  
            no_laparams=False, all_texts=None, detect_vertical=None, # LAParams
            word_margin=None, char_margin=None, line_margin=None, boxes_flow=None, # LAParams
            output_type='text', codec='utf-8', strip_control=False,
            maxpages=0, page_numbers=None, password="", scale=1.0, rotation=0,
            layoutmode='normal', output_dir=None, debug=False,
            disable_caching=False, **other):
    if _py2_no_more_posargs is not None:
        raise ValueError("Too many positional arguments passed.")
    if not files:
        raise ValueError("Must provide files to work upon!")

    if not no_laparams:
        laparams = pdfminer3.layout.LAParams()
        for param in ("all_texts", "detect_vertical", "word_margin", "char_margin", "line_margin", "boxes_flow"):
            paramv = locals().get(param, None)
            if paramv is not None:
                setattr(laparams, param, paramv)
    else:
        laparams = None

    imagewriter = None
    if output_dir:
        imagewriter = ImageWriter(output_dir)

    if output_type == "text" and outfile != "-":
        for override, alttype in (  (".htm", "html"),
                                    (".html", "html"),
                                    (".xml", "xml"),
                                    (".tag", "tag") ):
            if outfile.endswith(override):
                output_type = alttype

    if outfile == "-":
        outfp = sys.stdout
        if outfp.encoding is not None:
            codec = 'utf-8'
    else:
        outfp = open(outfile, "wb")


    for fname in files:
        with open(fname, "rb") as fp:
            pdfminer3.high_level.extract_text_to_fp(fp, **locals())
    return outfp



def trans(files, outfile):
    mBox.showinfo('提示', '运行中,请耐心等待\n 文件越复杂,运行时间越久哦(关了吧,没关系的)')
    outfp = extract_text(files=files,outfile=outfile)
    outfp.close()
    mBox.showinfo('提示ʾ', '运行完毕')


if __name__ == '__main__': 
    trans(files=['E:/java-2020-03/eclipse/workspace/Img2Txt/Fun/test.pdf'],outfile='output.html')

在运行代码的时候,注意删掉一些哈。

Tooltip

在 PDF 转文本哪里,用了一个弹出说明,我把代码封装成一个类了,希望以后能够用到:

# -*- coding: utf-8 -*-
import tkinter as tk

class Tooltip():
    def __init__(self,widget):
        self.widget = widget
        self.tipwindow = None   
        self.id = None    
        self.x = self.y = 0    
    def showtip(self,text):
        self.text = text
        if self.tipwindow or not self.text:
            return
        x,y,_cx,cy = self.widget.bbox("insert")
        x = x + self.widget.winfo_rootx()+27
        y = y + cy + self.widget.winfo_rooty()+27
        self.tipwindow = tw = tk.Toplevel(self.widget)
        tw.wm_overrideredirect(1)    
        tw.wm_geometry("+%d+%d"%(x,y))
        label = tk.Label(tw,text=self.text,justify=tk.LEFT,
                         background='#ffffe0',relief=tk.SOLID,
                         borderwidth=1,font=('tahma',"8","normal"))
        label.pack(ipadx=1)    
    
    def hidetip(self):
        tw = self.tipwindow
        self.tipwindow = None 
        if tw:
            tw.destroy()
            
def createToolTip(widget,text):
    aTooltip = Tooltip(widget)    
    def enter(event):    
        aTooltip.showtip(text)
    def leave(event):
        aTooltip.hidetip()
    widget.bind('<Enter>',enter)    
    widget.bind('<Leave>',leave)

关键句提取

这个很容易啦,直接用 pyhanlp 就行了。里面用的是 PageRank 算法,相当于 Google 的网页排名算法。

# -*- coding: utf-8 -*-
"""
Created on Thu May  7 14:52:32 2020

@author: 
"""
from pyhanlp import *
from tkinter import messagebox as mBox

import tkinter as tk

def summary(text,num,Widget):
    
    text_list = HanLP.extractSummary(text,num)
    text = '\n'.join([t for t in text_list])
    Widget.insert(tk.INSERT,text)
    mBox.showinfo('提示', '运行完毕')
    

if __name__ == "__main__":
    summary_list = summary('“芦花滩上有扁舟, 俊杰黄昏独自游, 义到尽头原是命, 反躬逃难必无忧。”\
这是一首出自《水浒传》中吴用留下的藏头反诗;电视剧《裂变》中汉奸“蝙蝠”也曾\
使用数字对应书本页面和文字的方法传递消息给日寇;电影《暗算》中更是提到了黄依\
依解决多种密文的具体情节;甚至连动画片《名侦探柯南》也出现了 skytale 加密的细\
节。事实上,密文不仅存在于荧幕中,而且深入到生活的方方面面,例如用于存储互联\
网消息的 cookie、以及互联网安全中常提到的数字签名、在银行等网站上填写个人信息\
时,都会用一定的手段将明文加密成密文传输到在远处的服务器中,可以说,在互联网\
的世界里,只要有比特流动,就一定会有加密的存在。为此,各大高校还设立了专门的\
学科,如密码学、密码分析学、密码史等。不得不说,密码的发展更数学密切相关、大\
多数的密码学家都兼任数学家的身份,而密码学,这一学科在战争时代更是快速地发展。\
以下将会介绍密码学的发展史、以及一些经典密码学的典型加密方法和其对应的解密方\
法的介绍、文章最后会简单地提及现代密码学的一些实现手段',5)
    print(summary_list)

截图

在图像转文本哪里,我还内置了截图功能,代码如下:

# -*- coding:utf-8 -*-  
import tkinter as tk
from tkinter import filedialog as fd
import os
from os import path
from PIL import ImageGrab
from time import sleep

class ScreenShot:
    def __init__(self,master,filename):
        
        self._createWidge(master, filename)
        #变量X和Y用来记录鼠标左键按下的位置
        
    def _onLeftButtonDown(self,event):
        self._X.set(event.x)
        self._Y.set(event.y)
        #开始截图
        self._sel = True
    
    def _onLeftButtonMove(self,event):
        if not self._sel:
            return
        try:
            #删除刚画完的图形,要不然鼠标移动的时候是黑乎乎的一片矩形
            self._canvas.delete(self._lastDraw)
        except Exception as e:
            pass
        self._lastDraw = self._canvas.create_rectangle(self._X.get(), self._Y.get(), 
                                                 event.x, event.y, outline='black',
                                                width = 5)

    def _onLeftButtonUp(self,event):
        self.fileName = os.path.join(os.path.dirname(__file__),'../Input') 
        self._sel = False
        try:
            self._canvas.delete(self._lastDraw)
        except Exception as e:
            pass
        sleep(0.1)
        #考虑鼠标左键从右下方按下而从左上方抬起的截图
        leftSel, rightSel = sorted([self._X.get(), event.x])
        topSel, bottomSel = sorted([self._Y.get(), event.y])
        pic = ImageGrab.grab((leftSel+1,topSel,rightSel+1,bottomSel))     
         #弹出保存截图对话框
        fDir = os.path.join(os.path.dirname(__file__),'../Input')  #���ϼ��ļ�Ŀ¼��
        self.fileName = fd.asksaveasfilename(title='保存截图',
                                        filetypes=[('JPG files','*.jpg')],
                                        initialdir=fDir)
        #默认的文件夹呀!!
        if self.fileName: 
            pic.save(self.fileName)
        pic.close()
        #关闭当前窗口
        #print(left, '  ', top,'  ',right,'  ',bottom)
        self.top.destroy()
        print(self.fileName)
        sleep(1)
        

    def _createWidge(self,master,filename):
        self.fileName =  os.path.abspath(os.path.join( os.path.dirname(__file__),".."))+'\Input'
        self._X = tk.IntVar(0)
        self._Y = tk.IntVar(0)
        
        #屏幕尺寸
        screenWidth = master.winfo_screenwidth()
        #print(screenWidth)
        screenHeight = master.winfo_screenheight()
        #print(screenHeight)
        #创建*组件容器
        self.top = tk.Toplevel(master, width=screenWidth, height=screenHeight)
        #不显示最大化、最小化按钮
        self.top.overrideredirect(True)
        self._canvas = tk.Canvas(self.top,bg='white', width=screenWidth, height=screenHeight)
        #显示全屏截图,在全屏截图上进行区域截图
        self._img = tk.PhotoImage(file=filename)
        self._canvas.create_image(screenWidth//2, screenHeight//2,image=self._img)
        #鼠标左键按下的位置
        self._canvas.bind('<Button-1>', self._onLeftButtonDown)
        #鼠标左键移动,显示选取的区域

        self._canvas.bind('<B1-Motion>', self._onLeftButtonMove)
        #获取鼠标左键抬起的位置,保存区域截图
            
        self._canvas.bind('<ButtonRelease-1>', self._onLeftButtonUp)
        self._canvas.pack(fill=tk.BOTH, expand=tk.YES)


def buttonCaptureClick(master):
    #最小化主窗口
    master.state('icon')
    sleep(0.5)
    filename = 'screenShot.png'
    im = ImageGrab.grab()
    im.save(filename)
    im.close()
    #显示全屏幕截图
    
    w = ScreenShot(master,filename)

    os.remove(filename)
    print(w.fileName)
    return w.fileName

古文排版

所谓古文排版,就是将横的转为右起,竖的。实现代码如下:

# -*- coding: utf-8 -*-
import re
import tkinter as tk
from tkinter import messagebox as mBox
def cut_text(text,lenth):
    textArr = re.findall('.{'+str(lenth)+'}', text)
    textArr.append(text[(len(textArr)*lenth):])
    return textArr

def verticalPrint(text,counts,Widget):
    mBox.showinfo('提示', '运行中,请耐心等待\n 文件越复杂,运行时间越久哦(关了吧,没关系的)')
    text = cut_text(text,counts)
    text[-1] = text[-1].ljust(counts,' ')
    cols = len(text)
    text.reverse()
    
    rows = []
    for i in range(counts):
        row = ''
        for col in range(cols):
            row += text[col][i]
        rows.append(row)
    
    text = '\n'.join(rows)
    
    string = ''
    for char in text:
        if  not char.isdigit() and not char==' ':
            if  (char >= u'\u0041' and char<=u'\u005a') or (char >= u'\u0061' and char<=u'\u007a'):
                char += ' '
            else:
                pass
        else:
            char +=' '     
        string += char
    
    Widget.insert(tk.INSERT,string)
    mBox.showinfo('提示', '运行完毕')
    
if __name__ == '__main__':
    x=u"凡是到达了的地方,都I want to die, but I still to my life 属于昨天。哪怕那山再青,那水再秀,那风再温柔。带深的流连便成了一种羁绊,\
绊住的不仅是双脚,还有未来。可我的钱不够[笑哭]"
#    counts = 12
#    string = verticalPrint(x,counts)
#    print(string)

软件使用

关于界面

界面如下:
荐
                                                        图像转文本、PDF 转文字(包括html、xml)、关键句提取 软件开发手记

国际化效果展示

在开始菜单里,有弄了个国际化,效果如下:
荐
                                                        图像转文本、PDF 转文字(包括html、xml)、关键句提取 软件开发手记

国际化实现

将文本封装成一个类即可,就是 GUI 文件里面的 I18N.py,大家可以看一下。

然后,在定义处,添加如下代码:

class OOP:
    def __init__(self):
        self.win = tk.Tk()
        self.win.resizable(0,0)    #这个是设置窗口不可缩放
        self.i18n = I18N('chi')
        self._createWidget()
        self.win.mainloop()
        
    def _quit(self):    #设置一个 menu 菜单项的激活函数
        self.win.quit()    #退出
        self.win.destroy()   #销毁
        exit()   #结束程序
    def _chi(self):
        self.win.quit()
        self.win.destroy()
        self.win = tk.Tk()
        self.win.resizable(0,0)    #这个是设置窗口不可缩放
        self.i18n = I18N('chi')
        self._createWidget()
        self.win.mainloop()
        
    def _jap(self):
        self.win.quit()
        self.win.destroy()
        self.win = tk.Tk()
        self.win.resizable(0,0)    #这个是设置窗口不可缩放
        self.i18n = I18N('jap')
        self._createWidget()
        self.win.mainloop()
        
    def _eng(self):
        self.win.quit()
        self.win.destroy()
        self.win = tk.Tk()
        self.win.resizable(0,0)    #这个是设置窗口不可缩放
        self.i18n = I18N('eng')
        self._createWidget()
        self.win.mainloop()

使用指南

图像转文本

荐
                                                        图像转文本、PDF 转文字(包括html、xml)、关键句提取 软件开发手记
在 输出路径中,可以得到 output.txt 文件
荐
                                                        图像转文本、PDF 转文字(包括html、xml)、关键句提取 软件开发手记
也可以识别日文、英文、繁体中文,而且效果不错。不过,公式就算了吧,效果太 low 了。
荐
                                                        图像转文本、PDF 转文字(包括html、xml)、关键句提取 软件开发手记
荐
                                                        图像转文本、PDF 转文字(包括html、xml)、关键句提取 软件开发手记
荐
                                                        图像转文本、PDF 转文字(包括html、xml)、关键句提取 软件开发手记
(支持输入任意图片格式~~)

PDF 转文字

荐
                                                        图像转文本、PDF 转文字(包括html、xml)、关键句提取 软件开发手记
效果:
荐
                                                        图像转文本、PDF 转文字(包括html、xml)、关键句提取 软件开发手记
日文:
荐
                                                        图像转文本、PDF 转文字(包括html、xml)、关键句提取 软件开发手记
英文当然也可以,这里不再展示了。

关键句提取

荐
                                                        图像转文本、PDF 转文字(包括html、xml)、关键句提取 软件开发手记

古文排版

荐
                                                        图像转文本、PDF 转文字(包括html、xml)、关键句提取 软件开发手记

Tkinter 有关指南:

这里使用的是 Tkinter 来开发一款软件的,如果不是用 Tkinter,请移步。
首先推荐一些 Tkinter 的教程吧:
Tkinter GUI 01
Tkinter GUI 02
Tkinter GUI 03
Tkinter GUI 04
Tkinter GUI 05
Tkinter GUI 06
Tkinter GUI 07
Tkinter GUI 08

然后,是一些有用的参考资料和书籍的下载地址:
Python GUI Tkinter 参考资料

下面是另一个软件,Word 转手写体
https://blog.csdn.net/weixin_42141390/article/details/106840073

本文地址:https://blog.csdn.net/weixin_42141390/article/details/107147254