[JavaScript] 纯文本查看 复制代码
async function translation(text, sl = "auto", tl = "zh") {//原文,原文语言,目标语言
var consult = {
google: {
"auto": "auto",
"zh": "zh-CN",
"jp": "ja",
"en": "en"
}
}
var value = await Google(text, consult.google[sl], consult.google[tl])
return value
//----------------------------
async function Google(text, sl, tl) {
var result = await new Promise(
function (end, error) {
//console.log('GET', 'https://translate.google.com/m?hl=zh-CN&sl=' + sl + '&tl=' + tl + '&ie=UTF-8&prev=_m&q=' + encodeURIComponent(text));
GM_xmlhttpRequest({
method: 'GET',
url: 'https://translate.google.com/m?hl=zh-CN&sl=' + sl + '&tl=' + tl + '&ie=UTF-8&prev=_m&q=' + encodeURIComponent(text),
onload: end,
onerror: error
})
}
).catch(
function (error) {
return error
}
)
if (result.status == 200) {
var dom = stringToDocument(result.responseText);
var trl = $(dom).find('.result-container');
var res = htmlDecode(trl[0].innerHTML).split('\n')
for (let i = 0; i < res.length; i++) {
res[i] = $.trim(res[i])
}
res = res.join('\n')
return { text: res, status: 200, original: { text: text, result: result } }
}
return result
}
function stringToDocument(txt) {
try //Internet Explorer
{
xmlDoc = new ActiveXObject("Microsoft.HTMLDOM");
xmlDoc.async = "false";
xmlDoc.loadXML(txt);
return (xmlDoc);
}
catch (e) {
try //Firefox, Mozilla, Opera, etc.
{
parser = new DOMParser();
xmlDoc = parser.parseFromString(txt, "text/html");
return (xmlDoc);
}
catch (e) { alert(e.message) }
}
return (null);
}
function htmlDecode(text) {
var temp = document.createElement("div");
temp.innerHTML = text;
var output = temp.innerText || temp.textContent;
temp = null;
return output;
}
}
class TranslPicture {
constructor(client_id, client_secret) {
this.client_id = client_id
this.client_secret = client_secret
}
Init() {
return new Promise(
complete => {
let self = this
GM_xmlhttpRequest(
{
"method": "POST",
"url": "https://aip.baidubce.com/oauth/2.0/token",
"data": `grant_type=client_credentials&client_id=${this.client_id}&client_secret=${this.client_secret}`,
"responseType": "json",
onload: function (reply) {
self.status = true
self.token = reply.response.access_token
complete(self.token)
}
}
)
}
)
}
TranslImage(url) {
return new Promise(
complete => {
function GetBase64(url) {
return new Promise(async response => {
var canvas = document.createElement('canvas')
var ctx = canvas.getContext('2d');
var image = new Image
image.setAttribute("crossOrigin", 'Anonymous')
image.src = await getImage(url)
image.onload = function () {
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0, image.width, image.height);
var dataURL = canvas.toDataURL('image/png');
return response([dataURL.split(",")[1], image])
}
function getImage() {
return new Promise(
complete => {
GM_xmlhttpRequest({
method: 'GET',
url: url,
responseType: 'blob',
onload: function (response) {
var reader = new FileReader();
reader.onloadend = function () {
complete(reader.result);
}
reader.readAsDataURL(response.response);
}
})
}
)
}
})
}
let self = this
GetBase64(url).then(function (param) {
let toBase64 = encodeURIComponent(param[0])
GM_xmlhttpRequest(
{
"method": "POST",
"url": "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate?access_token=" + self.token,
"data": `image=${toBase64}&language_type=auto_detect`,
"responseType": "json",
onload: function (response) {//responseText
complete([param[1], response.responseText])
}
}
)
})
}
)
}
EmbedText(data, reverse) {
return new Promise(
async complete => {
let image = data[0]
let json = conversion(data[1], 10, reverse)
for (let index in json) {
let tl = (await translation(json[index].text)).text
console.log(json[index].text,tl);
json[index].text = tl
}
let canvas = document.createElement("canvas");
ImageTransl(canvas, image, json)
//console.log(canvas.toDataURL('image/png'));
document.querySelector("#image-container > a > img").src = canvas.toDataURL('image/png')
complete(canvas.toDataURL('image/png'))
}
)
function ImageTransl(canvas, iamge, json, fontSize = 20) {
var context = canvas.getContext("2d");
var img = iamge
canvas.width = img.width
canvas.height = img.height
context.drawImage(img, 0, 0, img.width, img.height)
for (let index in json) {
let self = json[index]
TextFrame(context, self.text, self.location.left, self.location.top, self.location.width, self.location.height)
}
function TextFrame(context, text, rectX, rectY, rectWidth, rectHeight) {
// 绘制一个蓝色的矩形框
context.fillStyle = "white";
context.fillRect(rectX - 3, rectY - 3, rectWidth + 6, rectHeight + 6);
context.strokeStyle = "blue";
//context.strokeRect(rectX - 4, rectY - 4, rectWidth + 8, rectHeight + 8);//画矩形
// 定义要绘制的文本内容和字体大小
context.font = fontSize + "px Arial";
context.fillStyle = "black";//黑色画笔
textSorting(text, rectX, rectY + fontSize, rectWidth, fontSize);
function textSorting(text, x, y, maxWidth, lineHeight) {
// 将文本分割成单个字符
var chars = text.split("");
// 定义一个空字符串来存储每一行的文本
var line = "";
// 遍历每个字符
for (var i = 0; i < chars.length; i++) {
// 将当前字符添加到当前行
var testLine = line + chars[i];
// 计算当前行的宽度
var testWidth = context.measureText(testLine).width;
// 如果当前行的宽度超过了最大宽度
if (testWidth > maxWidth) {
// 在当前位置绘制当前行
context.fillText(line, x, y);
// 将当前字符作为下一行的开始
line = chars[i];
// 将 y 坐标增加一个行高
y += lineHeight;
// 如果 y 坐标超过了矩形的底部
if (y > rectY + rectHeight) {
// 停止绘制
break;
}
} else {
// 否则,将测试行作为当前行
line = testLine;
}
}
// 绘制最后一行(如果有)
if (y <= rectY + rectHeight) {
context.fillText(line, x, y);
}
}
}
}
function conversion(OcrResponse, threshold = 10, reverse = false) {//百度 API
if (typeof OcrResponse == "string") {
OcrResponse = JSON.parse(OcrResponse)
}
let dict = OcrResponse.words_result
let list = []
for (let i in dict) {
console.log(i);
let self = dict[i]
if (!("cancel" in self)) {
self.index = i
//-----------------------------
let sequence = self.location.width > self.location.height ? ["left", "top", "width", "height"] : ["top", "left", "height", "width"]
let association = []
let top = self.location.top
, left = self.location.left
, width = self.location.width
, height = self.location.height
let quantity = 1
let v = dict.filter(item => {
if (item.index != self.index) {
if (item.words.length <= 1) {
//console.log("跳过短文本", item.words);
item.cancel = true
} else if (Math.abs(self.location[sequence[0]] - item.location[sequence[0]]) < threshold) {
if (Math.abs(self.location[sequence[1]] - item.location[sequence[1]]) < (self.location[sequence[3]] * ++quantity) * 1.5) {
association.push(item)
item.cancel = true
return true
}
//console.log("坐标疑惑?", item);
}
}
})
for (let key in association) {
let item = association[key]
if (item.location.top < top) { top = item.location.top }
if (item.location.left < left) { left = item.location.left }
if (sequence[0] == "top") {//竖版
if (item.location.left + item.location.left > width) { width = (item.location.left + item.location.width) - left }
if (item.location.height > height) { height = item.location.height }
} else {//横版
if (item.location.left + item.location.left > width) { width = (item.location.left + item.location.width) - left }
if (item.location.top + item.location.height > height) { height = (item.location.top + item.location.height) - top }
}
}
var filter = self.words.length < 1 ? [...v] : [self, ...v]
if (filter.length > 0) {
if (reverse) {
var text = filter.map(
item => item = item.words
).reverse().join(' ')
} else {
var text = filter.map(
item => item = item.words
).join(' ')
}
list.push({
location: {
top: top,
left: left,
width: width,
height: height
},
text: text
})
}
}
}
return list
}
}
}
let TP = new TranslPicture("你的账号", "你的密匙")//用的百度的文字识别//翻译用的免费谷歌翻译
await TP.Init()
let data = await TP.TranslImage('图片url')//很久以前写的,忘了能不能跨域
console.log(await TP.EmbedText(data));