您需要先安装一款用户样式管理器扩展(如 Stylus )后才能安装此样式。
您需要先安装一款用户样式管理器扩展(如 Stylus )后才能安装此样式。
您需要先安装一款用户样式管理器扩展(如 Stylus )后才能安装此样式。
您需要先安装一款用户样式管理器扩展后才能安装此样式。
您需要先安装一款用户样式管理器扩展后才能安装此样式。
您需要先安装一款用户样式管理器扩展后才能安装此样式。
(我已经安装了用户样式管理器,让我安装!)
换行
// ==UserScript== // @name Image Downloader // @name:zh-CN 图片下载器 // @name:zh-TW 图片下载器 // @namespace http://tampermonkey.net/ // @description You can extract and download pictures in batches on most websites.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 可以在绝大多数网站提取并批量下载图片。尤其是类似于千库网、包图网这种,不能右键保存图片或者保存的图片文件格式无法识别,均可以用脚本提取,然后用脚本提供的下载按钮,就可以下载到正确格式的图片文件。其他的淘宝、天猫电商图片批量下载,youtube、B站封面下载,等等都可以的。点击右键-tampermonkey-图片下载器-打开脚本(或alt+w),按这个顺序使用。(目前只适合chrome+tampermonkey,其他组合多少有问题) // @description:zh-TW 可以在绝大多数网站提取并批量下载图片。尤其是类似于千库网、包图网这种,不能右键保存图片或者保存的图片文件格式无法识别,均可以用脚本提取,然后用脚本提供的下载按钮,就可以下载到正确格式的图片文件。其他的淘宝、天猫电商图片批量下载,youtube、B站封面下载,等等都可以的。点击右键-tampermonkey-图片下载器-打开脚本(或alt+w),按这个顺序使用。(目前只适合chrome+tampermonkey,其他组合多少有问题) // @version 1.58 // @author 桃源隐叟 // @include * // @grant GM_openInTab // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @grant GM_download // @require https://cdn.jsdelivr.net/npm/ hotkeys-js@3.7.2 /dist/hotkeys.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://greasyfork.org/zh-CN/scripts/419894/feedback // ==/UserScript== ( function () { 'use strict' ; var lang = navigator . appName == "Netscape" ? navigator . language : navigator . userLanguage ; var langSet ; var localization = { zh : { selectAll : "全选" , downloadBtn : "下载" , downloadMenuText : "打开脚本(Alt+w)" }, en :{ selectAll : "selectAll" , downloadBtn : "download" , downloadMenuText : "Open(Alt+w)" } } if ( lang . toLowerCase (). includes ( "zh-" )){ langSet = localization . zh ; } else { langSet = localization . en ; } 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 imgWaitDownload = []; var widthFilter = { min : 0 , max : 3000 }; var heightFilter = { min : 0 , max : 3000 }; var tempImgUrls = []; try { let imgEles = document . getElementsByTagName ( "img" ) for ( let i = 0 ; i < imgEles . length ; i ++) { ////console.log(imgEles[i].src); if (! imgUrls . includes ( imgEles [ i ]. src )) { imgUrls . push ( imgEles [ i ]. src ); } } } catch { //alert("error"); } try { 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 ( /"/ g , "" ))) { imgUrls . push ( imgRegs [ i ]. replace ( /"/ g , "" )); } } } catch { //alert("error"); } let imgContainer = ` < div class = "tyc-image-container" style = " position : fixed ; top : 0px ; right : 0px ; width : 50vw ; z - index : 2147483645 ; background - color : # dedede ; border : 1px solid # aaa ; overflow : scroll ; height : 100 %; "> < div class = "control-section" style = " width : 46vw ; z - index : 2147483646 ; position : fixed ; right : 30px ; top : 0px ; display : block ; height : 80px ; line - height : 40px ; background :# eee ; border : 1px solid # aaa ; border - radius : 2px ; "> < input class = "select-all" type = "checkbox" name = "select-all" value = "select-all" > $ { langSet . selectAll } < button class = "btn-download" style = " border : 1px solid # aaa ; border - radius : 5px ; height : 32px ; line - height : 32px ; margin : 0px ; padding : 0 5px ; "> $ { langSet . downloadBtn }</ button > < span style = "margin-left:10px;" class = "num-tip" >已选( 0 / $ { imgUrls . length })张图片</ span > < button class = "btn-close" style = " 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 ; "> X </ button > < p style = "line-height:12px;" > < div style = "float:left;" > < input type = "checkbox" class = "width-check img-check" 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;" > < input type = "checkbox" class = "height-check img-check" 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 > </ p > </ div > < div class = "tyc-image-wrapper" style = " margin - top : 82px ; display : flex ; justify - content : center ; align - items : center ; flex - wrap : wrap ; "> </ 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 ); if ( window . location . href . includes ( "hathitrust.org" )) { //imgUrls=[]; 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 { } } 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 ; var 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 currentImg = parseInt ( checkSvg . dataset . value ); let container = e . path . find (( ele ) => ele . className === ` tyc - img - item - container - $ { currentImg }`); if ( imgSelected . includes ( currentImg )) { imgSelected . splice ( imgSelected . indexOf ( currentImg ), 1 ); checkSvg . style . color = "black" ; container . style . border = "1px solid #99d" ; } else { imgSelected . push ( currentImg ); checkSvg . style . color = "white" ; container . style . border = "1px solid white" ; } document . querySelector ( ".num-tip" ). innerText = `已选( $ { imgSelected . length }/ $ { imgUrls . length })张图片`; transIndexToLink ( tempImgUrls ); } } document . querySelector ( ".btn-close" ). onclick = ( e ) => { document . querySelector ( ".tyc-image-container" ). remove (); } document . querySelector ( ".btn-download" ). onclick = ( e ) => { /* if (document.querySelector(".select-all").checked) { imgUrls.forEach((img, index) => { GM_download(img, `pic-${index}`); }); } else { alert("请勾选全选,下载全部,或者手动在图片上右键另存为指定图片"); } */ if ( imgWaitDownload . length >= 1 ) { imgWaitDownload . forEach ( async ( img , index ) => { console . log ( index ); console . log ( img ); await GM_download ( img , ` pic - $ { index }`); }); } else { alert ( "请至少选中一张图片。" ); } } 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 . 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 = tempImgUrls ; } else { transIndexToLink ( tempImgUrls ); } document . querySelector ( ".num-tip" ). innerText = `已选( $ { imgWaitDownload . length }/ $ { imgUrls . length })张图片`; } init (); function init () { tempImgUrls = imgUrls ; getSavedValue (); if ( document . querySelector ( ".width-check" ). checked ) { tempImgUrls = tempImgUrls . filter ( filterByWidth ); } if ( document . querySelector ( ".height-check" ). checked ) { tempImgUrls = tempImgUrls . filter ( filterByHeight ); } showImage ( tempImgUrls ); } function clean () { imgWaitDownload = []; imgSelected = []; document . querySelector ( ".num-tip" ). innerText = `已选( $ { imgSelected . length }/ $ { imgUrls . length })张图片`; document . querySelector ( ".tyc-image-wrapper" ). innerHTML = "" ; } function isDownload ( ele ) { return ele . className == "download-direct" ; } function isSelect ( ele ) { return ele . className == "select-image" ; } function transIndexToLink ( tempImgUrls ) { imgWaitDownload = []; imgSelected . forEach (( imgIndex , index ) => { imgWaitDownload . push ( tempImgUrls [ imgIndex ]); }); } 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 () { GM_getValue ( "width-check" ) && ( document . querySelector ( ".width-check" ). checked = GM_getValue ( "width-check" )); GM_getValue ( "height-check" ) && ( document . querySelector ( ".height-check" ). checked = GM_getValue ( "height-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" )); } } })();