/
android113
/
pixel_art_html_converter
Обзор
Документация
Войти
/
android113
/
pixel_art_html_converter
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
result.html
313 строк
11 KB
Скороходов Андрей Андреевич
Initial one(and last xd)
08 дек 2025, 13:55
08 дек 2025, 13:55
74040ac
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Результаты конвертации</title> <style> :root { --primary-color: #6a11cb; --secondary-color: #2575fc; --accent-color: #ff6b6b; --background-color: #f8f9fa; --card-bg: rgba(255, 255, 255, 0.9); --text-color: #333; --border-radius: 16px; --shadow: 0 8px 32px rgba(31, 38, 135, 0.2); --transition: all 0.3s ease; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 10%); min-height: 100vh; padding: 20px; display: flex; align-items: center; justify-content: center; color: var(--text-color); } .container { width: 100%; max-width: 1400px; margin: 0 auto; } .header { text-align: center; margin-bottom: 30px; } h1 { font-size: 2.5rem; color: white; margin-bottom: 10px; text-shadow: 0 2px 4px rgba(0,0,0,0.3); background: linear-gradient(45deg, #ff6b6b, #4ecdc4); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .subtitle { color: rgba(255, 255, 255, 0.8); font-size: 1.1rem; } .comparison-container { display: grid; grid-template-columns: 1fr 1fr; gap: 30px; align-items: start; } @media (max-width: 768px) { .comparison-container { grid-template-columns: 1fr; } } .image-wrapper { text-align: center; } .image-title { font-size: 1.3rem; font-weight: 600; margin-bottom: 20px; color: white; } .image-container { width: 100%; max-width: 600px; margin: 0 auto; position: relative; /* Flex center необходим, чтобы изображение width: auto стояло по центру, а не слева в случае вертикального формата */ display: flex; justify-content: center; align-items: center; } img { /* width: auto и max-width заставляют элемент img сжиматься до фактического размера изображения, чтобы рамка облегала контент */ width: auto; max-width: 100%; max-height: 600px; object-fit: contain; display: block; border: 6px solid transparent; /* Резервируем место и толщину рамки */ border-radius: 4px; /* Небольшое скругление углов самой картинки/рамки */ box-shadow: 0 4px 15px rgba(0,0,0,0.2); } .controls { text-align: center; margin-top: 20px; } button { background: linear-gradient(45deg, var(--primary-color), var(--secondary-color)); color: white; border: none; padding: 12px 20px; border-radius: 12px; cursor: pointer; font-size: 1rem; font-weight: 600; transition: var(--transition); box-shadow: 0 4px 15px rgba(106, 17, 203, 0.3); margin: 0 10px; } button:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(106, 17, 203, 0.4); } .info-panel { background: rgba(255, 255, 255, 0.2); backdrop-filter: blur(10px); padding: 15px; border-radius: var(--border-radius); margin-top: 20px; text-align: center; color: white; } .info-item { display: inline-block; margin: 0 15px; font-weight: 600; } </style> </head> <body> <div class="container"> <div class="header"> <h1>🎨 Результаты конвертации</h1> <p class="subtitle">Сравнение оригинального и пиксельного изображений</p> </div> <div class="comparison-container"> <div class="image-wrapper"> <h2 class="image-title">🖼️ Оригинал</h2> <div class="image-container"> <img id="originalImage" src="" alt="Оригинальное изображение"> </div> </div> <div class="image-wrapper"> <h2 class="image-title">✨ Пиксельный результат</h2> <div class="image-container"> <img id="pixelImage" src="" alt="Пиксельное изображение"> </div> </div> </div> <div class="info-panel"> <div class="info-item">Размер пикселя: <span id="pixelSizeInfo">8</span>px</div> <div class="info-item">Размер изображения: <span id="sizeInfo">400x400</span></div> </div> <div class="controls"> <button id="backBtn">Назад к конвертеру</button> <button id="downloadBtn">Скачать пиксельное изображение</button> </div> </div> <script> // Создаем скрытый canvas для анализа изображений const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); // Функция для определения среднего цвета краев изображения function getEdgeColor(img) { const width = img.width; const height = img.height; // Определяем размер краевой области const edgeSize = Math.max(1, Math.min(10, Math.floor(Math.min(width, height) * 0.05))); canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0); const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const data = imageData.data; let totalR = 0, totalG = 0, totalB = 0, totalA = 0; let count = 0; // Вспомогательная функция для сбора данных пикселя const addPixel = (r, g, b, a) => { if (a > 128) { // Игнорируем полностью прозрачные части, чтобы не искажать рамку totalR += r; totalG += g; totalB += b; totalA += a; count++; } }; // Проходим по верхнему и нижнему краю for (let x = 0; x < width; x++) { for (let y = 0; y < edgeSize; y++) { const i = (y * width + x) * 4; addPixel(data[i], data[i+1], data[i+2], data[i+3]); } for (let y = height - edgeSize; y < height; y++) { const i = (y * width + x) * 4; addPixel(data[i], data[i+1], data[i+2], data[i+3]); } } // Проходим по левому и правому краю (избегая повторов углов) for (let y = edgeSize; y < height - edgeSize; y++) { for (let x = 0; x < edgeSize; x++) { const i = (y * width + x) * 4; addPixel(data[i], data[i+1], data[i+2], data[i+3]); } for (let x = width - edgeSize; x < width; x++) { const i = (y * width + x) * 4; addPixel(data[i], data[i+1], data[i+2], data[i+3]); } } if (count > 0) { return { r: Math.round(totalR / count), g: Math.round(totalG / count), b: Math.round(totalB / count), a: Math.round(totalA / count) }; } else { return {r: 128, g: 128, b: 128, a: 255}; } } function getLuminance(color) { return (0.299 * color.r + 0.587 * color.g + 0.114 * color.b) / 255; } // Функция обновлена: теперь принимает imgElement и работает с ним напрямую function setImageOutline(imgElement) { const applyOutline = () => { const bgColor = getEdgeColor(imgElement); const luminance = getLuminance(bgColor); // Если края светлые - рамка черная. Если темные - рамка белая. const outlineColor = luminance > 0.5 ? '#000000' : '#FFFFFF'; // Рамка 6 пикселей, цвет по контрасту imgElement.style.borderColor = outlineColor; }; if (imgElement.complete && imgElement.naturalHeight !== 0) { applyOutline(); } else { imgElement.onload = applyOutline; } } const urlParams = new URLSearchParams(window.location.search); const originalImageData = urlParams.get('original'); const pixelImageData = urlParams.get('pixel'); const pixelSize = urlParams.get('pixelSize'); const outputSize = urlParams.get('outputSize'); const originalImage = document.getElementById('originalImage'); const pixelImage = document.getElementById('pixelImage'); originalImage.src = originalImageData; pixelImage.src = pixelImageData; document.getElementById('pixelSizeInfo').textContent = pixelSize; document.getElementById('sizeInfo').textContent = outputSize; // Вызываем без контейнера, так как работаем с самим элементом img setImageOutline(originalImage); setImageOutline(pixelImage); document.getElementById('backBtn').addEventListener('click', function() { window.close(); }); document.getElementById('downloadBtn').addEventListener('click', function() { const link = document.createElement('a'); link.download = 'pixel-art.png'; link.href = pixelImageData; link.click(); }); </script> </body> </html>