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='\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()

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM