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模块实现最终的截图效果并保存图片
2、最终项目代码 github地址
有问题请留言!觉得项目不错记得点个star,谢谢!
# -*- 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 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=50, anchor='nw', width=170, height=330) self.translate_text_box = tkinter.Text(window) # 创建text容器用于存放翻译后的文字
self.translate_text_box.place(x=210, y=50, 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=260, y=10, anchor='nw', width=60, height=20)
# 屏幕尺寸
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 = ''
api_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 = ''
secret_key = ''
http_client = None
myurl = '/api/trans/vip/translate'
q = content
from_lang = 'zh' # 源语言
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格式的结果转换字典结构
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() window = tkinter.Tk()
window.title('Capture')
# 创建tkinter主窗口
window.geometry('400x400') # 指定主窗口位置与大小
MyCapture()
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()
python截图+百度ocr(图片识别)+ 百度翻译的更多相关文章
- python实现百度OCR图片识别
一.直接上代码 import base64 import requests class CodeDemo: def __init__(self,AK,SK,code_url,img_path): se ...
- 一篇文章搞定百度OCR图片文字识别API
一篇文章搞定百度OCR图片文字识别API https://www.jianshu.com/p/7905d3b12104
- Python实现图片识别加翻译【高薪必学】
Python使用百度AI接口实现图片识别加翻译 另外很多人在学习Python的过程中,往往因为没有好的教程或者没人指导从而导致自己容易放弃,为此我建了个Python交流.裙 :一久武其而而流一思(数字 ...
- 百度OCR 文字识别 Android安全校验
百度OCR接口使用总结: 之前总结一下关于百度OCR文字识别接口的使用步骤(Android版本 不带包名配置 安全性弱).这边博客主要介绍,百度OCR文字识别接口,官方推荐使用方式,授权文件(安全模式 ...
- 百度OCR文字识别-Android安全校验
本文转载自好基友upuptop:https://blog.csdn.net/pyfysf/article/details/86438769 效果图: 如下为文章正文: 百度OCR接口使用总结:之前总结 ...
- Python批量图片识别并翻译——我用python给女朋友翻译化妆品标签
Python批量图片识别并翻译--我用python给女朋友翻译化妆品标签 最近小编遇到一个生存问题,女朋友让我给她翻译英文化妆品标签.美其名曰:"程序猿每天英语开发,英文一定很好吧,来帮我翻 ...
- Python 3 实现色情图片识别
Python 3 实现色情图片识别 项目简介 项目内容 本实验将使用 Python3 去识别图片是否为色情图片,我们会使用到 PIL 这个图片处理库,会编写算法来划分图像的皮肤区域. 项目知识点 Py ...
- 【程序员的吃鸡大法】利用OCR文字识别+百度算法搜索,玩转冲顶大会、百万英雄、芝士超人等答题赢奖金游戏
[先上一张效果图]: 一.原理: 其实原理很简单: 1.手机投屏到电脑: 2.截取投屏画面的题目部分,进行识别,得到题目和三个答案: 3.将答案按照一定的算法,进行搜索,得出推荐答案: 4.添加了一些 ...
- 利用OCR文字识别+百度算法搜索,玩转冲顶大会、百万英雄、芝士超人等答题赢奖金游戏
[先上一张效果图]: 一.原理: 其实原理很简单: 1.手机投屏到电脑: 2.截取投屏画面的题目部分,进行识别,得到题目和三个答案: 3.将答案按照一定的算法,进行搜索,得出推荐答案: 4.添加了一些 ...
- 百度Ocr文字识别
简述 最近开发一个项目需要用到Ocr文字识别技术来识别手写文字,在评估过程中体验了百度的文字识别和腾讯的文字识别.查找官方开发文档,发现它们都有印刷体和手写体两种符合项目需求的识别模式,但是腾讯的手写 ...
随机推荐
- UPDATE - 更新一个表中的行
SYNOPSIS UPDATE [ ONLY ] table SET column = { expression | DEFAULT } [, ...] [ FROM fromlist ] [ WHE ...
- egrep 或与
' HEADERABC' .txt | .txt 'HEADERABC' .txt > .txt .txt > .txt ' HEADERABC' ' TAILER123' .txt &g ...
- python 将字符串转换成字典dict
JSON到字典转化:>>>dictinfo = json.loads(json_str) 输出dict类型 字典到JSON转化:>>>jsoninfo = json ...
- redis安装到本地服务的方法
要安装Redis,首先要获取安装包. Windows的Redis安装包需要到以下GitHub链接找到. 链接:https://github.com/MSOpenTech/redis 打开网站后,找到R ...
- 三种Spring加载机制
方法一. 在main方法中启动Spring ApplicationContext ac = new XmlApplicationContext("applicationContext.xml ...
- Java中的接口是怎么实现的
接口 使用关键字interface来定义一个接口,和类的定义方法很相似分为接口声明和接口体. interface Printable { final int MAX = 100; void add( ...
- JavaScript ---- 闭包(什么是闭包,为什么使用闭包,闭包的作用)
经常被问到什么是闭包? 说实话闭包这个概念很难解释.JavaScript权威指南里有这么一段话:“JavaScript函数是将要执行的代码以及执行这些代码作用域构成的一个综合体.在计算机学术语里,这种 ...
- Go 转义字符
Go 转义字符 package main import "fmt" func main() { fmt.Printf("Hello\tWorld!") } 本文 ...
- lua数组和数据类型转换
一.lua数组 Lua数组大小不固定,下标是从 1开始. --数组 arr={"aaa","bbb","ccc"} --使用数值 for通 ...
- BZOJ 3779: 重组病毒(线段树+lct+树剖)
题面 escription 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病 ...