Greasy Fork

Greasy Fork is available in English.

comic fire 漫画下载脚本

自动处理并下载comic fire漫画图片的脚本

当前为 2018-10-28 提交的版本,查看 最新版本

// ==UserScript==
// @name         comic fire 漫画下载脚本
// @namespace    summer-script
// @version      0.2
// @description  自动处理并下载comic fire漫画图片的脚本
// @author       summer
// @match        https://r.binb.jp/epm/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    var SUPPORT_VERSION = 'v016112';
    var BUTTON_ID = 'btn-getter-download';
    var DEBUG = true;

    function init() {
        _btnInit();
        tip('初始化中...');

        var domReady = document.getElementById('content');
        var cidInput = document.getElementById('binb_cid');
        if (!domReady || !cidInput || !window.SpeedBinb) {
            setTimeout(init, 1000);
            return;
        }
        tip('下载');
        if (!checkVersion()) {
            tip('脚本可能已失效, 点击尝试运行');
        }
        document.getElementById(BUTTON_ID).onclick = function() {
            tip('正在运行...');
            rebuild();
            this.disabled = 'disabled';
        }
    }

    function rebuild() {
        var sb = window.SpeedBinb.getInstance('content');
        var cid = document.getElementById('binb_cid').value;
        load(function(img, imgInfo, now, sum) {
            tip('正在运行...('+now+'/'+sum+')');
            var cv = draw(img, imgInfo);
            var filename = cid + '-' + now + '.png';
            download(cv, filename);
            if (now >= sum) {
                tip('运行完毕');
            }
        });
    }

    function log() {
        if (!DEBUG) {
            return;
        }
        console.log.apply(console, arguments);
    }

    /**
     * 输出提示信息
     * @param {string} text 提示文字
     */
    function tip(text) {
        var btn = document.getElementById(BUTTON_ID);
        if (!btn) {
            btn = _btnInit();
        }
        btn.innerText = text;
    }

    /**
     * 阅读器版本确认
     */
    function checkVersion() {
        return (window.ViewerVersion === SUPPORT_VERSION);
    }

    /**
     * 绘制正确图像
     * @param {object} img 能用于绘制的Image对象
     * @param {object} imageInfo SpeedBinb中储存的图像信息
     */
    function draw(img, imageInfo) {
        var coords = _calcCoords(imageInfo, img.width, img.height);
        var cv = document.createElement('canvas');
        cv.width = imageInfo.orgwidth;
        cv.height = imageInfo.orgheight;
        var ctx = cv.getContext('2d');

        for(var i in coords) {
            ctx.drawImage(
                img,
                coords[i].xsrc,
                coords[i].ysrc,
                coords[i].width,
                coords[i].height,
                coords[i].xdest,
                coords[i].ydest,
                coords[i].width,
                coords[i].height
            );
        }
        return cv;
    }

    /**
     * 开始加载乱序图片
     * @param {function} cb 每张图片加载完成的回调
     *                      回调参数: Image对象
     *                               图像信息
     *                               当前正加载第几张图片
     *                               需要加载的图片总数
     * @param {array} queue 要加载的图片(不需要手动传入
     */
    function load(cb, queue) {
        var sb = window.SpeedBinb.getInstance('content');
        if (!queue) {
            queue = [].concat(sb.content.page);
        }
        if (0 === queue.length) {
            return;
        }
        var page = queue.shift();
        var imgInfo = page.image;
        var sum = sb.total;
        var now = sum - queue.length;

        var img = new Image();
        img.onerror = function() {
            log('image['+now+'] load fail');
            log('image['+now+'] load retry');
            img.onload = undefined;
            queue.unshift(page);
            setTimeout(function() {
                load(cb, queue);
            }, 2000);
        };
        img.onload = function(){
            log('img['+now+'] load success');
            cb(img, imgInfo, now, sum);
            load(cb, queue);
        };
        img.src = _getImageUrl(imgInfo);
        log('img['+now+'] loading');
    }

    /**
     * 下载画布中的图片
     * @param {object} canvas canvas的dom对象
     * @param {string} filename 文件名
     */
    function download(canvas, filename) {
        canvas.toBlob(function(blob) {
            var url = URL.createObjectURL(blob);
            var a = document.createElement('a');
            a.download = filename;
            a.href = url;
            a.click();
        });
    }

    /**
     * 计算拼图坐标
     * @param {object} imgInfo 图像信息{anchors:[], id:""...}
     * @param {number} width   乱序图片的宽度
     * @param {number} height  乱序图片的高度
     */
    function _calcCoords(imgInfo, width, height) {
        var sb = window.SpeedBinb.getInstance('content');
        var util = sb.As.Bt.qe;
        var ret = util.getImageDescrambleCoords(imgInfo, width, height);
        return ret.transfers[0].coords;
    }

    /**
     * 获取乱序图片的下载路径
     * @param {object} imgInfo 图像信息
     */
    function _getImageUrl(imgInfo) {
        var path = imgInfo.src;
        var sb = window.SpeedBinb.getInstance('content');
        return sb.As.Bt.qe.getImageUrl(path);
    }

    /**
     * 按钮初始化
     */
    function _btnInit() {
        var btn = document.createElement('button');
        btn.id = BUTTON_ID;
        btn.style.position = 'fixed';
        btn.style.top = '6px';
        btn.style.right = '8px';
        btn.style.zIndex = '22';
        btn.style.padding = '8px';
        btn.style.background = '#fff';
        btn.style.border = '1px solid #aaa';
        btn.style.borderRadius = '4px';
        btn.style.minWidth = '112px';
        btn.style.position = 'fixed';
        btn.style.color = '#000';
        document.body.appendChild(btn);
        return btn;
    }

    init();
})();