图立得-html纯前端图片拾色器V202507

图立得-html纯前端图片拾色器V202507

全棧开发,前端网页设计,图片设计工作制开源(绿色)好工具。

RGB 颜色、HEX 颜色、CMYK 颜色、HSL 颜色、坐标位置快速获取带色预览。

复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图立得前端图片拾色器,纯前端 chalide.cn</title>
<meta name="author" content="yujianyue, 15058593138@qq.com">

    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
            font-family: Arial, sans-serif;
        }
        
        body {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
            color: #333;
        }
        
        h1 {
            text-align: center;
            margin-bottom: 20px;
            color: #2c3e50;
        }
        
        .container {
            background-color: white;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        }
        
        .upload-area {
            border: 2px dashed #ccc;
            border-radius: 8px;
            padding: 15px;
            text-align: center;
            margin-bottom: 20px;
            transition: all 0.3s;
            cursor: pointer;
            background-color: #fafafa;
        }
        
        .upload-area:hover {
            border-color: #3498db;
            background-color: #f0f8ff;
        }
        
        .upload-area.drag-over {
            border-color: #2ecc71;
            background-color: #e8f8f0;
        }
        
        .upload-area i {
            font-size: 48px;
            color: #3498db;
            margin-bottom: 10px;
        }
        
        .upload-area p {
            margin-bottom: 10px;
            color: #7f8c8d;
        }
        
        input[type="file"] {
            display: none;
        }
        
        .preview-container {
            position: relative;
            margin-top: 20px;
            overflow: hidden;
            text-align: center;
        }
        
        #imagePreview {
            max-width: 100%;
            min-height: 70vh;
            display: inline-block;
            cursor: crosshair;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        }
        
        .color-info {
          position: sticky;
          top: 0; /* 当滚动到顶部时固定 */
          z-index: 100; /* 确保它在其他内容之上 */
            margin-top: 0px;
            padding: 5px;
            background-color: #f8f9fa;
            border-radius: 8px;
            display: flex;
            flex-wrap: wrap;
            gap: 5px;
            justify-content: center;
        }
        
        .color-info-item {
            min-width: 180px;
            text-align: left;
        }
        
        .color-info-item h3 {
            margin-bottom: 2px;
            color: #2c3e50;
            font-size: 16px;
        }
        
        .color-value {
            font-family: monospace;
            font-size: 14px;
            padding: 4px;
            background-color: white;
            border-radius: 4px;
            border: 1px solid #ddd;
            margin-bottom: 2px;
        }
        
        .color-preview {
            width: 60px;
            height: 20px;
            border-radius: 4px;
            border: 1px solid #ddd;
            margin: 0 auto;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
        }
        
        .coordinates {
            margin-top: 2px;
            font-size: 14px;
            color: #7f8c8d;
        }
        
        .error {
            color: #e74c3c;
            margin-top: 10px;
            text-align: center;
            padding: 10px;
            background-color: #fde8e8;
            border-radius: 4px;
            display: none;
        }
        
        .error.show {
            display: block;
        }
        
        .image-info {
            margin-top: 10px;
            font-size: 14px;
            color: #7f8c8d;
            text-align: center;
        }
        
        .magnifier {
            position: absolute;
            width: 120px;
            height: 120px;
            border: 3px solid #fff;
            border-radius: 50%;
            box-shadow: 0 0 15px rgba(0, 0, 0, 0.5);
            pointer-events: none;
            display: none;
            overflow: hidden;
            z-index: 100;
        }
        
        .magnifier-content {
            width: 100%;
            height: 100%;
            transform: scale(2.5);
            transform-origin: 0 0;
            background-repeat: no-repeat;
        }
        
        .zoom-lens {
            position: absolute;
            width: 20px;
            height: 20px;
            border: 2px solid #fff;
            border-radius: 50%;
            box-shadow: 0 0 5px rgba(0, 0, 0, 0.8);
            pointer-events: none;
            display: none;
            z-index: 99;
        }
        
        .no-image {
            text-align: center;
            padding: 40px;
            color: #7f8c8d;
            font-size: 18px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>图立得 - 前端图片拾色器</h1>
        
        <div class="upload-area" id="uploadArea">
            <p>拖放图片到此处或点击选择文件</p>
            <p>支持格式: JPG, PNG, GIF, WEBP</p>
            <input type="file" id="fileInput" accept="image/jpeg,image/png,image/gif,image/webp">
        </div>
               <div class="color-info" id="colorInfo" style="display: none;">
            <div class="color-info-item">
                <h3>RGB 颜色</h3>
                <div class="color-value" id="rgbValue">RGB(0, 0, 0)</div>
                <div class="color-preview" id="rgbPreview"></div>
            </div>
            
            <div class="color-info-item">
                <h3>HEX 颜色</h3>
                <div class="color-value" id="hexValue">#000000</div>
                <div class="color-preview" id="hexPreview"></div>
            </div>
            
            <div class="color-info-item">
                <h3>CMYK 颜色</h3>
                <div class="color-value" id="cmykValue">CMYK(0%, 0%, 0%, 100%)</div>
                <div class="color-preview" id="cmykPreview"></div>
            </div>
            
            <div class="color-info-item">
                <h3>HSL 颜色</h3>
                <div class="color-value" id="hslValue">HSL(0, 0%, 0%)</div>
                <div class="color-preview" id="hslPreview"></div>
            </div>
            
            <div class="color-info-item">
                <h3>坐标位置</h3>
                <div class="color-value" id="coordValue">X: 0, Y: 0</div>
                <div class="coordinates" id="pixelInfo">像素: RGBA(0, 0, 0, 0)</div>
            </div>
        </div>
        <div class="error" id="error"></div>
        
        <div class="preview-container" id="previewContainer">
            <div class="no-image" id="noImage">请选择或拖放图片到上方区域,选图后色号等显示在图片下方</div>
            <img id="imagePreview" style="display: none;">
            <div class="magnifier" id="magnifier">
                <div class="magnifier-content" id="magnifierContent"></div>
            </div>
            <div class="zoom-lens" id="zoomLens"></div>
        </div>
        
        <div class="image-info" id="imageInfo"></div>
        
 
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const uploadArea = document.getElementById('uploadArea');
            const fileInput = document.getElementById('fileInput');
            const previewContainer = document.getElementById('previewContainer');
            const noImage = document.getElementById('noImage');
            const imagePreview = document.getElementById('imagePreview');
            const imageInfo = document.getElementById('imageInfo');
            const colorInfo = document.getElementById('colorInfo');
            const error = document.getElementById('error');
            const rgbValue = document.getElementById('rgbValue');
            const hexValue = document.getElementById('hexValue');
            const cmykValue = document.getElementById('cmykValue');
            const hslValue = document.getElementById('hslValue');
            const coordValue = document.getElementById('coordValue');
            const pixelInfo = document.getElementById('pixelInfo');
            const rgbPreview = document.getElementById('rgbPreview');
            const hexPreview = document.getElementById('hexPreview');
            const cmykPreview = document.getElementById('cmykPreview');
            const hslPreview = document.getElementById('hslPreview');
            const magnifier = document.getElementById('magnifier');
            const magnifierContent = document.getElementById('magnifierContent');
            const zoomLens = document.getElementById('zoomLens');
            
            let canvas = document.createElement('canvas');
            let ctx = canvas.getContext('2d', { willReadFrequently: true });
            let currentImageData = null;
            let naturalWidth = 0;
            let naturalHeight = 0;
            
            // 点击上传区域
            uploadArea.addEventListener('click', function() {
                fileInput.click();
            });
            
            // 拖放功能
            uploadArea.addEventListener('dragover', function(e) {
                e.preventDefault();
                this.classList.add('drag-over');
            });
            
            uploadArea.addEventListener('dragleave', function() {
                this.classList.remove('drag-over');
            });
            
            uploadArea.addEventListener('drop', function(e) {
                e.preventDefault();
                this.classList.remove('drag-over');
                
                if (e.dataTransfer.files.length) {
                    handleFile(e.dataTransfer.files[0]);
                }
            });
            
            // 文件选择
            fileInput.addEventListener('change', function() {
                if (this.files.length) {
                    handleFile(this.files[0]);
                }
            });
            
            // 图片鼠标移动事件
            imagePreview.addEventListener('mousemove', function(e) {
                if (!currentImageData) return;
                
                const rect = this.getBoundingClientRect();
                const scaleX = this.naturalWidth / this.width;
                const scaleY = this.naturalHeight / this.height;
                
                let x = Math.round((e.clientX - rect.left) * scaleX);
                let y = Math.round((e.clientY - rect.top) * scaleY);
                
                // 确保坐标在图片范围内
                x = Math.max(0, Math.min(x, this.naturalWidth - 1));
                y = Math.max(0, Math.min(y, this.naturalHeight - 1));
                
                // 显示放大镜
                magnifier.style.display = 'block';
                magnifier.style.left = (e.clientX + 20) + 'px';
                magnifier.style.top = (e.clientY + 20) + 'px';
                
                // 更新放大镜内容
                magnifierContent.style.backgroundImage = `url(${imagePreview.src})`;
                magnifierContent.style.backgroundPosition = `-${x-24}px -${y-24}px`;
                
                // 显示缩放镜头
                zoomLens.style.display = 'block';
                zoomLens.style.left = (e.clientX - 10) + 'px';
                zoomLens.style.top = (e.clientY - 10) + 'px';
                
                // 获取像素颜色
                const pixel = ctx.getImageData(x, y, 1, 1).data;
                const r = pixel[0];
                const g = pixel[1];
                const b = pixel[2];
                const a = pixel[3] / 255;
                
                // 更新坐标显示
                coordValue.textContent = `X: ${x}, Y: ${y}`;
                pixelInfo.textContent = `像素: RGBA(${r}, ${g}, ${b}, ${a.toFixed(2)})`;
                
                // 更新RGB显示
                rgbValue.textContent = `RGB(${r}, ${g}, ${b})`;
                rgbPreview.style.backgroundColor = `rgb(${r}, ${g}, ${b})`;
                
                // 更新HEX显示
                const hex = rgbToHex(r, g, b);
                hexValue.textContent = `#${hex}`;
                hexPreview.style.backgroundColor = `#${hex}`;
                
                // 更新CMYK显示
                const cmyk = rgbToCmyk(r, g, b);
                cmykValue.textContent = `CMYK(${cmyk.c}%, ${cmyk.m}%, ${cmyk.y}%, ${cmyk.k}%)`;
                cmykPreview.style.backgroundColor = `rgb(${r}, ${g}, ${b})`;
                
                // 更新HSL显示
                const hsl = rgbToHsl(r, g, b);
                hslValue.textContent = `HSL(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%)`;
                hslPreview.style.backgroundColor = `hsl(${hsl.h}, ${hsl.s}%, ${hsl.l}%)`;
            });
            
            imagePreview.addEventListener('mouseout', function() {
                magnifier.style.display = 'none';
                zoomLens.style.display = 'none';
            });
            
            // 处理选择的文件
            function handleFile(file) {
                // 验证文件类型
                const validTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
                if (!validTypes.includes(file.type)) {
                    showError('不支持的文件类型');
                    return;
                }
                
                error.classList.remove('show');
                
                const reader = new FileReader();
                reader.onload = function(e) {
                    imagePreview.onload = function() {
                        // 保存原始尺寸
                        naturalWidth = this.naturalWidth;
                        naturalHeight = this.naturalHeight;
                        
                        // 设置canvas尺寸
                        canvas.width = naturalWidth;
                        canvas.height = naturalHeight;
                        
                        // 绘制图像到canvas
                        ctx.drawImage(this, 0, 0);
                        
                        // 获取图像数据
                        currentImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
                        
                        // 显示预览
                        noImage.style.display = 'none';
                        imagePreview.style.display = 'inline-block';
                        colorInfo.style.display = 'flex';
                        imageInfo.textContent = `${file.name} (${formatFileSize(file.size)}) - ${naturalWidth}×${naturalHeight}像素`;
                    };
                    imagePreview.src = e.target.result;
                };
                reader.onerror = function() {
                    showError('读取文件失败');
                };
                reader.readAsDataURL(file);
            }
            
            // RGB转HEX
            function rgbToHex(r, g, b) {
                return ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase();
            }
            
            // RGB转CMYK
            function rgbToCmyk(r, g, b) {
                if (r === 0 && g === 0 && b === 0) {
                    return { c: 0, m: 0, y: 0, k: 100 };
                }
                
                let c = 1 - (r / 255);
                let m = 1 - (g / 255);
                let y = 1 - (b / 255);
                
                const minCMY = Math.min(c, m, y);
                c = (c - minCMY) / (1 - minCMY);
                m = (m - minCMY) / (1 - minCMY);
                y = (y - minCMY) / (1 - minCMY);
                const k = minCMY;
                
                return {
                    c: Math.round(c * 100),
                    m: Math.round(m * 100),
                    y: Math.round(y * 100),
                    k: Math.round(k * 100)
                };
            }
            
            // RGB转HSL
            function rgbToHsl(r, g, b) {
                r /= 255, g /= 255, b /= 255;
                const max = Math.max(r, g, b), min = Math.min(r, g, b);
                let h, s, l = (max + min) / 2;

                if (max === min) {
                    h = s = 0; // achromatic
                } else {
                    const d = max - min;
                    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
                    switch (max) {
                        case r: h = (g - b) / d + (g < b ? 6 : 0); break;
                        case g: h = (b - r) / d + 2; break;
                        case b: h = (r - g) / d + 4; break;
                    }
                    h /= 6;
                }

                return {
                    h: h * 360,
                    s: s * 100,
                    l: l * 100
                };
            }
            
            // 显示错误
            function showError(message) {
                error.textContent = message;
                error.classList.add('show');
                noImage.style.display = 'block';
                imagePreview.style.display = 'none';
                colorInfo.style.display = 'none';
            }
            
            // 格式化文件大小
            function formatFileSize(bytes) {
                if (bytes === 0) return '0 Bytes';
                const k = 1024;
                const sizes = ['Bytes', 'KB', 'MB', 'GB'];
                const i = Math.floor(Math.log(bytes) / Math.log(k));
                return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
            }
        });
    </script>
</body>
</html>