前端实现采集图片某个区域的颜色色值

前端实现,获取本地图片某个区域的颜色色值,

效果图如下

代码如下

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片颜色拾取器</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: Arial, sans-serif;
            background-color: #f5f5f5;
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .container {
            background-color: white;
            padding: 2rem;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            width: 90%;
            max-width: 800px;
        }

        .upload-section {
            margin-bottom: 2rem;
            text-align: center;
        }

        #uploadBtn {
            padding: 0.8rem 1.5rem;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 1rem;
            transition: background-color 0.3s;
        }

        #uploadBtn:hover {
            background-color: #45a049;
        }

        .preview-section {
            margin-bottom: 2rem;
        }

        .image-container {
            width: 100%;
            height: 400px;
            border: 2px dashed #ccc;
            border-radius: 4px;
            overflow: hidden;
            position: relative;
        }

        #previewImage {
            width: 100%;
            height: 100%;
            object-fit: contain;
            cursor: crosshair;
        }

        .color-section {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 1rem;
        }

        .color-display {
            width: 100px;
            height: 100px;
            border-radius: 8px;
            border: 2px solid #ddd;
        }

        .color-values {
            display: flex;
            flex-direction: column;
            gap: 0.5rem;
            width: 100%;
            max-width: 300px;
        }

        .color-value-item {
            display: flex;
            align-items: center;
            gap: 0.5rem;
            background-color: #f0f0f0;
            padding: 0.5rem 1rem;
            border-radius: 4px;
        }

        .color-value {
            font-size: 1.2rem;
            font-weight: bold;
            flex-grow: 1;
        }

        .copy-btn {
            padding: 0.3rem 0.8rem;
            background-color: #2196F3;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 0.9rem;
            transition: background-color 0.3s;
        }

        .copy-btn:hover {
            background-color: #1976D2;
        }

        .copy-btn.copied {
            background-color: #4CAF50;
        }

        .paste-test {
            width: 100%;
            max-width: 300px;
            margin-top: 1rem;
        }

        #pasteInput {
            width: 100%;
            padding: 0.8rem 1rem;
            border: 2px solid #ddd;
            border-radius: 4px;
            font-size: 1rem;
            transition: border-color 0.3s;
        }

        #pasteInput:focus {
            outline: none;
            border-color: #2196F3;
        }

        #pasteInput::placeholder {
            color: #999;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="upload-section">
            <input type="file" id="imageInput" accept="image/*" style="display: none;">
            <button id="uploadBtn">上传图片</button>
            <div style="margin-top: 20px;color: #a19c9c;">功能介绍:选择图片上传,点击获取图片某个位置的颜色色值</div>
        </div>
        
        <div class="preview-section">
            <div class="image-container">
                <img id="previewImage" style="display: none;">
            </div>
        </div>
        
        <div class="color-section">
            <div class="color-display"></div>
            <div class="color-values">
                <div class="color-value-item">
                    <span class="color-value" id="hexValue">#000000</span>
                    <button class="copy-btn" data-value="hex">复制</button>
                </div>
                <div class="color-value-item">
                    <span class="color-value" id="rgbValue">rgb(0, 0, 0)</span>
                    <button class="copy-btn" data-value="rgb">复制</button>
                </div>
            </div>
            <div class="paste-test">
                <input type="text" id="pasteInput" placeholder="在这里粘贴测试复制的颜色值">
            </div>
        </div>
    </div>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const uploadBtn = document.getElementById('uploadBtn');
            const imageInput = document.getElementById('imageInput');
            const previewImage = document.getElementById('previewImage');
            const colorDisplay = document.querySelector('.color-display');
            const hexValue = document.getElementById('hexValue');
            const rgbValue = document.getElementById('rgbValue');
            const copyButtons = document.querySelectorAll('.copy-btn');

            // 点击上传按钮触发文件选择
            uploadBtn.addEventListener('click', () => {
                imageInput.click();
            });

            // 处理文件选择
            imageInput.addEventListener('change', (e) => {
                const file = e.target.files[0];
                if (file) {
                    const reader = new FileReader();
                    reader.onload = (e) => {
                        previewImage.src = e.target.result;
                        previewImage.style.display = 'block';
                    };
                    reader.readAsDataURL(file);
                }
            });

            // 创建画布用于获取颜色
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');

            // 处理图片点击事件
            previewImage.addEventListener('click', (e) => {
                if (!previewImage.src) return;

                // 获取图片容器的尺寸和位置
                const container = previewImage.parentElement;
                const containerRect = container.getBoundingClientRect();
                
                // 计算图片在容器中的实际显示尺寸
                const imageRatio = previewImage.naturalWidth / previewImage.naturalHeight;
                let imageWidth, imageHeight;
                
                if (containerRect.width / containerRect.height > imageRatio) {
                    // 图片高度填满容器
                    imageHeight = containerRect.height;
                    imageWidth = imageHeight * imageRatio;
                } else {
                    // 图片宽度填满容器
                    imageWidth = containerRect.width;
                    imageHeight = imageWidth / imageRatio;
                }
                
                // 计算图片在容器中的位置(居中)
                const imageX = (containerRect.width - imageWidth) / 2;
                const imageY = (containerRect.height - imageHeight) / 2;
                
                // 计算点击位置相对于图片的坐标
                const clickX = e.clientX - containerRect.left - imageX;
                const clickY = e.clientY - containerRect.top - imageY;
                
                // 如果点击在图片外部,则返回
                if (clickX < 0 || clickX > imageWidth || clickY < 0 || clickY > imageHeight) {
                    return;
                }
                
                // 将点击坐标转换为图片原始尺寸的坐标
                const originalX = (clickX / imageWidth) * previewImage.naturalWidth;
                const originalY = (clickY / imageHeight) * previewImage.naturalHeight;

                // 设置画布大小与图片相同
                canvas.width = previewImage.naturalWidth;
                canvas.height = previewImage.naturalHeight;

                // 在画布上绘制图片
                ctx.drawImage(previewImage, 0, 0);

                // 获取点击位置的颜色
                const pixel = ctx.getImageData(Math.floor(originalX), Math.floor(originalY), 1, 1).data;
                const color = `rgb(${pixel[0]}, ${pixel[1]}, ${pixel[2]})`;
                const hexColor = rgbToHex(pixel[0], pixel[1], pixel[2]);

                // 更新颜色显示
                colorDisplay.style.backgroundColor = color;
                hexValue.textContent = hexColor;
                rgbValue.textContent = color;
            });

            // 复制按钮点击事件
            copyButtons.forEach(button => {
                button.addEventListener('click', () => {
                    const valueType = button.dataset.value;
                    const valueToCopy = valueType === 'hex' ? hexValue.textContent : rgbValue.textContent;
                    
                    // 复制到剪贴板
                    navigator.clipboard.writeText(valueToCopy).then(() => {
                        // 显示复制成功状态
                        button.classList.add('copied');
                        button.textContent = '已复制';
                        
                        // 2秒后恢复按钮状态
                        setTimeout(() => {
                            button.classList.remove('copied');
                            button.textContent = '复制';
                        }, 2000);
                    }).catch(err => {
                        console.error('复制失败:', err);
                    });
                });
            });
        });

        // RGB转十六进制
        function rgbToHex(r, g, b) {
            return '#' + [r, g, b].map(x => {
                const hex = x.toString(16);
                return hex.length === 1 ? '0' + hex : hex;
            }).join('');
        } 
    </script>
</body>
</html> 
posted @ 2025-05-11 18:03  进军的蜗牛  阅读(76)  评论(0)    收藏  举报