荐 图像转文本、PDF 转文字(包括html、xml)、关键句提取 软件开发手记
文章目录
准备工作
声明
要源码的请关注后留言
软件效果请看使用指南
所需模块:
模块简介
Tkinter:主要是 GUI 模块
pytesseract:图像转文字 API 接口
pdfminter3:读取 PDF 并转换成其他格式
pyhanlp:进行关键句提取
安装方法:
清华源 pip 走起:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pytesseract
软件开发
图像转文本
在图像转文本 软件中,需要首先下载一个 tesseract 的开源,文本转图像工具。然后,通过 pytesseract 调用其 API,来实现图像识别文本(OCR)
可以下载任意版本,这里推荐下载最新版本
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)
软件使用
关于界面
界面如下:
国际化效果展示
在开始菜单里,有弄了个国际化,效果如下:
国际化实现
将文本封装成一个类即可,就是 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()
使用指南
图像转文本
在 输出路径中,可以得到 output.txt 文件
也可以识别日文、英文、繁体中文,而且效果不错。不过,公式就算了吧,效果太 low 了。
(支持输入任意图片格式~~)
PDF 转文字
效果:
日文:
英文当然也可以,这里不再展示了。
关键句提取
古文排版
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
上一篇: Visual Studio Code配置
下一篇: 功能齐全的Real播放器