• python截图+百度ocr(图片识别)+ 百度翻译(可选择翻译语言)


        一直想用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='
    ')
    140                     ocr_text += word['words'] + '
    '
    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='
    ')
                        ocr_text += word['words'] + '
    '
                    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()
    

      

  • 相关阅读:
    CSS 专业技巧
    MyBatisPlus大于等于、小于等于等等函数
    最新国内手机号校验正则表达式
    前端自动化测试----百度搜索功能实战
    pytest:数据驱动;结合allure生成测试报告
    pytest:参数化用例
    pytest:多线程并行和分布式执行;结合pytest-html生成测试报告
    pytest:自动执行fixture;fixture传递参数
    pytest:conftest.py文件
    pytest:通过scope控制fixture的作用范围
  • 原文地址:https://www.cnblogs.com/chen55555/p/11988054.html
Copyright © 2020-2023  润新知