批量生成图片工具(附源码)

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片生成器</title>
    <!-- 引入Font Awesome图标库 -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
    <style>
        /* 全局样式 */
        body {
            font-family: 'Roboto', Arial, sans-serif;
            background-color: #f9f9f9;
            color: #333;
            margin: 0;
            padding: 0;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
        }

        h1 {
            font-size: 2rem;
            margin-bottom: 1rem;
            color: #444;
        }

        p {
            font-size: 1rem;
            color: #666;
            margin-bottom: 2rem;
            text-align: center;
        }

        /* 容器样式 */
        .container {
            width: 100%;
            max-width: 500px;
            padding: 2rem;
            background-color: #fff;
            border-radius: 10px;
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
            text-align: center;
        }

        /* 自定义文件选择按钮 */
        .custom-file-upload {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 100%;
            padding: 0.8rem;
            margin: 0.5rem 0;
            border: none;
            border-radius: 5px;
            font-size: 1rem;
            cursor: pointer;
            text-align: center;
            background-color: #007bff;
            color: #fff;
            transition: background-color 0.3s ease;
        }

        .custom-file-upload:hover {
            background-color: #0056b3;
        }

        .custom-file-upload i {
            margin-right: 0.5rem;
        }

        .file-name {
            font-size: 0.9rem;
            color: #444;
            margin-top: 0.5rem;
            word-break: break-all; /* 防止路径过长导致溢出 */
        }

        input[type="number"] {
            width: 100%;
            padding: 0.8rem;
            margin: 0.5rem 0;
            border: 1px solid #ccc;
            border-radius: 5px;
            font-size: 1rem;
            outline: none;
            transition: border-color 0.3s ease;
        }

        input[type="number"]:hover {
            border-color: #aaa;
        }

        button {
            width: 100%;
            padding: 0.8rem;
            margin-top: 1rem;
            background-color: #28a745;
            color: #fff;
            border: none;
            border-radius: 5px;
            font-size: 1rem;
            cursor: pointer;
            transition: background-color 0.3s ease;
        }

        button:hover {
            background-color: #218838;
        }

        button:disabled {
            background-color: #ccc;
            cursor: not-allowed;
        }

        /* 加载动画 */
        .loading {
            margin-top: 1rem;
            font-size: 1rem;
            color: #007bff;
        }

        .spinner {
            display: inline-block;
            width: 16px;
            height: 16px;
            border: 3px solid rgba(0, 123, 255, 0.3);
            border-top-color: #007bff;
            border-radius: 50%;
            animation: spin 0.8s linear infinite;
            margin-right: 0.5rem;
        }

        @keyframes spin {
            to { transform: rotate(360deg); }
        }

        /* 隐藏Canvas */
        canvas {
            display: none;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1><i class="fas fa-image"></i> 图片生成器</h1>
        <p>上传一张图片,设置需要生成的图片数量,程序会生成指定数量的图片并打包成ZIP文件下载。</p>

        <!-- 自定义文件选择按钮 -->
        <button id="uploadButton" class="custom-file-upload">
            <i class="fas fa-upload"></i> 选择图片
        </button>
        <div id="fileName" class="file-name">未选择文件</div>

        <!-- 设置生成图片数量 -->
        <label for="imageCount"><i class="fas fa-copy"></i> 生成图片数量:</label>
        <input type="number" id="imageCount" value="100" min="1">

        <!-- 生成按钮 -->
        <button id="generateButton" disabled>
            <i class="fas fa-download"></i> 生成并下载ZIP
        </button>

        <!-- 加载动画 -->
        <div id="loading" class="loading" style="display: none;">
            <span class="spinner"></span> 正在生成,请稍候...
        </div>
    </div>

    <canvas id="canvas"></canvas>

    <!-- 引入JSZip库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>

    <script>
        const uploadButton = document.getElementById('uploadButton');
        const generateButton = document.getElementById('generateButton');
        const imageCountInput = document.getElementById('imageCount');
        const loadingDiv = document.getElementById('loading');
        const fileNameDiv = document.getElementById('fileName');
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');

        let originalImage = null;

        // 创建隐藏的文件输入框
        const fileInput = document.createElement('input');
        fileInput.type = 'file';
        fileInput.accept = 'image/jpeg, image/png, image/gif';
        fileInput.style.display = 'none';

        // 监听文件选择
        fileInput.addEventListener('change', (event) => {
            const file = event.target.files[0];
            if (file) {
                let filePath = file.name; // 默认显示文件名

                // 尝试获取完整路径
                if ('webkitRelativePath' in file && file.webkitRelativePath) {
                    filePath = file.webkitRelativePath; // 使用相对路径
                } else if (file.path) {
                    filePath = file.path; // 非标准API,仅在某些环境下支持(如Electron)
                }

                fileNameDiv.textContent = `已选择文件:${filePath}`;

                // 加载图片
                const img = new Image();
                img.src = URL.createObjectURL(file);
                img.onload = () => {
                    originalImage = img;
                    canvas.width = img.width;
                    canvas.height = img.height;
                    generateButton.disabled = false; // 启用生成按钮
                };
            } else {
                fileNameDiv.textContent = '未选择文件';
                generateButton.disabled = true; // 禁用生成按钮
            }
        });

        // 点击“选择图片”按钮时触发文件选择
        uploadButton.addEventListener('click', () => {
            fileInput.click(); // 触发隐藏的文件输入框
        });

        // 生成图片并保存ZIP
        generateButton.addEventListener('click', async () => {
            const count = parseInt(imageCountInput.value, 10);
            if (!originalImage || isNaN(count) || count <= 0) {
                alert('请上传一张图片并输入有效的生成数量!');
                return;
            }

            generateButton.disabled = true;
            loadingDiv.style.display = 'block';

            try {
                const zip = new JSZip();
                const folder = zip.folder('generated_images');

                for (let i = 0; i < count; i++) {
                    ctx.clearRect(0, 0, canvas.width, canvas.height);
                    ctx.drawImage(originalImage, 0, 0);
                    applyRandomModification(ctx, canvas.width, canvas.height);

                    const dataUrl = canvas.toDataURL('image/png');
                    const base64Data = dataUrl.split(',')[1];
                    folder.file(`generated_image_${i + 1}.png`, base64Data, { base64: true });
                }

                const content = await zip.generateAsync({ type: 'blob' });

                // 下载ZIP文件
                const link = document.createElement('a');
                link.href = URL.createObjectURL(content);
                link.download = 'generated_images.zip';
                link.click();
                alert(`${count}张图片已生成并打包为ZIP文件,默认保存到您的下载目录!`);
            } catch (error) {
                console.error('生成失败:', error);
                alert('生成失败,请重试!');
            } finally {
                loadingDiv.style.display = 'none';
                generateButton.disabled = false;
            }
        });

        // 随机修改图片
        function applyRandomModification(ctx, width, height) {
            const randomType = Math.floor(Math.random() * 3);

            if (randomType === 0) {
                ctx.globalAlpha = Math.random() * 0.5 + 0.5; // 修改透明度
            } else if (randomType === 1) {
                const angle = (Math.random() - 0.5) * 30; // 旋转角度
                ctx.translate(width / 2, height / 2);
                ctx.rotate((angle * Math.PI) / 180);
                ctx.translate(-width / 2, -height / 2);
            } else if (randomType === 2) {
                for (let i = 0; i < 1000; i++) {
                    const x = Math.random() * width;
                    const y = Math.random() * height;
                    const color = `rgba(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255}, 0.5)`;
                    ctx.fillStyle = color;
                    ctx.fillRect(x, y, 1, 1); // 添加噪点
                }
            }
        }
    </script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值