梦汐 发表于 2023-7-12 10:26

【JS】图片翻译

本帖最后由 梦汐 于 2023-7-12 10:32 编辑

大概就是把漫画图片机翻成中文,机翻结果挺一般的吧,写到一半就弃了
想看图片结果的可以改一下:document.querySelector("#image-container > a > img").src = canvas.toDataURL('image/png')
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, consult.google)
    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.innerHTML).split('\n')
            for (let i = 0; i < res.length; i++) {
                res = $.trim(res)
            }
            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(, 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)
                  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(, response.responseText])
                            }
                        }
                  )
                })
            }
      )
    }
    EmbedText(data, reverse) {
      return new Promise(
            async complete => {
                let image = data
                let json = conversion(data, 10, reverse)
                for (let index in json) {
                  let tl = (await translation(json.text)).text
                  console.log(json.text,tl);
                  json.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
                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;
                        // 计算当前行的宽度
                        var testWidth = context.measureText(testLine).width;
                        // 如果当前行的宽度超过了最大宽度
                        if (testWidth > maxWidth) {
                            // 在当前位置绘制当前行
                            context.fillText(line, x, y);
                            // 将当前字符作为下一行的开始
                            line = chars;
                            // 将 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
                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] - item.location]) < threshold) {
                              if (Math.abs(self.location] - item.location]) < (self.location] * ++quantity) * 1.5) {
                                    association.push(item)
                                    item.cancel = true
                                    return true
                              }
                              //console.log("坐标疑惑?", item);
                            }
                        }
                  })
                  for (let key in association) {
                        let item = association
                        if (item.location.top < top) { top = item.location.top }
                        if (item.location.left < left) { left = item.location.left }

                        if (sequence == "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] :
                  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));

Raohz520 发表于 2023-7-12 10:31

我好像知道是干嘛的了 {:1_918:}

yesiqi 发表于 2023-7-12 10:55

不行啊不行啊

sxlcsh 发表于 2023-7-12 13:30

本帖最后由 sxlcsh 于 2023-7-12 13:31 编辑

学习一下 汲取知识

Melody139 发表于 2023-7-12 14:03

这个好啊 嘿

redfieldw 发表于 2023-7-12 18:27

弃了是为啥,不是挺好的吗

Ballp 发表于 2023-7-18 20:45

这工作量,弃了多可惜啊

akts 发表于 2023-11-1 19:22

继续呗,别弃了哟
页: [1]
查看完整版本: 【JS】图片翻译