一直想用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模塊實現最終的截圖效果並保存圖片
#安裝 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()
