Touhou.AI | 图片翻译器

(WIP) https://touhou.ai/imgtrans/ 的用户脚本版本,一键翻译 Pixiv 的图片

目前为 2021-12-26 提交的版本。查看 最新版本

// ==UserScript==
// @name         Touhou.AI | Manga Translator
// @name:zh-CN   Touhou.AI | 图片翻译器
// @namespace    https://github.com/VoileLabs/imgtrans-userscript
// @version      0.2.2
// @description  (WIP) Userscript for https://touhou.ai/imgtrans/, translate images on Pixiv.
// @description:zh-CN (WIP) https://touhou.ai/imgtrans/ 的用户脚本版本,一键翻译 Pixiv 的图片
// @author       QiroNT
// @license      MIT
// @supportURL   https://github.com/VoileLabs/imgtrans-userscript
// @include      http*://www.pixiv.net*
// @match        http://www.pixiv.net/
// @connect      i.pximg.net
// @connect      i-f.pximg.net
// @connect      i-cf.pximg.net
// @connect      touhou.ai
// @grant        GM.xmlHttpRequest
// @grant        GM_xmlhttpRequest
// @run-at       document-end
// ==/UserScript==

'use strict';

async function submitTranslate(blob, suffix) {
    const formData = new FormData();
    formData.append('file', blob, 'image.' + suffix);
    const result = await GM.xmlHttpRequest({
        method: 'POST',
        url: 'https://touhou.ai/imgtrans/submit',
        // @ts-expect-error FormData is supported
        data: formData,
    });
    const json = JSON.parse(result.responseText);
    const id = json.task_id;
    return id;
}
async function getTranslateStatus(id) {
    const result = await GM.xmlHttpRequest({
        method: 'GET',
        url: 'https://touhou.ai/imgtrans/task-state?taskid=' + id,
    });
    const data = JSON.parse(result.responseText);
    return {
        state: data.state,
        waiting: (data.waiting || 0),
    };
}
function getStatusText(status) {
    switch (status.state) {
        case 'pending':
            if (status.waiting > 0) {
                return `正在等待,你的队列位置${status.waiting}`;
            }
            else {
                return `正在处理`;
            }
        case 'detection':
            return '正在检测文本';
        case 'ocr':
            return '正在识别文本';
        case 'mask_generation':
            return '正在生成文本掩码';
        case 'inpainting':
            return '正在修补图片';
        case 'translating':
            return '正在翻译';
        case 'render':
            return '正在渲染';
        case 'error':
            return '翻译出错';
        case 'error-lang':
            return '不支持的语言';
        default:
            return '未知状态';
    }
}
async function pullTransStatusUntilFinish(id, cb) {
    for (;;) {
        const timer = new Promise((resolve) => setTimeout(resolve, 500));
        const status = await getTranslateStatus(id);
        if (status.state === 'finished') {
            return;
        }
        else if (status.state === 'error') {
            throw new Error('翻译出错');
        }
        else if (status.state === 'error-lang') {
            throw new Error('不支持的语言');
        }
        else {
            cb(status);
        }
        await timer;
    }
}

var pixiv = () => {
    const images = new Set();
    const instances = new Map();
    const translatedMap = new Map();
    const translateEnabledMap = new Map();
    function rescanImages() {
        const imageNodes = Array.from(document.querySelectorAll('img')).filter((node) => {
            var _a;
            return node.hasAttribute('srcset') ||
                node.hasAttribute('data-trans') ||
                ((_a = node.parentElement) === null || _a === void 0 ? void 0 : _a.classList.contains('sc-1pkrz0g-1'));
        });
        const removedImages = new Set(images);
        for (const node of imageNodes) {
            removedImages.delete(node);
            if (!images.has(node)) {
                // new image
                console.log('new', node);
                try {
                    instances.set(node, mountToNode(node));
                    images.add(node);
                }
                catch (e) {
                    // ignore
                }
            }
        }
        for (const node of removedImages) {
            // removed image
            console.log('remove', node);
            if (instances.has(node)) {
                const instance = instances.get(node);
                instance.stop();
                instances.delete(node);
                images.delete(node);
            }
        }
    }
    function mountToNode(imageNode) {
        // get current displayed image
        const src = imageNode.getAttribute('src');
        const srcset = imageNode.getAttribute('srcset');
        // get original image
        const parent = imageNode.parentElement;
        if (!parent)
            throw new Error('no parent');
        const originalSrc = parent.getAttribute('href') || src;
        const originalSrcSuffix = originalSrc.split('.').pop();
        // console.log(src, originalSrc)
        let originalImage;
        let translatedImage = translatedMap.get(originalSrc);
        let translateMounted = false;
        let buttonDisabled = false;
        async function getTranslatedImage() {
            if (translatedImage)
                return translatedImage;
            buttonDisabled = true;
            const text = button.innerText;
            button.innerText = '正在拉取原图';
            if (!originalImage) {
                // fetch original image
                const result = await GM.xmlHttpRequest({
                    method: 'GET',
                    responseType: 'blob',
                    url: originalSrc,
                    headers: { referer: 'https://www.pixiv.net/' },
                    overrideMimeType: 'text/plain; charset=x-user-defined',
                }).catch((e) => {
                    button.innerText = '拉取原图出错';
                    throw e;
                });
                originalImage = result.response;
            }
            button.innerText = '正在提交翻译';
            const id = await submitTranslate(originalImage, originalSrcSuffix).catch((e) => {
                button.innerText = '提交翻译出错';
                throw e;
            });
            button.innerText = '正在等待';
            await pullTransStatusUntilFinish(id, (status) => {
                const text = getStatusText(status);
                button.innerText = text;
            }).catch((e) => {
                button.innerText = String(e);
                throw e;
            });
            button.innerText = '正在下载图片';
            const image = await GM.xmlHttpRequest({
                method: 'GET',
                responseType: 'blob',
                url: 'https://touhou.ai/imgtrans/result/' + id + '/final.jpg',
            }).catch((e) => {
                button.innerText = '下载图片出错';
                throw e;
            });
            const imageUri = URL.createObjectURL(image.response);
            translatedImage = imageUri;
            translatedMap.set(originalSrc, translatedImage);
            button.innerText = text;
            buttonDisabled = false;
            return imageUri;
        }
        async function enable() {
            translateMounted = true;
            try {
                const translated = await getTranslatedImage();
                imageNode.setAttribute('data-trans', src);
                imageNode.setAttribute('src', translated);
                imageNode.removeAttribute('srcset');
                button.innerText = '还原';
            }
            catch (e) {
                buttonDisabled = false;
                translateMounted = false;
                throw e;
            }
        }
        function disable() {
            translateMounted = false;
            imageNode.setAttribute('src', src);
            if (srcset)
                imageNode.setAttribute('srcset', srcset);
            imageNode.removeAttribute('data-trans');
            button.innerText = '翻译';
        }
        // called on click
        function toggle() {
            if (buttonDisabled)
                return;
            if (!translateMounted) {
                translateEnabledMap.set(originalSrc, true);
                enable();
            }
            else {
                translateEnabledMap.delete(originalSrc);
                disable();
            }
        }
        // create a translate botton
        parent.style.position = 'relative';
        const container = document.createElement('div');
        container.style.position = 'absolute';
        container.style.zIndex = '1';
        container.style.bottom = '10px';
        container.style.right = '10px';
        const button = document.createElement('button');
        button.setAttribute('type', 'button');
        button.innerText = '翻译';
        button.style.fontSize = '1rem';
        button.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();
            toggle();
        });
        container.appendChild(button);
        parent.appendChild(container);
        // enable if enabled
        if (translateEnabledMap.get(originalSrc))
            enable();
        return {
            imageNode,
            stop: () => {
                parent.removeChild(container);
                if (translateMounted)
                    disable();
            },
            async enable() {
                translateEnabledMap.set(originalSrc, true);
                return await enable();
            },
            disable() {
                translateEnabledMap.delete(originalSrc);
                return disable();
            },
            isEnabled() {
                return translateMounted;
            },
        };
    }
    // translate all
    let removeTransAll;
    function refreshTransAll() {
        if (document.querySelector('.sc-emr523-2'))
            return;
        const bookmark = document.querySelector('.gtm-main-bookmark');
        if (bookmark) {
            const container = bookmark.parentElement.parentElement;
            if (container.querySelector('[data-transall]'))
                return;
            const el = document.createElement('div');
            el.innerText = '翻译全部';
            el.setAttribute('data-transall', 'true');
            el.style.display = 'inline-block';
            el.style.marginRight = '13px';
            el.style.padding = '0';
            el.style.color = 'inherit';
            el.style.height = '32px';
            el.style.lineHeight = '32px';
            el.style.cursor = 'pointer';
            el.style.fontWeight = '700';
            const transall = (e) => {
                e.preventDefault();
                e.stopPropagation();
                let finished = 0;
                const total = instances.size;
                el.innerText = `翻译中(0/${total})`;
                let erred = false;
                const inc = () => {
                    finished++;
                    if (finished === total) {
                        if (erred)
                            el.innerText = '翻译完成';
                        else
                            el.innerText = '翻译完成(有失败)';
                        el.removeEventListener('click', transall);
                    }
                    else {
                        el.innerText = `翻译中(${finished}/${total})`;
                    }
                };
                const err = () => {
                    erred = true;
                    inc();
                };
                for (const instance of instances.values()) {
                    if (instance.isEnabled())
                        inc();
                    else
                        instance.enable().then(inc).catch(err);
                }
            };
            el.addEventListener('click', transall);
            container.appendChild(el);
            removeTransAll = () => {
                container.removeChild(el);
            };
        }
    }
    const imageObserver = new MutationObserver((mutations) => {
        rescanImages();
        refreshTransAll();
    });
    imageObserver.observe(document.body, { childList: true, subtree: true });
    // unmount
    return () => {
        instances.forEach((instance) => instance.stop());
        removeTransAll === null || removeTransAll === void 0 ? void 0 : removeTransAll();
    };
};

let currentURL;
let stopTranslator;
const installObserver = new MutationObserver(() => {
    if (currentURL !== location.href) {
        currentURL = location.href;
        // there is a navigation in the page
        /* unmount previous translator */
        if (stopTranslator)
            stopTranslator();
        /* mount new translator */
        // check if the page is a image page
        const url = new URL(location.href);
        // https://www.pixiv.net/(en/)artworks/<id>
        if (url.hostname.endsWith('pixiv.net') && url.pathname.match(/\/artworks\//)) {
            stopTranslator = pixiv();
        }
    }
});
installObserver.observe(document.body, { childList: true, subtree: true });
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1ndHJhbnMtdXNlcnNjcmlwdC51c2VyLmpzIiwic291cmNlcyI6WyIuLi9zcmMvY29yZS50cyIsIi4uL3NyYy9waXhpdi9pbmRleC50cyIsIi4uL3NyYy9tYWluLnRzIl0sInNvdXJjZXNDb250ZW50IjpbbnVsbCxudWxsLG51bGxdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFPLGVBQWUsZUFBZSxDQUFDLElBQVUsRUFBRSxNQUFjO0lBQzlELE1BQU0sUUFBUSxHQUFHLElBQUksUUFBUSxFQUFFLENBQUE7SUFDL0IsUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLFFBQVEsR0FBRyxNQUFNLENBQUMsQ0FBQTtJQUVoRCxNQUFNLE1BQU0sR0FBRyxNQUFNLEVBQUUsQ0FBQyxjQUFjLENBQUM7UUFDckMsTUFBTSxFQUFFLE1BQU07UUFDZCxHQUFHLEVBQUUsbUNBQW1DOztRQUV4QyxJQUFJLEVBQUUsUUFBUTtLQUNmLENBQUMsQ0FBQTtJQUVGLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFBO0lBQzVDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFpQixDQUFBO0lBQ2pDLE9BQU8sRUFBRSxDQUFBO0FBQ1gsQ0FBQztBQU9NLGVBQWUsa0JBQWtCLENBQUMsRUFBVTtJQUNqRCxNQUFNLE1BQU0sR0FBRyxNQUFNLEVBQUUsQ0FBQyxjQUFjLENBQUM7UUFDckMsTUFBTSxFQUFFLEtBQUs7UUFDYixHQUFHLEVBQUUsK0NBQStDLEdBQUcsRUFBRTtLQUMxRCxDQUFDLENBQUE7SUFDRixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQTtJQUM1QyxPQUFPO1FBQ0wsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFlO1FBQzNCLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMs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

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址