Image Downloader

You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)

נכון ליום 22-01-2022. ראה הגרסה האחרונה.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Image Downloader
// @name:zh-CN   图片下载器
// @name:zh-TW   图片下载器
// @name:ja   画像ダウンローダー
// @name:ko   이미지 다운로더
// @name:de   Image Downloader
// @name:es   Image Downloader
// @name:eo   Image Downloader
// @name:fr   Image Downloader
// @name:it   Image Downloader
// @name:ru   Image Downloader
// @name:vi   Image Downloader
// @name:pt-BR   Image Downloader
// @name:id   Image Downloader
// @name:ar   Image Downloader
// @name:bg   Image Downloader
// @name:cs   Image Downloader
// @name:tr   Image Downloader
// @name:el   Image Downloader
// @name:hu   Image Downloader
// @name:th   Image Downloader
// @namespace       http://tampermonkey.net/
// @description You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:zh-CN    可以在绝大多数网站提取并批量下载图片。尤其是类似于千库网、包图网或者有妖气、腾讯漫画、b站漫画这种,不能右键保存图片或者保存的图片文件格式无法识别,均可以用脚本提取,然后用脚本提供的下载按钮,就可以下载到正确格式的图片文件。点击右键-tampermonkey-图片下载器-打开脚本(或快捷键alt+w),按这个顺序使用。(目前只适合chrome+tampermonkey,其他组合多少有问题)
// @description:zh-TW   可以在绝大多数网站提取并批量下载图片。尤其是类似于千库网、包图网或者有妖气、腾讯漫画、b站漫画这种,不能右键保存图片或者保存的图片文件格式无法识别,均可以用脚本提取,然后用脚本提供的下载按钮,就可以下载到正确格式的图片文件。点击右键-tampermonkey-图片下载器-打开脚本(或快捷键alt+w),按这个顺序使用。(目前只适合chrome+tampermonkey,其他组合多少有问题)
// @description:ja  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:ko  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:de  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:es  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:eo  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:fr  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:it  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:ru  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:vi  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:pt-BR  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:id  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:ar  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:bg  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:cs  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:tr  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:el  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:hu  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @description:th  You can extract and download pictures in batches on most websites(e.g.instagram).Right Click-tampermonkey-Image Downloader(or alt+w),use in this order.(currently only suitable for tampermonkey and chrome,others have not tried it)
// @version         1.95
// @author          桃源隐叟
// @include         *
// @connect *
// @grant           GM_openInTab
// @grant        GM_registerMenuCommand
// @grant           GM_setValue
// @grant           GM_getValue
// @grant        GM_xmlhttpRequest
// @grant GM_download
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/hotkeys.min.js
// @require      https://cdn.bootcss.com/jszip/3.7.1/jszip.min.js
// @require      https://cdn.bootcss.com/FileSaver.js/1.3.8/FileSaver.min.js
// @run-at         document-end
// @match        *
// @match        https://www.bilibili.com/
// @match        https://588ku.com/
// @homepageURL       https://github.com/taoyuancun123/modifyText/blob/master/modifyText.js
// @supportURL        https://greatest.deepsurf.us/zh-CN/scripts/419894/feedback
// @license GPLv3
// ==/UserScript==
 
(function () {
    'use strict';
 
    var lang = navigator.appName == "Netscape" ? navigator.language : navigator.userLanguage;
    var langSet;
    var localization = {
        zh: {
            selectAll: "全选",
            downloadBtn: "下载",
            downloadMenuText: "打开脚本(Alt+w)",
            zipDownloadBtn: "zip下载",
            selectAlert:"请至少选中一张图片。",
            fetchTip:"准备抓取canvas图片",
            fetchCount1:`抓取canvas图片第`,
            fetchCount2:'张',
            fetchDoneTip1:"已选(0/",
            fetchDoneTip1Type2:"已选(",
            fetchDoneTip2:")张图片",
        },
        en: {
            selectAll: "selectAll",
            downloadBtn: "download",
            downloadMenuText: "Open(Alt+w)",
            zipDownloadBtn: "zip Download",
            selectAlert:"Please at last select one image.",
            fetchTip:"Ready to fetch canvas image.",
            fetchCount1:`Fetch the`,
            fetchCount2:' canvas image.',
            fetchDoneTip1:"(0/",
            fetchDoneTip1Type2:"(",
            fetchDoneTip2:") Images selected",
        }
    }
 
    if (lang.toLowerCase().includes("zh-")) {
        langSet = localization.zh;
    } else {
        langSet = localization.en;
    }

    const autoBigImage={
        bigImageArray:[],
        defaultRules:[            
            {originReg:/(?<=(.+sinaimg\.(?:cn|com)\/))([\w\.]+)(?=(\/.+))/i,replacement:"large"},
            {originReg:/(?<=(.+alicdn\.(?:cn|com)\/.+\.(jpg|jpeg|gif|png|bmp|webp)))_.+/i,replacement:""},
            {originReg:/(.+alicdn\.(?:cn|com)\/.+)(\.\d+x\d+)(\.(jpg|jpeg|gif|png|bmp|webp)).*/i,replacement:(match,p1,p2,p3)=>p1+p3},
            {originReg:/(?<=(.+360buyimg\.(?:cn|com)\/))(\w+\/)(?=(.+\.(jpg|jpeg|gif|png|bmp|webp)))/i,replacement:"n0/"},
            {originReg:/(?<=(.+hdslb\.(?:cn|com)\/.+\.(jpg|jpeg|gif|png|bmp|webp)))@.+/i,replacement:""},
        ],
        replace(originImgUrls){            
            let that=this;   
            that.bigImageArray=[];
            let tempArray=Array.from(new Set(originImgUrls));
            //console.log(that.bigImageArray);
            
            tempArray.forEach(replaceByReg);
            function replaceByReg(urlStr,urlIndex){
                if(urlStr.includes("data:image/"))return;
                that.defaultRules.forEach((rule,ruleIndex)=>{
                    let bigImage=urlStr.replace(rule.originReg,rule.replacement); 
                    if(bigImage!==urlStr){                        
                        that.bigImageArray.push(urlStr);
                        that.bigImageArray.push(bigImage);
                    }else{
                        that.bigImageArray.push(urlStr);
                    }                    
                })
            }
        },
        getBigImageArray(originImgUrls){            
            this.replace(originImgUrls);
            let uniqueArray=Array.from(new Set(this.bigImageArray));            
            return uniqueArray;
        },
        showRules(){

        }
    }
 
    GM_registerMenuCommand(langSet.downloadMenuText, wrapper);
    hotkeys('alt+w', wrapper);
 
    function wrapper() {  
        try {
            document.querySelector(".tyc-image-container").remove();
        } catch { 
        }
        var imgUrls = [];
        var bodyStr = document.body.innerHTML;
        var imgSelected = [];
        var zipImgSelected = [];
        var imgWaitDownload = [];
        var zipImgWaitDownload = [];
        var widthFilter = { min: 0, max: 3000 };
        var heightFilter = { min: 0, max: 3000 };
        var filteredImgUrls = [];
        var zipFilteredImgUrls = [];
        try{
            var zipFolder = new JSZip();
            var zipSubFoler = zipFolder.folder('pics');
        }
        catch{
            
        }        
 
        var fetchTip='';
 
        try {
            let imgEles = document.getElementsByTagName("img");
            let canvasEles=document.getElementsByTagName("canvas");
 
            for (let i = 0; i < imgEles.length; i++) {
                ////console.log(imgEles[i].src);
                if (!imgUrls.includes(imgEles[i].src)) {
                    imgUrls.push(imgEles[i].src);
                } else if (!imgUrls.includes(imgEles[i].srcset)) {
                    imgUrls.push(imgEles[i].srcset);
                }
            }
 
            let imgRegs = bodyStr.match(/(?<=background-image:\s*url\()(\S+)(?=\))/g);
 
            for (let i = 0; i < imgRegs.length; i++) {
                ////console.log(imgRegs[i]);
                if (!imgUrls.includes(imgRegs[i].replace(/&quot;/g, ""))) {
                    imgUrls.push(imgRegs[i].replace(/&quot;/g, ""));
                }
            }
 
            if (window.location.href.includes("hathitrust.org")) {
                let imgs = document.querySelectorAll(".image img");
                if (imgs.length > 0) {
                    let canvas = document.createElement("canvas");
                    imgUrls = [];
                    for (let pi = 0; pi < imgs.length; pi++) {
                        canvas.width = imgs[pi].width;
                        canvas.height = imgs[pi].height;     
                        canvas.getContext("2d").drawImage(imgs[pi], 0, 0);     
                        imgUrls.push(canvas.toDataURL("image/png"));
                    }
     
                    document.querySelector(".select-all").style = "position:relative;width:15px;height:15px;"
                } else {
     
                }
            }
 
            if(window.location.href.toString().includes("manga.bilibili.com/")){
                let iframeCanvas=`<iframe style="display:none;" id="tyc-insert-iframe"></iframe>`;
                if(document.getElementById("tyc-insert-iframe")==null){
                    document.body.insertAdjacentHTML("afterbegin",iframeCanvas);
                    document.getElementById("tyc-insert-iframe").contentDocument.body.insertAdjacentHTML("afterbegin",`<canvas id="tyc-insert-canvas"></canvas>`);
                    document.body.getElementsByTagName('canvas')[0].__proto__.toBlob=document.getElementById("tyc-insert-iframe").contentDocument.getElementById("tyc-insert-canvas").__proto__.toBlob;
                }
 
            }
 
            let oldLength=imgUrls.length;
            if(canvasEles.length>0){ 
                fetchTip=langSet.fetchTip;
                var completeFlag=0;                
                for(let j=0;j<canvasEles.length;j++){                    
                    canvasEles[j].toBlob(blobCallback);    
                    function blobCallback(blob){
                        let oFileReader = new FileReader();
                        oFileReader.onloadend = function (e) {
                            let base64 = e.target.result;                                 
                            if (base64.includes("data:image")) {
                                if (!imgUrls.includes(base64)) {                                
                                    //imgUrls.push(base64);                                
                                    imgUrls[oldLength+j]=base64;
                                }
                                completeFlag++;                                                         
                                document.querySelector(".num-tip").innerText=`${langSet.fetchCount1} ${completeFlag}/${canvasEles.length} ${langSet.fetchCount2}`;                                      
                                if(completeFlag===canvasEles.length){
                                    clean();
                                    init();
                                }
                            }
                        };
                        
                        oFileReader.readAsDataURL(blob);
                    }
                }
            }else{
                fetchTip=`${langSet.fetchDoneTip1}${imgUrls.length}${langSet.fetchDoneTip2}`;
            }           
 
        } catch {
            //alert("error");
        }
 
        let imgContainer = `
        <style>
            .tyc-image-container{
                position:fixed;
                top:0px;
                left:10%;
                width:80vw;
                z-index:2147483645;
                background-color: #dedede;
                border: 1px solid #aaa;
                overflow:scroll;height:100%;
            }
    
            .tyc-image-container button{
                border:1px solid #aaa;
                border-radius:5px;
                height:32px;line-height:32px;
                margin:0px;padding:0 5px;
            }
    
            .tyc-image-container button:hover{
                background-color: #f50;
                color: #fff;
            }
    
            .control-section{
                width:80vw;
                z-index:2147483646;
                position:fixed;
                top:0px;
                left:10%;
                display: flex;
                flex-direction: column;
                justify-content: center;                
                line-height:40px;
                background:#eee;border:1px solid #aaa;border-radius:2px;                
            }
    
            .control-section-sub{
                display: flex;
                margin-bottom: 5px;               
            }
    
            .tyc-normal-section{
                display: flex;
                align-items: center;
                flex-direction: row;
                justify-content: flex-start;    
                flex-wrap: nowrap;            
                align-content: normal;
    
            }
            .btn-download{
                border:1px solid #aaa;border-radius:5px;
                height:32px;line-height:32px;
                margin:0px;padding:0 5px;
            }
            .btn-zipDownload{
                border:1px solid #aaa;border-radius:5px;
                height:32px;line-height:32px;
                margin:0px;padding:0 5px;
            }
            .btn-close{
                font-size:20px;position:absolute;
                right:30px;top:4px;
                height:32px;line-height:32px;
                margin:0px;
                border-radius:10px;border:1px solid #aaa;
                width:30px;
            }
    
            .tyc-image-wrapper{
                margin-top:82px;display:flex;justify-content:center;
                align-items:center;flex-wrap:wrap;
            }
    
            .tyc-input-checkbox{
                background-color: initial;
                cursor: default;
                appearance: auto;
                box-sizing: border-box;
                margin: 3px 3px 3px 4px;
                padding: initial;
                border: initial;
            }
    
            .tyc-extend-set{
                padding: 10px;
                border-top: 1px solid rgba(100,100,100,0.1);
            }
    
            .tyc-extend-set{
                display: none;
                align-items: stretch;
                flex-direction: column;
                justify-content: flex-start;
                flex-wrap: nowrap;
                padding: 5px;
                width: auto;
            }
    
            .tyc-extend-set-container{
                display: flex;
                align-items: flex-start;
                flex-direction: column;
                justify-content: flex-start;
                flex-wrap: nowrap;
                align-content: normal;
                border: 1px solid rgba(100,100,100,0.5);
                padding: 5px;
                margin-bottom: 5px;
            }
    
            .tyc-autobigimg-set{
                display: flex;
                align-items: flex-start;
                flex-direction: column;
                justify-content: flex-start;
                flex-wrap: nowrap;
                align-content: normal;
                border: 1px solid rgba(100,100,100,0.5);
                padding: 5px;
            }
    
            .tyc-set-domain{
                display: flex;
                align-items: flex-start;
                flex-direction: column;
                justify-content: flex-start;
                flex-wrap: nowrap;
                align-content: normal;
                margin: 5px;
                padding: 5px;
                border: 1px solid rgba(100,100,100,0.3);
                width: 95%;
            }
    
            .tyc-abi-title{
                display: flex;
                flex-direction: row;
                align-items: center;
                justify-content: space-between;
                width: 100%;
            }
    
            .tyc-abi-domain-title{
                display: flex;
                flex-direction: row;
                align-items: center;
                justify-content: space-between;
                width: 95%;
                border-bottom: 1px solid #ddd;
            }
            .tyc-set-replacerule{
                display: flex;
                flex-direction: row;
                justify-content: flex-start;
                align-items: center;
                margin-bottom: 3px;
                flex-wrap: wrap;
            }
    
            .tyc-set-replacerule *,.tyc-set-replacerule button{
                margin-left: 5px;
            }
        </style>
        <div class="tyc-image-container">
            <div class="control-section">
                <div class="control-section-sub tyc-normal-section">
                    <input class="select-all tyc-input-checkbox" type="checkbox" name="select-all" value="select-all">${langSet.selectAll}
                    <button class="btn-download" style="margin-left:5px;">${langSet.downloadBtn}</button> 
                    <button class="btn-zipDownload" style="margin-left:5px;">${langSet.zipDownloadBtn}</button> 
                    <span style="margin-left:10px;" class="num-tip">${langSet.fetchDoneTip1}${imgUrls.length}${langSet.fetchDoneTip2}</span>
                    <button cstyle="margin-left:10px;" class="btn-close" >X</button>
                </div>
    
            
                <div style="line-height:12px;" class="control-section-sub tyc-normal-section">
                    <div style="float:left;display:block;">
                    <input type="checkbox" class="width-check img-check tyc-input-checkbox" name="width-check" value="width-check">Width:
                    <input type="text" class="width-value-min" size="1" style="height:15px;width:50px;"
                        min="0" max="9999" value="0">-
                        <input type="text" class="width-value-max" size="1" style="height:15px;width:50px;"
                        min="0" max="9999" value="3000">
                    </div>
            
                    <div style="float:left;margin-left:30px;display:block;">
                        <input type="checkbox" class="height-check img-check tyc-input-checkbox" name="height-check" value="height-check">Height:
                        <input type="text" class="height-value-min" size="1" style="height:15px;width:50px;"
                            min="0" max="9999" value="0">-
                            <input type="text" class="height-value-max" size="1" style="height:15px;width:50px;"
                            min="0" max="9999" value="3000">
                    </div>
            
                    <div style="float:left;margin-left:30px;display:block;" class="tyc-cors">
                        <span class="tyc-tip" style="display: none;
                        position: absolute;
                        top: 5px;
                        left: 50px;
                        white-space: nowrap;
                        background: rgb(204, 204, 204);
                        border: 1px solid rgb(150, 150, 150);
                        border-radius: 3px;
                        padding: 5px;">勾选使用zip下载后,会请求跨域权限,否则zip下载基本下载不到图片。
                        </span>        
                        <input type="checkbox" class="cors-check img-check tyc-input-checkbox" name="cors-check" value="cors-check">
                        <span>使用zip下载</span>     
                    </div>
                    <div style="float:left;margin-left:30px;display:block;" class="tyc-extend-btn">
                        <span>更多设置 </span>
                        <span style="top: 3px;position: relative;">
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-double-down" viewBox="0 0 16 16">
                                <path fill-rule="evenodd" d="M1.646 6.646a.5.5 0 0 1 .708 0L8 12.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/>
                                <path fill-rule="evenodd" d="M1.646 2.646a.5.5 0 0 1 .708 0L8 8.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/>
                            </svg>
                        </span> 
                    </div>
                </div>
                <div class="tyc-extend-set control-section-sub">
                    <div class="tyc-autobigimg-set tyc-extend-set-container">
                        <div class="tyc-abi-title">  
                            <div>
                                <input type="checkbox" name="sites" class="tyc-show-in-menu">开启自动大图
                            </div> 
                            <div>
                                <button>新增规则</button>
                            </div>
                            
                        </div>
                        <div class="tyc-set-domain">
                            <div class="tyc-set-replacerule">                        
                                    <input type="checkbox" name="sites" class="tyc-show-in-menu">
                                    <input type="text" name="title" placeholder="输入待替换正则" class="tyc-search-title">
                                    <input type="text" name="urls" placeholder="输入替换它的字符串或者函数" class="tyc-search-url">
                                    <button class="tyc-delete">删除</button>                        
                            </div>
                            <div class="tyc-set-replacerule">                        
                                    <input type="checkbox" name="sites" class="tyc-show-in-menu">
                                    <input type="text" name="title" placeholder="输入将显示在菜单中的提示名" class="tyc-search-title">
                                    <input type="text" name="urls" placeholder="参考其他例子,输入除关键词外的网址部分" class="tyc-search-url">
                                    <button class="tyc-delete">删除</button>                        
                            </div>
                        </div>
                    </div> 
               
                </div>
            </div>
            <div class="tyc-image-wrapper" >
            </div>
        </div>`
 
        let showBigImage = `
        <div class="show-big-image" style="position:fixed;left:30%;top:30%;z-index:2147483647;">
        </div>
    `
 
        document.body.insertAdjacentHTML("afterbegin", imgContainer);
  
        document.body.onclick = (e) => {
            //console.log(e);
            if ((e.target.nodeName == "IMG" && e.target.className === "tyc-image-preview")) {
                let imgContainer = e.path.find(
 
                    (ele) => {
                        try {
                            //console.log(ele);
                            return ele.className.includes("tyc-img-item-container");
                        }
                        catch {
 
                        }
 
                    }
                )
                let path = imgContainer.getElementsByTagName("img")[0].src;
 
                try {
                    let container = document.querySelector(".show-big-image");
                    if (container.getElementsByTagName("img")[0].src === path) {
                        container.remove();
                        return;
                    } else {
                        container.remove();
                    }
                }
                catch {
 
                }
                document.body.insertAdjacentHTML("beforeend", showBigImage);
 
                let showItem = `<img src="${path}"/>`
 
                document.querySelector(".show-big-image").insertAdjacentHTML("beforeend", showItem);
 
                let tempImg = document.querySelector(".show-big-image img");
 
                let dWidth = (window.innerWidth - tempImg.width) / 2;
                let dHeight = (window.innerHeight - tempImg.height) / 2;
 
                document.querySelector(".show-big-image").style.left = dWidth + "px";
                document.querySelector(".show-big-image").style.top = dHeight + "px";
            } else if (e.target.parentElement.className === "show-big-image") {
                try {
                    document.querySelector(".show-big-image").remove();
                }
                catch
                {
 
                }
 
            } else if (e.target.classList[1] == "bi-download" || e.path.find(isDownload) != undefined) {
                let imgContainer = e.path.find(
 
                    (ele) => {
                        try {
                            //console.log(ele);
                            return ele.className.includes("tyc-img-item-container");
                        }
                        catch {
 
                        }
 
                    }
                )
                let path = imgContainer.getElementsByTagName("img")[0].src;
                let filename;
                if (path.indexOf("/") > 0)//如果包含有"/"号 从最后一个"/"号+1的位置开始截取字符串
                {
                    filename = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf("."));
                }
                else {
                    filename = path;
                }
                //console.log("download start" + path + " " + filename);
                GM_download(path, "pic");
            } else if (e.target.classList[1] == "bi-check" || e.path.find(isSelect) != undefined) {
                let checkSvg = e.path.find((ele) => ele.classList[1] === "bi-check");
                let currentImgIndex = parseInt(checkSvg.dataset.value);
 
                let container = e.path.find((ele) => ele.className === `tyc-img-item-container-${currentImgIndex}`);
  
                if (imgSelected.includes(currentImgIndex)) {
                    imgSelected.splice(imgSelected.indexOf(currentImgIndex), 1);
                    checkSvg.style.color = "black";
                    container.style.border = "1px solid #99d";
                } else {
                    imgSelected.push(currentImgIndex);
                    checkSvg.style.color = "white";
                    container.style.border = "1px solid white";
                }
 
                zipImgSelected=imgSelected;
 
                document.querySelector(".num-tip").innerText = `${langSet.fetchDoneTip1Type2}${imgSelected.length}/${imgUrls.length}${langSet.fetchDoneTip2}`;
                imgWaitDownload=transIndexToLink(filteredImgUrls,imgSelected);
                zipImgWaitDownload=transIndexToLink(zipFilteredImgUrls,zipImgSelected);
                zipImgWaitDownload=cutoffNotBase64Img(zipImgWaitDownload);
            }
        }
 
        document.querySelector(".btn-close").onclick = (e) => {
            document.querySelector(".tyc-image-container").remove();
        }
 
        document.querySelector(".btn-download").onclick = (e) => {
            if (imgWaitDownload.length >= 1) {
                //console.log(imgWaitDownload);
                imgWaitDownload.forEach(async (img, index) => {
                    //let filename = `pic-${index}.jpg`;
                    //filename=filename.replace(/\\/g, '/').replace(/\/{2,}/g, '/');
                    await GM_download(img, `pic-${index}`);
                });
            } else {
                alert(`${langSet.selectAlert}`);
            }
        }
 
        document.querySelector(".btn-zipDownload").onclick = (e) => {
            //console.log(zipImgWaitDownload);
            try {
                if (zipImgWaitDownload.length >= 1) {
                    //console.log(zipImgWaitDownload);
                    zipImgWaitDownload.forEach(async (img, index) => {
                        let fileExt = img.substring(img.indexOf("image/") + 6, img.indexOf(";"))
                        fileExt=fileExt.includes("svg")?"svg":fileExt;
                        let filename = `pic${index}.${fileExt}`;  
                        zipSubFoler.file(filename, img.split(",")[1], { base64: true });                        
                    });
     
                    zipFolder.generateAsync({ type: "blob" })
                        .then(function (content) {
                            // see FileSaver.js
                            saveAs(content, "pics.zip");
                            zipFolder.remove("pics");
                            zipSubFoler = zipFolder.folder('pics');
                        });
     
                } else {
                    alert(`${langSet.selectAlert}`);
                }
            } catch (error) {
                //console.log(error);
            }

 
        }
 
        document.querySelector(".tyc-cors").onmouseover=e=>{
            e.preventDefault();
            document.querySelector(".tyc-tip").style.display="block";
        }
 
        document.querySelector(".tyc-cors").onmouseout=e=>{
            e.preventDefault();
            document.querySelector(".tyc-tip").style.display="none";
        }
 
        document.body.onchange = (e) => {
            if (e.target.className.includes("width-check")) {
                GM_setValue('width-check', e.target.checked);
            }
            if (e.target.className.includes("height-check")) {
                GM_setValue('height-check', e.target.checked);
            }
 
            if (e.target.className.includes("cors-check")) {
                GM_setValue('cors-check', e.target.checked);
                if (document.querySelector(".cors-check").checked) {
                    fetchBase64ImgsThenPushToZipArray();
                }                
            }
 
            if (e.target.nodeName === "INPUT" && e.target.type === "text" && e.target.className.includes("value")) {
                GM_setValue(e.target.className, e.target.value);
            }
 
            (e.target.className.includes("width-check") || e.target.className.includes("height-check") ||
 
                (e.target.nodeName === "INPUT" && e.target.type === "text" && e.target.className.includes("value")))
                && (clean(), init());
 
        }
 
        document.querySelector(".select-all").onchange = (e) => {
            if (document.querySelector(".select-all").checked) {
                imgWaitDownload = filteredImgUrls;
                zipImgWaitDownload=cutoffNotBase64Img(zipFilteredImgUrls);
            } else {
                imgWaitDownload=transIndexToLink(filteredImgUrls,imgSelected);
                zipImgWaitDownload=transIndexToLink(zipFilteredImgUrls,zipImgSelected);
            }
 
            document.querySelector(".num-tip").innerText = `${langSet.fetchDoneTip1Type2}${imgWaitDownload.length}/${filteredImgUrls.length}${langSet.fetchDoneTip2}`;
        }

        document.querySelector(".tyc-extend-btn").onclick=e=>{
            if(document.querySelector(".tyc-extend-btn").classList.contains("extend-open")){
                document.querySelector(".tyc-extend-btn").classList.remove("extend-open");
                document.querySelector(".tyc-extend-set").style.display="none";
                document.querySelector(".tyc-extend-btn").style.color="black";
                document.querySelector(".tyc-extend-btn").innerHTML=`<span>更多设置 </span>
                <span style="top: 3px;position: relative;">
                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-double-down" viewBox="0 0 16 16">
                        <path fill-rule="evenodd" d="M1.646 6.646a.5.5 0 0 1 .708 0L8 12.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/>
                        <path fill-rule="evenodd" d="M1.646 2.646a.5.5 0 0 1 .708 0L8 8.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/>
                    </svg>
                </span> `
                ;
            }else{
                document.querySelector(".tyc-extend-btn").classList.add("extend-open");
                document.querySelector(".tyc-extend-set").style.display="flex";
                document.querySelector(".tyc-extend-btn").style.color="#f50";
                document.querySelector(".tyc-extend-btn").innerHTML=`<span>收起 </span>
                <span style="top: 3px;position: relative;">
                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-double-up" viewBox="0 0 16 16">
                    <path fill-rule="evenodd" d="M7.646 2.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 3.707 2.354 9.354a.5.5 0 1 1-.708-.708l6-6z"/>
                    <path fill-rule="evenodd" d="M7.646 6.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 7.707l-5.646 5.647a.5.5 0 0 1-.708-.708l6-6z"/>
                    </svg>
                </span> `

            }
        }


 
        init();
        function init() {            
            filteredImgUrls = imgUrls;
            filteredImgUrls=autoBigImage.getBigImageArray(filteredImgUrls);
            getSavedValue();
            if (document.querySelector(".width-check").checked) {
                filteredImgUrls = filteredImgUrls.filter(filterByWidth);
            }
 
            if (document.querySelector(".height-check").checked) {
                filteredImgUrls = filteredImgUrls.filter(filterByHeight);
            }
 
 
            zipFilteredImgUrls = filteredImgUrls;
            if (document.querySelector(".cors-check").checked) {
                fetchBase64ImgsThenPushToZipArray();
            }            
            showImage(filteredImgUrls);
        }
 
        function clean() {
            imgWaitDownload = [];
            imgSelected = [];
            document.querySelector(".num-tip").innerText = `${langSet.fetchDoneTip1Type2}${imgSelected.length}/${imgUrls.length}${langSet.fetchDoneTip2}`;
            document.querySelector(".tyc-image-wrapper").innerHTML = "";
        }
 
        function isDownload(ele) {
            return ele.className == "download-direct";
        }
 
        function isSelect(ele) {
            return ele.className == "select-image";
        }
 
        function transIndexToLink(WholeImgs,selectedImgs) {
            let transedImgs=[];
            selectedImgs.forEach((imgIndex, index) => {
                transedImgs.push(WholeImgs[imgIndex]);
            });
            return transedImgs;
        }
 
        function showImage(filtedImgUrls) {
            filtedImgUrls.forEach((img, index) => {
                if (window.location.href.includes("huaban.com")) {
                    if (img.includes("/webp")) {
                        img = img.replace(/\/webp/g, "/png");
                    }
                }
                let insertImg = `<div class="tyc-img-item-container-${index}" style="text-align:center;font-size:0px;
    margin:5px;border:1px solid #99d;border-radius:3px;
    ">
    <img class="tyc-image-preview" src="${img}"/ style="width:auto;height:200px;"></div>`
                document.querySelector(".tyc-image-wrapper").insertAdjacentHTML("beforeend", insertImg);
                let naturalW = document.querySelector(`.tyc-img-item-container-${index} .tyc-image-preview`).naturalWidth;
                let naturalH = document.querySelector(`.tyc-img-item-container-${index} .tyc-image-preview`).naturalHeight;
 
                let imgInfoContainer = `
            <div style="font-size:0px;background-color:rgba(100,100,100,0.6);height:30px;position:relative;">
 
 
    </div>
            `;
 
                let thisImgContainer = document.querySelector(`.tyc-img-item-container-${index}`);
                let imgContainerWidth = thisImgContainer.getBoundingClientRect().width;
                let imgInfo = `
            <span style="font-size:16px;position:absolute;left:calc(50% - 80px);top:7px;">${naturalW}X${naturalH}</span>
            `;
 
 
                /*
                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrows-fullscreen" viewBox="0 0 16 16" style="position:absolute;top:5px;right:5px;">
          <path fill-rule="evenodd" d="M5.828 10.172a.5.5 0 0 0-.707 0l-4.096 4.096V11.5a.5.5 0 0 0-1 0v3.975a.5.5 0 0 0 .5.5H4.5a.5.5 0 0 0 0-1H1.732l4.096-4.096a.5.5 0 0 0 0-.707zm4.344 0a.5.5 0 0 1 .707 0l4.096 4.096V11.5a.5.5 0 1 1 1 0v3.975a.5.5 0 0 1-.5.5H11.5a.5.5 0 0 1 0-1h2.768l-4.096-4.096a.5.5 0 0 1 0-.707zm0-4.344a.5.5 0 0 0 .707 0l4.096-4.096V4.5a.5.5 0 1 0 1 0V.525a.5.5 0 0 0-.5-.5H11.5a.5.5 0 0 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 0 .707zm-4.344 0a.5.5 0 0 1-.707 0L1.025 1.732V4.5a.5.5 0 0 1-1 0V.525a.5.5 0 0 1 .5-.5H4.5a.5.5 0 0 1 0 1H1.732l4.096 4.096a.5.5 0 0 1 0 .707z"/>
        </svg>*/
 
                let downAndFullBtn = `
    <span style="position:absolute;right:calc(50% - 30px);top:2px;border:1px solid #333;
    width:26px;height:26px;border-radius:20px;" class="select-image" data-value="${index}">
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check" viewBox="0 0 16 16"  style="position:absolute;top:-1px;right:-2px;width:30px;height:30px;" data-value="${index}">
      <path d="M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425a.267.267 0 0 1 .02-.022z"/>
    </svg>
    </span>
    <span style="position:absolute;right:calc(50% - 60px);top:2px;border:1px solid #333;
    width:26px;height:26px;border-radius:20px;
    " class="download-direct">
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-download" viewBox="0 0 16 16" style="position:absolute;top:5px;right:5px;">
      <path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
      <path d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
    </svg>
    </span>
 
    `;
 
                let downloadBtn = `
            <span style="position:absolute;right:calc(50% - 15px);top:2px;border:1px solid #333;
    width:26px;height:26px;border-radius:20px;
    " class="download-direct">
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-download" viewBox="0 0 16 16" style="position:absolute;top:5px;right:5px;">
      <path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
      <path d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
    </svg>
    </span>
            `
                thisImgContainer.insertAdjacentHTML("beforeend", imgInfoContainer);
 
                let thisImgInfoContainer = thisImgContainer.querySelector("div");
 
                let rectWidth = parseInt(thisImgContainer.getBoundingClientRect().width);
 
                if (rectWidth > 120) {
                    thisImgInfoContainer.insertAdjacentHTML("beforeend", imgInfo);
                    thisImgInfoContainer.insertAdjacentHTML("beforeend", downAndFullBtn);
                } else if (rectWidth <= 120 && rectWidth >= 50) {
                    thisImgInfoContainer.insertAdjacentHTML("beforeend", downAndFullBtn);
                    thisImgInfoContainer.getElementsByClassName("select-image")[0].style.right = "50%";
                    thisImgInfoContainer.getElementsByClassName("download-direct")[0].style.right = "calc(50% - 30px)";
                } else {
                    thisImgInfoContainer.insertAdjacentHTML("beforeend", downloadBtn);
                }
                ////console.log(img);
            });
        }
 
        function filterByWidth(src) {
            let tempImg = new Image();
            tempImg.src = src;
            if (tempImg.width >= parseInt(document.querySelector(".width-value-min").value)
                && tempImg.width <= parseInt(document.querySelector(".width-value-max").value)) {
                return src;
            }
        }
 
        function filterByHeight(src) {
            let tempImg = new Image();
            tempImg.src = src;
            if (tempImg.height >= parseInt(document.querySelector(".height-value-min").value)
                && tempImg.height <= parseInt(document.querySelector(".height-value-max").value)) {
                return src;
            }
        }
 
        function getSavedValue() {
            if(GM_getValue("width-check")!=undefined){
                //console.log(GM_getValue("width-check"));
                (document.querySelector(".width-check").checked = GM_getValue("width-check"));
            }
 
            if(GM_getValue("height-check")!=undefined){
                (document.querySelector(".height-check").checked = GM_getValue("height-check"));
            }
 
            if(GM_getValue("cors-check")!=undefined){
                (document.querySelector(".cors-check").checked = GM_getValue("cors-check"));
                
            }
 
            GM_getValue("width-value-min") && (document.querySelector(".width-value-min").value = GM_getValue("width-value-min"));
            GM_getValue("width-value-max") && (document.querySelector(".width-value-max").value = GM_getValue("width-value-max"));
            GM_getValue("height-value-min") && (document.querySelector(".height-value-min").value = GM_getValue("height-value-min"));
            GM_getValue("height-value-max") && (document.querySelector(".height-value-max").value = GM_getValue("height-value-max"));
 
        }
 
        function fetchBase64ImgsThenPushToZipArray() {
            zipFilteredImgUrls.forEach((imgUrl, urlIndex) => {
                if (imgUrl.includes("data:image")) {
                    return;
                }
 
/*                 fetch(imgUrl,{
                    method: "get",
                    mode: 'cors'
                }).then(response=>{
                    if (!response.ok) {
                        throw new Error('Network response was not OK');
                      }
                      return response.blob();
                    }).then(myBlob=>{
                    var blob = myBlob
                        let oFileReader = new FileReader();
                        oFileReader.onloadend = function (e) {
                            let base64 = e.target.result;
                            //console.log("》》", base64)
 
                            if (base64.includes("data:image")) {
                                zipFilteredImgUrls[urlIndex] = base64;
                                //zipImgWaitDownload.push(base64);
                            }
                        };
                        oFileReader.readAsDataURL(blob);                    
                })
                .catch((error)=>{ */
                try {
                    GM_xmlhttpRequest({
                        method: "get",
                        url: imgUrl,
                        responseType: "blob",
                        onload: function (r) {
                            var blob = r.response;
                            let oFileReader = new FileReader();
                            oFileReader.onloadend = function (e) {
                                let base64 = e.target.result; 
                                if (base64.startsWith("data:image")) {
                                    zipFilteredImgUrls[urlIndex] = base64;
                                    //zipImgWaitDownload.push(base64);
                                }
                            };
                            oFileReader.readAsDataURL(blob);
                        }
                    });
                } catch (error) {
                    
                }

                //})
            })
        }
 
        function cutoffNotBase64Img(imgsUrlArray) {
            let resultArr = [];
            imgsUrlArray.forEach((imgUrl, urlIndex) => {
                if (imgUrl.startsWith("data:image")&&imgUrl.includes("base64")) {
                    resultArr.push(imgUrl);
                }
            }
            );
            return resultArr;
        }
    //下面这个括号是wrapper的括号   
    }
})();