a { text-decoration: none }

    一直想用python做一个截图并自动翻译的工具,恰好最近有时间就在网上找了资料,根据资料以及自己的理解做了一个简单的截图翻译工具。整理一下并把代码放在github给大家参考。界面用python自带的GUI的tkinter,截图用的是pillow,图片识别用的是百度ocr的api,翻译用的是百度翻译api。

 

1、前期准备

(1) demo环境

window 10
python3.6

baidu-aip==2.2.18.0
certifi==2019.11.28
chardet==3.0.4
idna==2.8
Pillow==6.2.1
requests==2.22.0
urllib3==1.25.7

(2)安装第三方包

pip install pillow
pip install baidu-aip

(3)百度ocr的api申请步骤参考 点击跳转

    申请百度的ocr的api,添加项目获取相应的appid等信息

 

 

 

 

 

(4)百度翻译api申请步骤参考 点击跳转

  申请百度翻译的api,添加项目获取相应的appid等信息

 

 

 

 

 

(5)tkinter教程参考   点击跳转

  使用tkinter制作GUI界面。

  设计思路:

    1)点击截图按钮先截取当前屏幕的全屏截图

    2)在截取的全屏截图上点击鼠标左键拖动鼠标选择需要截取的区域,截取成功后调用百度ocr的api完成图片的识别,并把结果返回到左边的文本框。

    3)点击翻译按钮调用百度翻译的api把刚才识别的结果翻译成英文(目前只做了中文翻译成英文)并把结果返回到右边的文本框。

  最终效果图:

  

 

 

 

(6)pillow教程参考 点击跳转

   用pillow模块实现最终的截图效果并保存图片

 

(7)python程序打包成exe文件

#安装
pip install pyinstaller

#到项目文件夹打包你要的打包的python文件
pyinstaller -w myCapture1.3.py

 

 2、最终项目代码  github地址

有问题请留言!觉得项目不错记得点个star,谢谢!

 

  1 # -*- coding: utf-8 -*-
  2 # __author: rock
  3 # @time: 2019-12-03
  4 import tkinter
  5 # import asyncio
  6 from PIL import ImageGrab
  7 from aip import AipOcr
  8 import time
  9 import os
 10 import http.client
 11 import hashlib
 12 import json
 13 import urllib
 14 import random
 15 
 16 
 17 class MyCapture:
 18 
 19     def __init__(self):
 20         # 变量X和Y用来记录鼠标左键按下的位置
 21         self.X = tkinter.IntVar(value=0)
 22         self.Y = tkinter.IntVar(value=0)
 23         self.sel = False
 24         self.ocr_text = None
 25         self.capture_png_path = \'\'
 26         self.capture_text_box = tkinter.Text(window)  # 创建text容器用于存放截图识别的文字
 27         self.capture_text_box.place(x=20, y=50, anchor=\'nw\', width=170, height=330)
 28 
 29         self.translate_text_box = tkinter.Text(window)  # 创建text容器用于存放翻译后的文字
 30         self.translate_text_box.place(x=210, y=50, anchor=\'nw\', width=170, height=330)
 31 
 32         self.capture_btn = tkinter.Button(text=\'截图\', command=self.capture_cmd)  # 创建一个按钮
 33         self.capture_btn.place(x=80, y=10, anchor=\'nw\', width=60, height=20)  # 在创建的窗口的西北角x=20,y=10处放置按钮
 34 
 35         self.capture_btn = tkinter.Button(text=\'翻译\', command=self.translate_cmd)  # 创建一个按钮
 36         self.capture_btn.place(x=260, y=10, anchor=\'nw\', width=60, height=20)
 37         # 屏幕尺寸
 38         self.screenWidth = window.winfo_screenwidth()
 39         self.screenHeight = window.winfo_screenheight()
 40         self.temp_png = \'temp.png\'
 41         # self.create_canvas()
 42 
 43     def create_canvas(self):
 44         time.sleep(0.2)
 45         im = ImageGrab.grab()
 46         im.save(self.temp_png)
 47         im.close()
 48         # 创建顶级组件容器
 49         self.top = tkinter.Toplevel(window, width=self.screenWidth, height=self.screenHeight)
 50         # 不显示最大化、最小化按钮
 51         self.top.overrideredirect(True)
 52         self.canvas = tkinter.Canvas(self.top, bg=\'white\', width=self.screenWidth, height=self.screenHeight)
 53         # 显示全屏截图,在全屏截图上进行区域截图
 54         self.image = tkinter.PhotoImage(file=self.temp_png)
 55         self.canvas.create_image(self.screenWidth // 2, self.screenHeight // 2, image=self.image)
 56 
 57         # 鼠标左键按下的位置
 58         self.canvas.bind(\'<Button-1>\', self.mouse_left_down)
 59         # 鼠标左键移动,显示选取的区域
 60         self.canvas.bind(\'<B1-Motion>\', self.mouse_move)
 61         # 获取鼠标左键抬起的位置,保存区域截图
 62         self.canvas.bind(\'<ButtonRelease-1>\', self.mouse_left_up)
 63 
 64         self.canvas.pack(fill=tkinter.BOTH, expand=tkinter.YES)
 65 
 66     def mouse_left_down(self, event):
 67         """鼠标左键按下的位置"""
 68         self.X.set(event.x)
 69         self.Y.set(event.y)
 70         self.sel = True  # 开始截图
 71 
 72     # 鼠标左键移动,显示选取的区域
 73     def mouse_move(self, event):
 74         if not self.sel:
 75             return
 76         try:
 77             # 删除刚画完的图形,要不然鼠标移动的时候是黑乎乎的一片矩形
 78             self.canvas.delete(self.lastDraw)
 79         except Exception as e:
 80             pass
 81         self.lastDraw = self.canvas.create_rectangle(self.X.get(), self.Y.get(), event.x, event.y, outline=\'red\')
 82 
 83     def mouse_left_up(self, event):
 84         """获取鼠标左键抬起的位置,保存区域截图"""
 85         self.sel = False
 86         try:
 87             self.canvas.delete(self.lastDraw)
 88         except Exception as e:
 89             pass
 90         # 考虑鼠标左键从右下方按下而从左上方抬起的截图
 91         x1, x2 = sorted([self.X.get(), event.x])  # tkinter记录的坐标点
 92         y1, y2 = sorted([self.Y.get(), event.y])
 93 
 94         pic = ImageGrab.grab((x1+1, y1+1, x2, y2))
 95         # pic.show()
 96         self.capture_png_path = \'capture_png.png\'
 97         pic.save(self.capture_png_path)
 98 
 99         # 关闭当前窗口
100         self.top.destroy()
101 
102     def capture_cmd(self):
103         """点击截图按钮触发函数"""
104         window.iconify()  # 窗口最小化
105         # 显示全屏幕截图
106         self.create_canvas()
107         self.capture_btn.wait_window(self.top)
108         os.remove(self.temp_png)
109         self.ocr_text = self.baidu_ocr(self.capture_png_path)
110         # print(self.ocr_text)
111         if self.ocr_text:
112             self.capture_text_box.delete(\'1.0\', tkinter.END)   # 清空文本框
113             self.translate_text_box.delete(\'1.0\', tkinter.END)
114             self.capture_text_box.insert(\'end\', self.ocr_text)
115             window.deiconify()  # 窗口显示
116             os.remove(self.capture_png_path)
117 
118     def translate_cmd(self):
119         """点击翻译按钮触发函数"""
120         if self.ocr_text:
121             self.translate_text = self.baidu_translate(self.ocr_text)
122             self.translate_text_box.delete(\'1.0\', tkinter.END)
123             if self.translate_text:
124                 self.translate_text_box.insert(\'end\', self.translate_text)
125 
126     def baidu_ocr(self, file_path):
127         """ 调用通用文字识别, 图片参数为本地图片 """
128         app_id = \'\'
129         api_key = \'\'
130         secret_key = \'\'
131         ocr_text = \'\'
132         if os.path.isfile(file_path):
133             with open(file_path, \'rb\') as fp:
134                 image = fp.read()
135             ocr_ret = AipOcr(app_id, api_key, secret_key).basicGeneral(image)
136             words = ocr_ret.get(\'words_result\')
137             if words is not None and len(words):
138                 for word in words:
139                     # print(word[\'words\'], end=\'\n\')
140                     ocr_text += word[\'words\'] + \'\n\'
141                 return ocr_text
142             else:
143                 return None
144         else:
145             return None
146 
147     def baidu_translate(self, content):
148         app_id = \'\'
149         secret_key = \'\'
150         http_client = None
151         myurl = \'/api/trans/vip/translate\'
152         q = content
153         from_lang = \'zh\'  # 源语言
154         to_lang = \'en\'  # 翻译后的语言
155         salt = random.randint(32768, 65536)
156         sign = app_id + q + str(salt) + secret_key
157         sign = hashlib.md5(sign.encode()).hexdigest()
158         myurl = myurl + \'?appid=\' + app_id + \'&q=\' + urllib.parse.quote(
159             q) + \'&from=\' + from_lang + \'&to=\' + to_lang + \'&salt=\' + str(
160             salt) + \'&sign=\' + sign
161 
162         try:
163             http_client = http.client.HTTPConnection(\'api.fanyi.baidu.com\')
164             http_client.request(\'GET\', myurl)
165             # response是HTTPResponse对象
166             response = http_client.getresponse()
167             json_response = response.read().decode("utf-8")  # 获得返回的结果,结果为json格式
168             js = json.loads(json_response)  # 将json格式的结果转换字典结构
169             dst = str(js["trans_result"][0]["dst"])  # 取得翻译后的文本结果
170             # print(dst)  # 打印结果
171             return dst
172         except Exception as e:
173             print(e)
174             return None
175         finally:
176             if http_client:
177                 http_client.close()
178 
179 
180 window = tkinter.Tk()
181 window.title(\'Capture\')
182 # 创建tkinter主窗口
183 window.geometry(\'400x400\')  # 指定主窗口位置与大小
184 MyCapture()
185 window.mainloop()

 

 

 可选择语言版本1.3

 

 

# -*- coding: utf-8 -*-
# __author: rock
# @time: 2019-12-03
import tkinter
# import asyncio
from PIL import ImageGrab
from aip import AipOcr
import time
import os
import http.client
import hashlib
import json
import urllib
import random
from tkinter import ttk


# def get_from_lang(self):
#     print(self.from_lang.get())
#     # return
#
#
# def get_to_lang(self):
#     print(self.to_lang.get())
#     # return


class MyCapture:

    def __init__(self):
        # 变量X和Y用来记录鼠标左键按下的位置
        self.X = tkinter.IntVar(value=0)
        self.Y = tkinter.IntVar(value=0)
        self.sel = False
        self.ocr_text = None
        self.capture_png_path = \'\'
        self.capture_text_box = tkinter.Text(window)  # 创建text容器用于存放截图识别的文字
        self.capture_text_box.place(x=20, y=70, anchor=\'nw\', width=170, height=330)

        self.translate_text_box = tkinter.Text(window)  # 创建text容器用于存放翻译后的文字
        self.translate_text_box.place(x=210, y=70, anchor=\'nw\', width=170, height=330)

        self.capture_btn = tkinter.Button(text=\'截图\', command=self.capture_cmd)  # 创建一个按钮
        self.capture_btn.place(x=80, y=10, anchor=\'nw\', width=60, height=20)  # 在创建的窗口的西北角x=20,y=10处放置按钮

        self.capture_btn = tkinter.Button(text=\'翻译\', command=self.translate_cmd)  # 创建一个按钮
        self.capture_btn.place(x=270, y=10, anchor=\'nw\', width=60, height=20)

        # 下拉选择框
        self.from_lang = \'zh\'
        self.to_lang = \'en\'
        self.lang_dic = {\'自动识别\': \'auto\', \'中文\': \'zh\', \'英语\': \'en\', \'日语\': \'jp\'}
        self.from_lang_L = tkinter.Label(window, text=\'原语言:\')
        self.from_lang_box = ttk.Combobox(window, state="readonly")
        self.from_lang_box[\'value\'] = (\'自动识别\', \'中文\', \'英语\', \'日语\')
        self.from_lang_box.current(1)
        self.from_lang_L.place(x=20, y=40, anchor=\'nw\')
        self.from_lang_box.place(x=80, y=40, anchor=\'nw\', width=80, height=20)
        self.from_lang_box.bind("<<ComboboxSelected>>", self.get_from_lang)

        self.to_lang_L = tkinter.Label(window, text=\'目标语言:\')
        self.to_lang_box = ttk.Combobox(window,state="readonly")
        self.to_lang_box[\'value\'] = (\'中文\', \'英语\', \'日语\')
        self.to_lang_box.current(1)
        self.to_lang_L.place(x=210, y=40, anchor=\'nw\')
        self.to_lang_box.place(x=270, y=40, anchor=\'nw\', width=60, height=20)
        self.to_lang_box.bind("<<ComboboxSelected>>", self.get_to_lang)

        # 屏幕尺寸
        self.screenWidth = window.winfo_screenwidth()
        self.screenHeight = window.winfo_screenheight()
        self.temp_png = \'temp.png\'
        # self.create_canvas()

    def create_canvas(self):
        time.sleep(0.2)
        im = ImageGrab.grab()
        im.save(self.temp_png)
        im.close()
        # 创建顶级组件容器
        self.top = tkinter.Toplevel(window, width=self.screenWidth, height=self.screenHeight)
        # 不显示最大化、最小化按钮
        self.top.overrideredirect(True)
        self.canvas = tkinter.Canvas(self.top, bg=\'white\', width=self.screenWidth, height=self.screenHeight)
        # 显示全屏截图,在全屏截图上进行区域截图
        self.image = tkinter.PhotoImage(file=self.temp_png)
        self.canvas.create_image(self.screenWidth // 2, self.screenHeight // 2, image=self.image)

        # 鼠标左键按下的位置
        self.canvas.bind(\'<Button-1>\', self.mouse_left_down)
        # 鼠标左键移动,显示选取的区域
        self.canvas.bind(\'<B1-Motion>\', self.mouse_move)
        # 获取鼠标左键抬起的位置,保存区域截图
        self.canvas.bind(\'<ButtonRelease-1>\', self.mouse_left_up)

        self.canvas.pack(fill=tkinter.BOTH, expand=tkinter.YES)

    def mouse_left_down(self, event):
        """鼠标左键按下的位置"""
        self.X.set(event.x)
        self.Y.set(event.y)
        self.sel = True  # 开始截图

    # 鼠标左键移动,显示选取的区域
    def mouse_move(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=\'red\')

    def mouse_left_up(self, event):
        """获取鼠标左键抬起的位置,保存区域截图"""
        self.sel = False
        try:
            self.canvas.delete(self.lastDraw)
        except Exception as e:
            pass
        # 考虑鼠标左键从右下方按下而从左上方抬起的截图
        x1, x2 = sorted([self.X.get(), event.x])  # tkinter记录的坐标点
        y1, y2 = sorted([self.Y.get(), event.y])

        pic = ImageGrab.grab((x1+1, y1+1, x2, y2))
        # pic.show()
        self.capture_png_path = \'capture_png.png\'
        pic.save(self.capture_png_path)

        # 关闭当前窗口
        self.top.destroy()

    def capture_cmd(self):
        """点击截图按钮触发函数"""
        window.iconify()  # 窗口最小化
        # 显示全屏幕截图
        self.create_canvas()
        self.capture_btn.wait_window(self.top)
        os.remove(self.temp_png)
        self.ocr_text = self.baidu_ocr(self.capture_png_path)
        print(self.ocr_text)
        if self.ocr_text:
            self.capture_text_box.delete(\'1.0\', tkinter.END)   # 清空文本框
            self.translate_text_box.delete(\'1.0\', tkinter.END)
            self.capture_text_box.insert(\'end\', self.ocr_text)
            window.deiconify()  # 窗口显示
            os.remove(self.capture_png_path)

    def translate_cmd(self):
        """点击翻译按钮触发函数"""
        if self.ocr_text:
            self.translate_text = self.baidu_translate(self.ocr_text)
            self.translate_text_box.delete(\'1.0\', tkinter.END)
            if self.translate_text:
                self.translate_text_box.insert(\'end\', self.translate_text)

    def baidu_ocr(self, file_path):
        """ 调用通用文字识别, 图片参数为本地图片 """
        app_id = \'你自己的appid\'
        api_key = \'你自己的api_key\'
        secret_key = \'你自己的secret_key\'
        ocr_text = \'\'
        if os.path.isfile(file_path):
            with open(file_path, \'rb\') as fp:
                image = fp.read()
            ocr_ret = AipOcr(app_id, api_key, secret_key).basicGeneral(image)
            words = ocr_ret.get(\'words_result\')
            if words is not None and len(words):
                for word in words:
                    # print(word[\'words\'], end=\'\n\')
                    ocr_text += word[\'words\'] + \'\n\'
                return ocr_text
            else:
                return None
        else:
            return None

    def baidu_translate(self, content):
        app_id = \'你自己的appid\'
        secret_key = \'你自己的secretkey\'
        http_client = None
        myurl = \'/api/trans/vip/translate\'
        q = content
        # from_lang = \'zh\'  # 源语言
        from_lang = self.from_lang  # 源语言
        to_lang = self.to_lang  # 翻译后的语言
        # to_lang = \'en\'  # 翻译后的语言
        salt = random.randint(32768, 65536)
        sign = app_id + q + str(salt) + secret_key
        sign = hashlib.md5(sign.encode()).hexdigest()
        myurl = myurl + \'?appid=\' + app_id + \'&q=\' + urllib.parse.quote(
            q) + \'&from=\' + from_lang + \'&to=\' + to_lang + \'&salt=\' + str(
            salt) + \'&sign=\' + sign

        try:
            http_client = http.client.HTTPConnection(\'api.fanyi.baidu.com\')
            http_client.request(\'GET\', myurl)
            # response是HTTPResponse对象
            response = http_client.getresponse()
            json_response = response.read().decode("utf-8")  # 获得返回的结果,结果为json格式
            js = json.loads(json_response)  # 将json格式的结果转换字典结构
            # print(js)
            dst = str(js["trans_result"][0]["dst"])  # 取得翻译后的文本结果
            # print(dst)  # 打印结果
            return dst
        except Exception as e:
            print(e)
            return None
        finally:
            if http_client:
                http_client.close()

    def get_from_lang(self, event):
        # print(self.from_lang_box.get())
        self.from_lang = self.lang_dic[self.from_lang_box.get()]
        # return

    def get_to_lang(self, event):
        # print(self.to_lang_box.get())
        self.to_lang = self.lang_dic[self.to_lang_box.get()]
        # return


window = tkinter.Tk()
window.title(\'Capture\')
# 创建tkinter主窗口
window.geometry(\'400x420\')  # 指定主窗口位置与大小
capture = MyCapture()
# capture.from_lang.bind("<<ComboboxSelected>>", get_from_lang(capture))
# capture.to_lang.bind("<<ComboboxSelected>>", get_to_lang(capture))
window.mainloop()

  

 

版权声明:本文为chen55555原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/chen55555/p/11988054.html