{"id":10,"date":"2025-06-09T21:32:33","date_gmt":"2025-06-09T12:32:33","guid":{"rendered":"http:\/\/tools.easy-trip-more.com\/?page_id=10"},"modified":"2025-06-09T21:32:33","modified_gmt":"2025-06-09T12:32:33","slug":"jpg%e3%83%bbpng%e7%94%bb%e5%83%8f%e3%82%92webp%e7%94%bb%e5%83%8f%e3%81%ab%e4%b8%80%e6%8b%ac%e5%a4%89%e6%8f%9b","status":"publish","type":"page","link":"https:\/\/tools.easy-trip-more.com\/","title":{"rendered":"JPG\u30fbPNG\u753b\u50cf\u3092WEBP\u753b\u50cf\u306b\u4e00\u62ec\u5909\u63db"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"ja\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>\u753b\u50cf\u5909\u63db\u30c4\u30fc\u30eb &#8211; JPG\/PNG \u21d4 WebP<\/title>\n    <style>\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n\n        body {\n            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n            min-height: 100vh;\n        }\n\n        .container {\n            max-width: 800px;\n            margin: 0 auto;\n            background: rgba(255, 255, 255, 0.95);\n            backdrop-filter: blur(10px);\n            border-radius: 20px;\n            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);\n            overflow: hidden;\n        }\n\n        .header {\n            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);\n            color: white;\n            padding: 30px;\n            text-align: center;\n        }\n\n        .header h1 {\n            font-size: 2.5rem;\n            margin-bottom: 10px;\n            text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n        }\n\n        .header p {\n            font-size: 1.1rem;\n            opacity: 0.9;\n        }\n\n        .content {\n            padding: 40px;\n        }\n\n        .upload-area {\n            border: 3px dashed #ddd;\n            border-radius: 15px;\n            padding: 60px 20px;\n            text-align: center;\n            margin-bottom: 30px;\n            transition: all 0.3s ease;\n            cursor: pointer;\n            background: linear-gradient(45deg, #f8f9ff 0%, #f0f4ff 100%);\n        }\n\n        .upload-area:hover {\n            border-color: #4facfe;\n            background: linear-gradient(45deg, #f0f4ff 0%, #e8f2ff 100%);\n            transform: translateY(-2px);\n        }\n\n        .upload-area.dragover {\n            border-color: #4facfe;\n            background: linear-gradient(45deg, #e8f2ff 0%, #d8ebff 100%);\n            transform: scale(1.02);\n        }\n\n        .upload-icon {\n            font-size: 4rem;\n            color: #4facfe;\n            margin-bottom: 20px;\n        }\n\n        .upload-text {\n            font-size: 1.2rem;\n            color: #666;\n            margin-bottom: 10px;\n        }\n\n        .upload-subtext {\n            color: #999;\n            font-size: 0.9rem;\n        }\n\n        #fileInput {\n            display: none;\n        }\n\n        .format-selector {\n            margin-bottom: 30px;\n        }\n\n        .format-selector h3 {\n            margin-bottom: 15px;\n            color: #333;\n            font-size: 1.3rem;\n        }\n\n        .format-options {\n            display: flex;\n            gap: 15px;\n            flex-wrap: wrap;\n            justify-content: center;\n        }\n\n        .format-option {\n            position: relative;\n        }\n\n        .format-option input[type=\"radio\"] {\n            display: none;\n        }\n\n        .format-option label {\n            display: block;\n            padding: 15px 25px;\n            background: #f8f9fa;\n            border: 2px solid #e9ecef;\n            border-radius: 50px;\n            cursor: pointer;\n            transition: all 0.3s ease;\n            font-weight: 600;\n            color: #666;\n            min-width: 120px;\n            text-align: center;\n        }\n\n        .format-option input[type=\"radio\"]:checked + label {\n            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);\n            color: white;\n            border-color: #4facfe;\n            transform: translateY(-2px);\n            box-shadow: 0 5px 15px rgba(79, 172, 254, 0.3);\n        }\n\n        .quality-slider {\n            margin-bottom: 30px;\n            display: none;\n        }\n\n        .quality-slider.show {\n            display: block;\n        }\n\n        .quality-slider h4 {\n            margin-bottom: 10px;\n            color: #333;\n        }\n\n        .slider-container {\n            display: flex;\n            align-items: center;\n            gap: 15px;\n        }\n\n        .slider {\n            flex: 1;\n            height: 6px;\n            border-radius: 3px;\n            background: #ddd;\n            outline: none;\n            -webkit-appearance: none;\n        }\n\n        .slider::-webkit-slider-thumb {\n            appearance: none;\n            width: 20px;\n            height: 20px;\n            border-radius: 50%;\n            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);\n            cursor: pointer;\n            box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);\n        }\n\n        .quality-value {\n            font-weight: bold;\n            color: #4facfe;\n            min-width: 40px;\n        }\n\n        .convert-btn {\n            width: 100%;\n            padding: 18px;\n            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n            color: white;\n            border: none;\n            border-radius: 50px;\n            font-size: 1.2rem;\n            font-weight: bold;\n            cursor: pointer;\n            transition: all 0.3s ease;\n            margin-bottom: 30px;\n        }\n\n        .convert-btn:hover:not(:disabled) {\n            transform: translateY(-2px);\n            box-shadow: 0 10px 25px rgba(102, 126, 234, 0.4);\n        }\n\n        .convert-btn:disabled {\n            opacity: 0.6;\n            cursor: not-allowed;\n        }\n\n        .preview-area {\n            display: none;\n            margin-top: 30px;\n        }\n\n        .bulk-download-area {\n            text-align: center;\n            margin-bottom: 30px;\n            padding: 20px;\n            background: #f8f9fa;\n            border-radius: 15px;\n        }\n\n        .bulk-download-btn {\n            background: linear-gradient(135deg, #ff7b7b 0%, #ff416c 100%);\n            color: white;\n            border: none;\n            padding: 15px 30px;\n            border-radius: 25px;\n            cursor: pointer;\n            font-weight: bold;\n            font-size: 1.1rem;\n            transition: all 0.3s ease;\n        }\n\n        .bulk-download-btn:hover {\n            transform: translateY(-2px);\n            box-shadow: 0 5px 15px rgba(255, 65, 108, 0.4);\n        }\n\n        .preview-container {\n            display: grid;\n            grid-template-columns: 1fr 1fr;\n            gap: 30px;\n            margin-bottom: 40px;\n        }\n\n        .preview-box {\n            text-align: center;\n        }\n\n        .preview-box h4 {\n            margin-bottom: 15px;\n            color: #333;\n            font-size: 1.1rem;\n        }\n\n        .preview-box img {\n            max-width: 100%;\n            max-height: 300px;\n            border-radius: 10px;\n            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);\n            margin-bottom: 15px;\n        }\n\n        .file-info {\n            background: #f8f9fa;\n            padding: 15px;\n            border-radius: 10px;\n            text-align: left;\n        }\n\n        .file-info div {\n            margin-bottom: 5px;\n            color: #666;\n        }\n\n        .download-btn {\n            background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);\n            color: white;\n            border: none;\n            padding: 12px 30px;\n            border-radius: 25px;\n            cursor: pointer;\n            font-weight: bold;\n            transition: all 0.3s ease;\n            margin-top: 15px;\n        }\n\n        .download-btn:hover {\n            transform: translateY(-2px);\n            box-shadow: 0 5px 15px rgba(17, 153, 142, 0.4);\n        }\n\n        .progress-bar {\n            width: 100%;\n            height: 6px;\n            background: #f0f0f0;\n            border-radius: 3px;\n            overflow: hidden;\n            margin: 20px 0;\n            display: none;\n        }\n\n        .progress-fill {\n            height: 100%;\n            background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%);\n            width: 0%;\n            transition: width 0.3s ease;\n        }\n\n        .compression-info {\n            background: #e8f5e8;\n            border: 1px solid #4caf50;\n            padding: 10px;\n            border-radius: 8px;\n            margin-top: 10px;\n            font-size: 0.9rem;\n        }\n\n        .compression-info.size-increase {\n            background: #fff3cd;\n            border-color: #ffc107;\n        }\n\n        @media (max-width: 768px) {\n            .container {\n                margin: 10px;\n                border-radius: 15px;\n            }\n\n            .header h1 {\n                font-size: 2rem;\n            }\n\n            .content {\n                padding: 30px 20px;\n            }\n\n            .preview-container {\n                grid-template-columns: 1fr;\n                gap: 20px;\n            }\n\n            .format-options {\n                flex-direction: column;\n                align-items: center;\n            }\n\n            .format-option label {\n                min-width: 200px;\n            }\n        }\n    <\/style>\n<\/head>\n<body>\n    <div class=\"container\">\n        <div class=\"header\">\n            <h1>\ud83d\udd04 \u753b\u50cf\u5909\u63db\u30c4\u30fc\u30eb<\/h1>\n            <p>JPG\u30fbPNG \u21d4 WebP \u306e\u76f8\u4e92\u5909\u63db\u304c\u7c21\u5358\u306b\u3067\u304d\u307e\u3059<\/p>\n        <\/div>\n        \n        <div class=\"content\">\n            <div class=\"upload-area\" onclick=\"document.getElementById('fileInput').click()\">\n                <div class=\"upload-icon\">\ud83d\udcc1<\/div>\n                <div class=\"upload-text\">\u30d5\u30a1\u30a4\u30eb\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u9078\u629e\u3001\u307e\u305f\u306f\u30c9\u30e9\u30c3\u30b0&#038;\u30c9\u30ed\u30c3\u30d7<\/div>\n                <div class=\"upload-subtext\">JPG\u3001PNG\u3001WebP\u5f62\u5f0f\u306b\u5bfe\u5fdc<\/div>\n            <\/div>\n            \n            <input type=\"file\" id=\"fileInput\" accept=\".jpg,.jpeg,.png,.webp\" multiple>\n            \n            <div class=\"format-selector\">\n                <h3>\u5909\u63db\u5148\u306e\u5f62\u5f0f\u3092\u9078\u629e<\/h3>\n                <div class=\"format-options\">\n                    <div class=\"format-option\">\n                        <input type=\"radio\" id=\"toWebp\" name=\"format\" value=\"webp\" checked>\n                        <label for=\"toWebp\">WebP<\/label>\n                    <\/div>\n                    <div class=\"format-option\">\n                        <input type=\"radio\" id=\"toJpg\" name=\"format\" value=\"jpg\">\n                        <label for=\"toJpg\">JPG<\/label>\n                    <\/div>\n                    <div class=\"format-option\">\n                        <input type=\"radio\" id=\"toPng\" name=\"format\" value=\"png\">\n                        <label for=\"toPng\">PNG<\/label>\n                    <\/div>\n                <\/div>\n            <\/div>\n            \n            <div class=\"quality-slider\" id=\"qualitySlider\">\n                <h4>\u753b\u8cea\u8a2d\u5b9a<\/h4>\n                <div class=\"slider-container\">\n                    <input type=\"range\" class=\"slider\" id=\"qualityRange\" min=\"0.1\" max=\"1\" step=\"0.1\" value=\"0.8\">\n                    <span class=\"quality-value\" id=\"qualityValue\">80%<\/span>\n                <\/div>\n            <\/div>\n            \n            <button class=\"convert-btn\" id=\"convertBtn\" disabled>\u5909\u63db\u958b\u59cb<\/button>\n            \n            <div class=\"progress-bar\" id=\"progressBar\">\n                <div class=\"progress-fill\" id=\"progressFill\"><\/div>\n            <\/div>\n            \n            <div class=\"preview-area\" id=\"previewArea\"><\/div>\n        <\/div>\n    <\/div>\n\n    <!-- JSZip CDN -->\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jszip\/3.10.1\/jszip.min.js\"><\/script>\n\n    <script>\n        const fileInput = document.getElementById('fileInput');\n        const uploadArea = document.querySelector('.upload-area');\n        const convertBtn = document.getElementById('convertBtn');\n        const previewArea = document.getElementById('previewArea');\n        const qualitySlider = document.getElementById('qualitySlider');\n        const qualityRange = document.getElementById('qualityRange');\n        const qualityValue = document.getElementById('qualityValue');\n        const progressBar = document.getElementById('progressBar');\n        const progressFill = document.getElementById('progressFill');\n        \n        let selectedFiles = [];\n        let convertedResults = [];\n\n        \/\/ \u30c9\u30e9\u30c3\u30b0&\u30c9\u30ed\u30c3\u30d7\u6a5f\u80fd\n        uploadArea.addEventListener('dragover', (e) => {\n            e.preventDefault();\n            uploadArea.classList.add('dragover');\n        });\n\n        uploadArea.addEventListener('dragleave', () => {\n            uploadArea.classList.remove('dragover');\n        });\n\n        uploadArea.addEventListener('drop', (e) => {\n            e.preventDefault();\n            uploadArea.classList.remove('dragover');\n            const files = Array.from(e.dataTransfer.files);\n            handleFiles(files);\n        });\n\n        \/\/ \u30d5\u30a1\u30a4\u30eb\u9078\u629e\n        fileInput.addEventListener('change', (e) => {\n            const files = Array.from(e.target.files);\n            handleFiles(files);\n        });\n\n        \/\/ \u54c1\u8cea\u30b9\u30e9\u30a4\u30c0\u30fc\n        qualityRange.addEventListener('input', (e) => {\n            const value = Math.round(e.target.value * 100);\n            qualityValue.textContent = value + '%';\n        });\n\n        \/\/ \u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u5909\u66f4\u6642\u306e\u54c1\u8cea\u30b9\u30e9\u30a4\u30c0\u30fc\u8868\u793a\u5236\u5fa1\n        document.querySelectorAll('input[name=\"format\"]').forEach(radio => {\n            radio.addEventListener('change', (e) => {\n                if (e.target.value === 'png') {\n                    qualitySlider.classList.remove('show');\n                } else {\n                    qualitySlider.classList.add('show');\n                }\n            });\n        });\n\n        \/\/ \u521d\u671f\u72b6\u614b\u3067\u54c1\u8cea\u30b9\u30e9\u30a4\u30c0\u30fc\u3092\u8868\u793a\n        qualitySlider.classList.add('show');\n\n        function handleFiles(files) {\n            const validFiles = files.filter(file => {\n                const type = file.type.toLowerCase();\n                return type.includes('jpeg') || type.includes('jpg') || \n                       type.includes('png') || type.includes('webp');\n            });\n\n            if (validFiles.length === 0) {\n                alert('JPG\u3001PNG\u3001WebP\u5f62\u5f0f\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002');\n                return;\n            }\n\n            selectedFiles = validFiles;\n            convertBtn.disabled = false;\n            \n            \/\/ \u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u30a8\u30ea\u30a2\u306e\u8868\u793a\u3092\u66f4\u65b0\n            uploadArea.innerHTML = `\n                <div class=\"upload-icon\">\u2705<\/div>\n                <div class=\"upload-text\">${validFiles.length}\u500b\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u9078\u629e\u3055\u308c\u307e\u3057\u305f<\/div>\n                <div class=\"upload-subtext\">\u30af\u30ea\u30c3\u30af\u3057\u3066\u4ed6\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e<\/div>\n            `;\n        }\n\n        \/\/ \u5909\u63db\u51e6\u7406\n        convertBtn.addEventListener('click', async () => {\n            if (selectedFiles.length === 0) return;\n\n            const format = document.querySelector('input[name=\"format\"]:checked').value;\n            const quality = parseFloat(qualityRange.value);\n\n            convertBtn.disabled = true;\n            progressBar.style.display = 'block';\n            previewArea.innerHTML = '';\n            previewArea.style.display = 'none';\n            convertedResults = [];\n\n            const results = [];\n            \n            for (let i = 0; i < selectedFiles.length; i++) {\n                const file = selectedFiles[i];\n                \n                \/\/ \u30d7\u30ed\u30b0\u30ec\u30b9\u30d0\u30fc\u66f4\u65b0\n                const progress = ((i + 1) \/ selectedFiles.length) * 100;\n                progressFill.style.width = progress + '%';\n                \n                try {\n                    const result = await convertImage(file, format, quality);\n                    results.push(result);\n                    convertedResults.push(result);\n                } catch (error) {\n                    console.error('\u5909\u63db\u30a8\u30e9\u30fc:', error);\n                    alert(`${file.name} \u306e\u5909\u63db\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002`);\n                }\n            }\n\n            displayResults(results);\n            convertBtn.disabled = false;\n            progressBar.style.display = 'none';\n        });\n\n        async function convertImage(file, targetFormat, quality) {\n            return new Promise((resolve, reject) => {\n                const canvas = document.createElement('canvas');\n                const ctx = canvas.getContext('2d');\n                const img = new Image();\n\n                img.onload = () => {\n                    \/\/ \u5143\u306e\u753b\u50cf\u30b5\u30a4\u30ba\u3092\u7dad\u6301\n                    canvas.width = img.width;\n                    canvas.height = img.height;\n                    \n                    \/\/ \u9ad8\u54c1\u8cea\u306a\u63cf\u753b\u8a2d\u5b9a\n                    ctx.imageSmoothingEnabled = true;\n                    ctx.imageSmoothingQuality = 'high';\n                    ctx.drawImage(img, 0, 0);\n\n                    let mimeType, extension, finalQuality;\n                    switch (targetFormat) {\n                        case 'webp':\n                            mimeType = 'image\/webp';\n                            extension = 'webp';\n                            \/\/ WebP\u306e\u5834\u5408\u3001JPG\u304b\u3089\u306e\u5909\u63db\u3067\u306f\u54c1\u8cea\u3092\u5c11\u3057\u4e0b\u3052\u308b\n                            finalQuality = file.type.includes('jpeg') || file.type.includes('jpg') ? \n                                           Math.min(quality, 0.85) : quality;\n                            break;\n                        case 'jpg':\n                            mimeType = 'image\/jpeg';\n                            extension = 'jpg';\n                            finalQuality = quality;\n                            break;\n                        case 'png':\n                            mimeType = 'image\/png';\n                            extension = 'png';\n                            finalQuality = undefined; \/\/ PNG\u306f\u54c1\u8cea\u30d1\u30e9\u30e1\u30fc\u30bf\u306a\u3057\n                            break;\n                    }\n\n                    canvas.toBlob((blob) => {\n                        if (blob) {\n                            const originalName = file.name.replace(\/\\.[^\/.]+$\/, '');\n                            const convertedName = originalName + '.' + extension;\n                            \n                            resolve({\n                                originalFile: file,\n                                convertedBlob: blob,\n                                convertedName: convertedName,\n                                originalSize: file.size,\n                                convertedSize: blob.size\n                            });\n                        } else {\n                            reject(new Error('\u5909\u63db\u306b\u5931\u6557\u3057\u307e\u3057\u305f'));\n                        }\n                    }, mimeType, finalQuality);\n                };\n\n                img.onerror = () => reject(new Error('\u753b\u50cf\u306e\u8aad\u307f\u8fbc\u307f\u306b\u5931\u6557\u3057\u307e\u3057\u305f'));\n                img.src = URL.createObjectURL(file);\n            });\n        }\n\n        function displayResults(results) {\n            if (results.length === 0) return;\n\n            let html = '<h3 style=\"margin-bottom: 20px; color: #333;\">\u5909\u63db\u7d50\u679c<\/h3>';\n            \n            \/\/ \u4e00\u62ec\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u30dc\u30bf\u30f3\n            html += `\n                <div class=\"bulk-download-area\">\n                    <h4 style=\"margin-bottom: 15px; color: #333;\">\u4e00\u62ec\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9<\/h4>\n                    <button class=\"bulk-download-btn\" onclick=\"downloadAllAsZip()\">\n                        \ud83d\udce6 \u3059\u3079\u3066\u3092ZIP\u3067\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\n                    <\/button>\n                <\/div>\n            `;\n            \n            results.forEach((result, index) => {\n                const originalUrl = URL.createObjectURL(result.originalFile);\n                const convertedUrl = URL.createObjectURL(result.convertedBlob);\n                const compressionRatio = ((1 - result.convertedSize \/ result.originalSize) * 100).toFixed(1);\n                const isIncrease = result.convertedSize > result.originalSize;\n                \n                html += `\n                    <div class=\"preview-container\" style=\"margin-bottom: 40px;\">\n                        <div class=\"preview-box\">\n                            <h4>\u5909\u63db\u524d<\/h4>\n                            <img decoding=\"async\" src=\"${originalUrl}\" alt=\"\u5909\u63db\u524d\">\n                            <div class=\"file-info\">\n                                <div><strong>\u30d5\u30a1\u30a4\u30eb\u540d:<\/strong> ${result.originalFile.name}<\/div>\n                                <div><strong>\u30b5\u30a4\u30ba:<\/strong> ${formatFileSize(result.originalSize)}<\/div>\n                                <div><strong>\u5f62\u5f0f:<\/strong> ${result.originalFile.type}<\/div>\n                            <\/div>\n                        <\/div>\n                        \n                        <div class=\"preview-box\">\n                            <h4>\u5909\u63db\u5f8c<\/h4>\n                            <img decoding=\"async\" src=\"${convertedUrl}\" alt=\"\u5909\u63db\u5f8c\">\n                            <div class=\"file-info\">\n                                <div><strong>\u30d5\u30a1\u30a4\u30eb\u540d:<\/strong> ${result.convertedName}<\/div>\n                                <div><strong>\u30b5\u30a4\u30ba:<\/strong> ${formatFileSize(result.convertedSize)}<\/div>\n                                <div class=\"compression-info ${isIncrease ? 'size-increase' : ''}\">\n                                    <strong>\u30b5\u30a4\u30ba\u5909\u5316:<\/strong> ${isIncrease ? '+' : '-'}${Math.abs(compressionRatio)}%\n                                    ${isIncrease ? '\uff08\u30b5\u30a4\u30ba\u304c\u5897\u52a0\u3057\u307e\u3057\u305f\uff09' : '\uff08\u5727\u7e2e\u3055\u308c\u307e\u3057\u305f\uff09'}\n                                <\/div>\n                            <\/div>\n                            <button class=\"download-btn\" onclick=\"downloadFile('${convertedUrl}', '${result.convertedName}')\">\n                                \u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\n                            <\/button>\n                        <\/div>\n                    <\/div>\n                `;\n            });\n\n            previewArea.innerHTML = html;\n            previewArea.style.display = 'block';\n        }\n\n        async function downloadAllAsZip() {\n            if (convertedResults.length === 0) {\n                alert('\u5909\u63db\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308a\u307e\u305b\u3093\u3002');\n                return;\n            }\n\n            const zip = new JSZip();\n            \n            \/\/ \u5404\u5909\u63db\u6e08\u307f\u30d5\u30a1\u30a4\u30eb\u3092ZIP\u306b\u8ffd\u52a0\n            for (const result of convertedResults) {\n                zip.file(result.convertedName, result.convertedBlob);\n            }\n\n            try {\n                \/\/ ZIP\u30d5\u30a1\u30a4\u30eb\u3092\u751f\u6210\n                const zipBlob = await zip.generateAsync({type: 'blob'});\n                \n                \/\/ \u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\n                const url = URL.createObjectURL(zipBlob);\n                const a = document.createElement('a');\n                a.href = url;\n                a.download = `converted_images_${new Date().getTime()}.zip`;\n                document.body.appendChild(a);\n                a.click();\n                document.body.removeChild(a);\n                URL.revokeObjectURL(url);\n            } catch (error) {\n                console.error('ZIP\u4f5c\u6210\u30a8\u30e9\u30fc:', error);\n                alert('ZIP\u30d5\u30a1\u30a4\u30eb\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002');\n            }\n        }\n\n        function formatFileSize(bytes) {\n            if (bytes === 0) return '0 Bytes';\n            const k = 1024;\n            const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n            const i = Math.floor(Math.log(bytes) \/ Math.log(k));\n            return parseFloat((bytes \/ Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n        }\n\n        function downloadFile(url, filename) {\n            const a = document.createElement('a');\n            a.href = url;\n            a.download = filename;\n            document.body.appendChild(a);\n            a.click();\n            document.body.removeChild(a);\n        }\n    <\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>\u753b\u50cf\u5909\u63db\u30c4\u30fc\u30eb &#8211; JPG\/PNG \u21d4 WebP \ud83d\udd04 \u753b\u50cf\u5909\u63db\u30c4\u30fc\u30eb JPG\u30fbPNG \u21d4 WebP \u306e\u76f8\u4e92\u5909\u63db\u304c\u7c21\u5358\u306b\u3067\u304d\u307e\u3059 \ud83d\udcc1 \u30d5\u30a1\u30a4\u30eb\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u9078\u629e\u3001\u307e\u305f\u306f\u30c9\u30e9\u30c3\u30b0&#038;\u30c9\u30ed\u30c3\u30d7 JPG\u3001PN [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"swell_btn_cv_data":"","footnotes":""},"class_list":["post-10","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/tools.easy-trip-more.com\/index.php?rest_route=\/wp\/v2\/pages\/10","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tools.easy-trip-more.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/tools.easy-trip-more.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/tools.easy-trip-more.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tools.easy-trip-more.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10"}],"version-history":[{"count":3,"href":"https:\/\/tools.easy-trip-more.com\/index.php?rest_route=\/wp\/v2\/pages\/10\/revisions"}],"predecessor-version":[{"id":13,"href":"https:\/\/tools.easy-trip-more.com\/index.php?rest_route=\/wp\/v2\/pages\/10\/revisions\/13"}],"wp:attachment":[{"href":"https:\/\/tools.easy-trip-more.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}