Greasy Fork

Greasy Fork is available in English.

获取网站所有图片

获取网站的所有图片,支持查看和下载。

当前为 2024-11-27 提交的版本,查看 最新版本

// ==UserScript==
// @name         获取网站所有图片
// @version      2.0.0
// @description  获取网站的所有图片,支持查看和下载。
// @author       BennieCHAN
// @license      MIT
// @match        *://*/*
// @grant        GM_addStyle
// @grant        GM_registerMenuCommand
// @grant        GM_xmlhttpRequest
// @grant        GM_download
// @connect      *
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/hotkeys-js/3.9.1/hotkeys.min.js
// @namespace http://greasyfork.icu/users/1381791
// ==/UserScript==

(function () {
    'use strict';

    class ImageCollector {
        constructor() {
            this.imgList = [];
            this.zip = new JSZip();
            this.init();
        }

        init() {
            this.addStyles();
            this.registerMenu();
            hotkeys('alt+p', () => this.showImages());
        }

        addStyles() {
            const styles = `
                #imageList { position: fixed; top: 10%; left: 10%; width: 80%; height: 80%; background: white; overflow: auto; z-index: 9999; border: 2px solid black; display: none; }
                #imageList ul { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; }
                #imageList li { margin: 10px; position: relative; }
                #imageList img { max-width: 150px; max-height: 150px; display: block; border: 1px solid gray; }
                #imageList .actions { position: absolute; top: 5px; right: 5px; background: rgba(0,0,0,0.5); color: white; padding: 2px 5px; cursor: pointer; }
                #imageList .download-all { margin: 10px; cursor: pointer; display: inline-block; background: black; color: white; padding: 5px 10px; }
                #imageList .close-btn { position: absolute; top: 5px; right: 5px; background: red; color: white; padding: 5px 10px; cursor: pointer; z-index: 10000; }
            `;
            GM_addStyle(styles);
        }

        registerMenu() {
            GM_registerMenuCommand('获取图片 (Alt+P)', () => this.showImages());
        }

        collectImages() {
            const images = [];
            const elements = $('img, canvas, [style*="background-image"]');
            elements.each((index, el) => {
                if (el.tagName === 'IMG') {
                    images.push(el.src);
                } else if (el.tagName === 'CANVAS') {
                    images.push(el.toDataURL());
                } else {
                    const backgroundImage = getComputedStyle(el).backgroundImage;
                    if (backgroundImage.startsWith('url')) {
                        images.push(backgroundImage.slice(5, -2));
                    }
                }
            });
            this.imgList = [...new Set(images)];
        }

        showImages() {
            this.collectImages();
            const container = $('#imageList');
            if (container.length === 0) {
                $('body').append('<div id="imageList"><ul></ul><div class="download-all">下载所有图片</div><div class="close-btn">关闭</div></div>');
                $('#imageList').on('click', '.download-all', () => this.downloadAll());
                $('#imageList').on('click', '.actions', (e) => {
                    const src = $(e.target).data('src');
                    this.downloadImage(src, `image_${Date.now()}.png`);
                });
                $('#imageList').on('click', '.close-btn', () => this.closeImages());
            }

            const list = this.imgList.map(src => `
                <li>
                    <img src="${src}" alt="image">
                    <div class="actions" data-src="${src}">下载</div>
                </li>`).join('');
            $('#imageList ul').html(list);
            $('#imageList').fadeIn();
        }

        closeImages() {
            $('#imageList').fadeOut();
        }

        downloadImage(src, fileName) {
            GM_download({
                url: src,
                name: fileName,
                onerror: () => alert(`图片下载失败: ${src}`)
            });
        }

        downloadAll() {
            if (this.imgList.length === 0) {
                alert('没有找到可下载的图片。');
                return;
            }
            const zipFolder = this.zip.folder('Images');
            const downloadQueue = [...this.imgList];
            const processNext = () => {
                if (downloadQueue.length === 0) {
                    this.zip.generateAsync({ type: 'blob' }).then(content => {
                        saveAs(content, `Images_${Date.now()}.zip`);
                        alert('所有图片已打包下载完成!');
                    });
                    return;
                }
                const src = downloadQueue.shift();
                GM_xmlhttpRequest({
                    method: 'GET',
                    url: src,
                    responseType: 'blob',
                    onload: (response) => {
                        const fileName = `image_${Date.now()}.png`;
                        zipFolder.file(fileName, response.response);
                        processNext();
                    },
                    onerror: () => {
                        console.error(`无法下载图片: ${src}`);
                        processNext();
                    }
                });
            };
            processNext();
        }
    }

    new ImageCollector();
})();