吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1882|回复: 7
收起左侧

[Java 转载] 【JS】图片翻译

[复制链接]
梦汐 发表于 2023-7-12 10:26
本帖最后由 梦汐 于 2023-7-12 10:32 编辑

大概就是把漫画图片机翻成中文,机翻结果挺一般的吧,写到一半就弃了
想看图片结果的可以改一下:document.querySelector("#image-container > a > img").src = canvas.toDataURL('image/png')
[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));

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Raohz520 发表于 2023-7-12 10:31
我好像知道是干嘛的了
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
继续呗,别弃了哟
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 19:56

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表