安装文字识别软件
参考 python-文字识别-tesseract
安装python需要的库
pip install pillow==9.0.1
pip install pytesseract==0.3.8
使用涉及到的技术
- tkinter编程
- Python+tkinter+pillow实现屏幕任意区域截图
- 图片显示
- 图片保存
- 图片文字识别
- 剪贴板复制
具体代码如下
"""
文件名: main.py
功 能:XXX类,该类主要涉及XXX功能
版权信息:版本所有(C) 2019-2022
修改记录:
2022-05-16 19:11:57 创建
2022-05-16 19:11:57 修改
安装库:
python -m pip install --upgrade pip
pip install pillow==9.0.1
pip install pytesseract==0.3.8
参考资料:
https://cloud.tencent.com/developer/article/1097904
https://digi.bib.uni-mannheim.de/tesseract/
https://gitcode.net/mirrors/tesseract-ocr/tessdata?utm_source=csdn_github_accelerator
https://zhuanlan.zhihu.com/p/452913602
"""
import tkinter as tk
import tkinter.filedialog
from PIL import ImageGrab, ImageTk, Image
import pytesseract
import time
import os
class MouseCapture:
"""用来显示全屏幕截图并响应二次截图的窗口类"""
@staticmethod
def __get_desktop():
desktop = tk.Toplevel()
desktop.overrideredirect(True)
return desktop
def __canvas_on_mouse_left_button_down(self, event: tk.Event):
"""鼠标左键按下的位置"""
self.__x_pos.set(getattr(event, "x"))
self.__y_pos.set(getattr(event, "y"))
self.__select = True
def __canvas_on_mouse_left_button_move(self, event: tk.Event):
"""鼠标左键移动,显示选取的区域"""
if not self.__select:
return
canvas = getattr(event, "widget")
canvas.delete(self.__last_draw_rectangle)
self.__last_draw_rectangle = canvas.create_rectangle(
self.__x_pos.get(), self.__y_pos.get(),
getattr(event, "x"), getattr(event, "y"),
outline='black')
def __canvas_on_mouse_left_button_up(self, event: tk.Event):
"""获取鼠标左键抬起的位置,保存区域截图"""
self.__select = False
canvas = getattr(event, "widget")
canvas.delete(self.__last_draw_rectangle)
time.sleep(0.1)
left, right = sorted([self.__x_pos.get(), getattr(event, "x")])
top, bottom = sorted([self.__y_pos.get(), getattr(event, "y")])
self.__capture_bbox = (left + 1, top + 1, right, bottom)
self.__capture_image = ImageGrab.grab(self.__capture_bbox)
canvas.master.destroy()
def __get_canvas(self, master):
screen_width = master.winfo_screenwidth()
screen_height = master.winfo_screenheight()
canvas = tk.Canvas(master, bg='white', width=screen_width,
height=screen_height)
self.__screen_image = ImageTk.PhotoImage(image=ImageGrab.grab())
canvas.create_image(screen_width//2, screen_height//2,
image=self.__screen_image)
canvas.bind('<Button-1>', self.__canvas_on_mouse_left_button_down)
canvas.bind('<B1-Motion>', self.__canvas_on_mouse_left_button_move)
canvas.bind('<ButtonRelease-1>', self.__canvas_on_mouse_left_button_up)
canvas.pack(fill=tk.BOTH, expand=tk.YES)
return canvas
def __init__(self):
self.__x_pos = tk.IntVar(value=0)
self.__y_pos = tk.IntVar(value=0)
self.__screen_image = None
self.__select = False
self.__last_draw_rectangle = None
self.__capture_bbox = None
self.__capture_image = None
self.__desktop = self.__get_desktop()
self.__get_canvas(self.__desktop)
def __del__(self):
self.__desktop.destroy()
@property
def desktop(self):
return self.__desktop
@property
def capture_bbox(self):
return self.__capture_bbox
@property
def capture_image(self):
return self.__capture_image
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
toolbar = tk.Frame(self.master, bd=1, relief=tk.RAISED)
toolbar.pack(side=tk.TOP, fill=tk.X)
self.__tool_item(toolbar, 1, "截取屏幕", bind=self.btn_capture_on_click)
self.__tool_item(toolbar, 2, "复制文本", command=self.btn_copy_on_click)
self.__tool_item(toolbar, 3, "保存截图", command=self.btn_save_on_click)
self.__tool_item(toolbar, 4, "识别图片", command=self.btn_open_on_click)
self.__tool_item(toolbar, 5, "退出程序", command=self.master.destroy)
self.pack()
self.__txt_ocr_text = tk.Text(self, height=10, relief=tk.RAISED)
self.__txt_ocr_text.pack(fill=tk.X)
self.__lbl_capture_img = tk.Label(self, relief=tk.RAISED)
self.__lbl_capture_img.pack(fill=tk.X)
self.__screen_image = None
@staticmethod
def __get_image(filename):
return ImageTk.PhotoImage(Image.open(os.path.join("images", filename)))
def __tool_item(self, master, serial_num, text, bind=None, command=None):
btn_kw = {
"compound": tk.LEFT,
"relief": tk.FLAT, "text": text, "font": ('', '16')}
if command:
btn_kw["command"] = command
btn = tk.Button(master, **btn_kw)
if bind:
btn.bind("<ButtonRelease-1>", bind)
btn.grid(row=1, column=serial_num, padx=10)
def btn_open_on_click(self):
"""保存截图"""
filename = tkinter.filedialog.askopenfilename(
title='打开图片', filetypes=[('image', '*.jpg *.png')])
if filename and self.__screen_image:
self.__screen_image = Image.open(filename)
self.__ocr_image(self.__screen_image)
def __ocr_image(self, image: Image):
tk_image = ImageTk.PhotoImage(image)
self.__lbl_capture_img.configure(image=tk_image)
self.__lbl_capture_img.image = tk_image
self.__txt_ocr_text.delete("1.0", "end")
ocr_text = pytesseract.image_to_string(image, lang='chi_sim')
self.__txt_ocr_text.insert("end", ocr_text)
def btn_save_on_click(self):
"""保存截图"""
filename = tkinter.filedialog.asksaveasfilename(
title='保存截图', filetypes=[('image', '*.jpg *.png')])
if filename and self.__screen_image:
self.__screen_image.save(filename)
def btn_copy_on_click(self):
"""复制文本到剪贴板"""
self.master.clipboard_clear()
ocr_txt = self.__txt_ocr_text.get("1.0", "end").strip()
self.master.clipboard_append(ocr_txt)
self.master.update()
def btn_capture_on_click(self, event: tk.Event):
"""截取屏幕"""
self.master.state('icon')
time.sleep(0.2)
mc = MouseCapture()
getattr(event, "widget").wait_window(mc.desktop)
self.__screen_image = mc.capture_image
self.__ocr_image(self.__screen_image)
self.master.state('normal')
@staticmethod
def start_app():
root = tk.Tk()
root.geometry('800x600')
Application(master=root)
root.mainloop()
if __name__ == '__main__':
Application.start_app()