1.引言:
网上有很多的ocr识别图片转文字再翻译的软件。但是没有翻译日语的。于是想自己做一个对含有日语的图片进行识别并翻译为中文的小工具。这里提一下,如果看这篇文章的人只是希望找个选中文本并翻译的软件程序,那推荐看此链接程序。
这个软件功能是复制文本然后自动翻译,支持日语、英语等多种语言。
如果还是希望实现截图翻译,请继续看,下文娓娓道来。
2.思路:
基本动作流程:
截图 ->对剪切板中图片的文字进行识别->翻译。
3.具体实现:
1).对需要翻译的内容截图。
截图可通过搭配其他软件来实现。使用QQ或者微信等截图工具截图到剪切板也行。或者自己开发也行。
这里,我用的是网上流行的微信的dll库来实现截图的。名字:PrScrn.dll。网上有下载,但好像都是32位的,看网上是用下面的代码来使用这个截图dll的。我运行的时候出错了。这里也贴一下,或许对于制作的人有参考。估计python 是32位的应该可以使用。或许有了解确切原因的请留言。
# #**********调用微信dll截图********************
def capture():
import ctypes
try:
dll = ctypes.cdll.LoadLibrary('PrScrn.dll')
except Exception as e:
print("Dll load error: ")
print(e)
return
else:
try:
dll.PrScrn(0)
except:
print("Sth wrong in capture!")
return
因为电脑python是64的。后来改成python代码中运行,出现截图框了,截图反正是好用了。
os.system('rundll32 PrScrn.dll PrScrn')
另外是监视剪贴板内容,参照这个
def main():
im = ImageGrab.grabclipboard()
if 'image' in str(im):
#print(im)
pyperclip.copy('test')
assert isinstance(im, object)
im.save("ocr.png")
img_path = os.path.join(os.getcwd(), "ocr.png")
content = vcode2str(img_path)
ui.setOcrText(str(content))
#mytext=fanyi(content)
mytext=my_translate(content)
ui.setTransText(str(mytext))
os.remove(img_path)
time.sleep(2)
else:
pass
#print("请检查是否正确截图后重试!")
import win32con,win32gui
import win32clipboard as cb
class MyWindow(): #剪切板监听
def __init__(self):
#注册一个窗口类
wc = win32gui.WNDCLASS()
wc.lpszClassName = 'MyWindow'
wc.hbrBackground = win32con.COLOR_BTNFACE+1
wc.lpfnWndProc = self.wndProc
class_atom=win32gui.RegisterClass(wc)
#创建窗口
self.hwnd = win32gui.CreateWindow( class_atom, u'OCR',
win32con.WS_OVERLAPPEDWINDOW,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT, 0,0, 0, None)
# 显示窗口
# win32gui.ShowWindow(self.hwnd, win32con.SW_SHOWNORMAL)
#消息处理
def wndProc(self, hwnd, msg, wParam, lParam):
if msg == win32con.WM_DESTROY:
win32gui.PostQuitMessage(0)
if msg == win32con.WM_DRAWCLIPBOARD: #当剪切板更新的时候收到这个消息
main()
return win32gui.DefWindowProc(hwnd, msg, wParam, lParam)
2).图片转文本(日语),OCR。
依靠百度开发平台的OCR来实现。具体注册过程就不写了,网上会找到。终点是要得到三个值。appID,API key, secret Key。下面程序要用。
另外,还要安装百度的sdk.
我用的是pycharm,如下安装即可。很方便。
对于OCR调试的话,百度开发平台官网有例子程序。如下,先运行看看。先确保自己目前申请和搭建的环境是可用的。
from aip import AipOcr
""" 你的 APPID AK SK """
APP_ID = '123321'
API_KEY = 'vrUQ0123123123KsXIUT'
SECRET_KEY = 'm6zy123123123123123PGikQ'
client = AipOcr(APP_ID, API_KEY, SECRET_KEY)
""" 读取图片 """
def get_file_content(filePath):
with open(filePath, 'rb') as fp:
return fp.read()
image = get_file_content('C:\\Users\\Administrator\\Desktop\\AAA.bmp')
""" 调用通用文字识别, 图片参数为本地图片 """
#client.basicGeneral(image);
""" 如果有可选参数 """
options = {}
options["language_type"] = "CHN_ENG"
options["detect_direction"] = "true"
options["detect_language"] = "true"
options["probability"] = "true"
""" 带参数调用通用文字识别, 图片参数为本地图片 """
result=client.basicGeneral(image, options)
print(result)
详细参数设置请参照下面官网链接:比如设置其他语言的识别等等。
https://cloud.baidu.com/doc/OCR/OCR-Python-SDK.html#.E6.96.B0.E5.BB.BAAipOcr
3).日语翻译为中文。
本来想用百度翻译的。但是下面这个提交参数sig和token不知道怎么生成的。于是就放弃这个途径了。
还有一种方式是申请百度翻译的api.申请的时候看到需要填写公司。于是就没有申请了。
目前是用有道翻译的demo接口实现翻译的。
下面是用有道翻译的代码。
def my_translate(in_str):
import requests
import json
url = "https://aidemo.youdao.com/trans"
data = {
"q": in_str,
"from": "ja",
"to": "zh-CHS"}
headers = {
"User-Agent":"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Mobile Safari/537.36",
"Referer": "https://ai.youdao.com/product-fanyi.s"
}
response = requests.post(url, data=data, headers=headers)
html_str = response.content.decode() # json字符串
dict_ret = json.loads(html_str)
ret = dict_ret["translation"]
print("翻译结果是:", ret)
print("\n")
return ret
4.完成代码:
# coding:utf-8
import pyperclip
import os
import time
from PIL import Image,ImageGrab
import subprocess
from aip import AipOcr
#-----------------------UI begin--------------------------------------------------
# Form implementation generated from reading ui file 'snip_translate.ui'
#
# Created by: PyQt5 UI code generator 5.10.1
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1309, 892)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton_jietu = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_jietu.setGeometry(QtCore.QRect(10, 10, 91, 41))
self.pushButton_jietu.setObjectName("pushButton_jietu")
self.pushButton_cptext = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_cptext.setGeometry(QtCore.QRect(10, 60, 91, 41))
self.pushButton_cptext.setObjectName("pushButton_cptext")
self.pushButton_cptext.clicked.connect(self.cptext)
self.pushButton_jietu.clicked.connect(self.jietu)
self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
self.textEdit.setGeometry(QtCore.QRect(690, 40, 611, 801))
self.textEdit.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.textEdit.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.textEdit.setLineWrapColumnOrWidth(0)
self.textEdit.setObjectName("textEdit")
self.textEdit_ocr = QtWidgets.QTextEdit(self.centralwidget)
self.textEdit_ocr.setGeometry(QtCore.QRect(120, 40, 541, 801))
self.textEdit_ocr.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.textEdit_ocr.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.textEdit_ocr.setObjectName("textEdit_ocr")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(320, 10, 121, 21))
font = QtGui.QFont()
font.setFamily("Aharoni")
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.label.setFont(font)
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(890, 10, 121, 21))
font = QtGui.QFont()
font.setFamily("黑体")
font.setPointSize(14)
font.setBold(False)
font.setWeight(50)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1309, 23))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton_jietu.setText(_translate("MainWindow", "截图"))
self.pushButton_cptext.setText(_translate("MainWindow", "复制文本"))
self.label.setText(_translate("MainWindow", "识别结果"))
self.label_2.setText(_translate("MainWindow", "译文"))
def cptext(self, MainWindow):
pass
def jietu(self,MainWindow):
os.system('rundll32 PrScrn.dll PrScrn')
def setTransText(self, str):
self.textEdit.setPlainText(str)
def setOcrText(self, str):
self.textEdit_ocr.setPlainText(str)
#-----------------UI end--------------------------------------------------------
#**********图片处理********************
def vcode2str(img_url):
""" 你的 APPID AK SK """
APP_ID = '123123123'
API_KEY = 'vr123123123KsXIUT'
SECRET_KEY = 'm6123123123123123123kQ'
client = AipOcr(APP_ID, API_KEY, SECRET_KEY)
# """ 读取图片 """
def get_file_content(filePath):
with open(filePath, 'rb') as fp:
return fp.read()
# image = get_file_content('YZM.jpg')
image = get_file_content(img_url)
""" 调用通用文字识别, 图片参数为本地图片 """
client.basicGeneral(image);
""" 如果有可选参数 """
options = {}
options["language_type"] = "JAP"
options["detect_direction"] = "false"
options["detect_language"] = "false"
options["probability"] = "false"
""" 带参数调用通用文字识别, 图片参数为本地图片 """
a=client.basicGeneral(image, options)
length = len(a['words_result'])
b = ""
for i in range(length):
b = b + a['words_result'][i]["words"]
print("图片文本: " + b)
with open("original.txt",'w+') as fp:
# fp.write(b)
#print("文字识别部分已保存到本地")
#print(b)
fp.close()
return b
# #**********调用微信dll截图********************
def capture():
import ctypes
try:
dll = ctypes.cdll.LoadLibrary('PrScrn.dll')
except Exception as e:
print("Dll load error: ")
print(e)
return
else:
try:
dll.PrScrn(0)
except:
print("Sth wrong in capture!")
return
def main():
im = ImageGrab.grabclipboard()
if 'image' in str(im):
#print(im)
pyperclip.copy('test')
assert isinstance(im, object)
im.save("ocr.png")
img_path = os.path.join(os.getcwd(), "ocr.png")
content = vcode2str(img_path)
ui.setOcrText(str(content))
#mytext=fanyi(content)
mytext=my_translate(content)
ui.setTransText(str(mytext))
os.remove(img_path)
time.sleep(2)
else:
pass
#print("请检查是否正确截图后重试!")
import win32con,win32gui
import win32clipboard as cb
class MyWindow(): #剪切板监听
def __init__(self):
#注册一个窗口类
wc = win32gui.WNDCLASS()
wc.lpszClassName = 'MyWindow'
wc.hbrBackground = win32con.COLOR_BTNFACE+1
wc.lpfnWndProc = self.wndProc
class_atom=win32gui.RegisterClass(wc)
#创建窗口
self.hwnd = win32gui.CreateWindow( class_atom, u'OCR',
win32con.WS_OVERLAPPEDWINDOW,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT, 0,0, 0, None)
# 显示窗口
# win32gui.ShowWindow(self.hwnd, win32con.SW_SHOWNORMAL)
#消息处理
def wndProc(self, hwnd, msg, wParam, lParam):
if msg == win32con.WM_DESTROY:
win32gui.PostQuitMessage(0)
if msg == win32con.WM_DRAWCLIPBOARD: #当剪切板更新的时候收到这个消息
main()
return win32gui.DefWindowProc(hwnd, msg, wParam, lParam)
def my_translate(in_str):
import requests
import json
url = "https://aidemo.youdao.com/trans"
data = {
"q": in_str,
"from": "ja",
"to": "zh-CHS"}
headers = {
"User-Agent":"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Mobile Safari/537.36",
"Referer": "https://ai.youdao.com/product-fanyi.s"
}
response = requests.post(url, data=data, headers=headers)
html_str = response.content.decode() # json字符串
dict_ret = json.loads(html_str)
ret = dict_ret["translation"]
print("翻译结果是:", ret)
print("\n")
return ret
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
mw = MyWindow()
cb.SetClipboardViewer(mw.hwnd) #注册为剪切板监听窗口
win32gui.PumpMessages()
sys.exit(app.exec_())
使用效果:
原图片:
图片文本: 水没した際の応急処置水抜き内部に侵入した水を抜いてください。2.水洗い…19ページ「海での使用後の基本的なメンテナンス順序」をご参照ください。3.乾燥…19ページ「海での使用後の基本的なメンテナンス順序」をこ参照ください。4.オイル注油…16~17ページ「注油についてのご注意」をご参照ください。オイルの付け過ぎはかえって回転を悪くする場合があります。※長く噴霧させると逆流します。決してグリススプレーは使用しないでください●お願い以上はあくまで応急処置です。不意に水没された場合は、できるだけ早く当社のメンテナンスを受けられるよう、最寄りの小売店にお預けくださいa※メンテナンス価格はおおよそ¥3,500プラス部品代になりますが、状態によって異なります。
翻译结果是: [‘请在水中进行应急处理拔出进入内部的水。2.水洗……请参照19页“在海使用后的基本维护顺序”。3.干燥……请参照19页“在海使用后的基本维护顺序”。4.加油!请参照16~17页“关于加油的注意”。如果你涂太多油,反而会造成旋转速度变差。※长时间喷雾的话逆流。绝对不要使用润滑剂●拜托以上的话只是应急处理。如果是突然被水淹没的话,为了能尽早接受本公司的维修,请寄放在最近的零售店。a *维护价格大约为3,500加的零部件价格,根据状态不同会有所不同。’]
感谢大神
https://github.com/1061700625/OCR
, 代码主体是参照这个的,微信dll在里面有下载。