15色以下に減色した画像を、画像解析し色レイヤーごとに表示(画像表示縮小追加)

画像の色情報と色レイヤー





15色に減色webアプリこちら
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>画像の色情報と色レイヤー</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }
        input[type="file"] {
            margin-bottom: 10px;
        }
        .colorLayerContainer {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
        }
        .colorLayer {
            margin: 5px;
            border: 1px solid #ccc;
            width: 50px;
            height: 50px;
        }
        .colorLayerImageContainer {
            margin: 5px;
            width: 400px;
            height: auto;
            text-align: center;
        }
        .colorLayerImage {
            max-width: 100%;
            max-height: 400px;
        }
    </style>
</head>
<body>

    <input type="file" id="imageUploader" accept="image/*">
    <div id="colorLayers" class="colorLayerContainer"></div>
    <div id="colorLayerImage" class="colorLayerImageContainer"></div>
    <br/><br/><br/><br/>
   

    <script>
        const errorMargin = 3;
        let img;

        document.getElementById('imageUploader').addEventListener('change', function(e) {
            const file = e.target.files[0];
            const reader = new FileReader();
            reader.onload = function(e) {
                img = new Image();
                img.onload = function() {
                    const canvas = document.createElement('canvas');
                    const ctx = canvas.getContext('2d');
                    canvas.width = img.width;
                    canvas.height = img.height;
                    ctx.drawImage(img, 0, 0);
                    const imageData = ctx.getImageData(0, 0, img.width, img.height);
                    const colors = extractColors(imageData);
                    const mergedColors = mergeSimilarColors(colors);
                    displayColorLayers(mergedColors, img.width, img.height);
                    displayColorImageLayers(mergedColors, imageData);
                };
                img.src = e.target.result;
            };
            reader.readAsDataURL(file);
        });

        function extractColors(imageData) {
            const colors = {};
            const data = imageData.data;
            for (let i = 0; i < data.length; i += 4) {
                const r = data[i];
                const g = data[i + 1];
                const b = data[i + 2];
                const roundedColor = roundColorValues(r, g, b);
                colors[roundedColor] = (colors[roundedColor] || 0) + 1;
            }
            return colors;
        }

        function roundColorValues(r, g, b) {
            const roundedR = Math.round(r / errorMargin) * errorMargin;
            const roundedG = Math.round(g / errorMargin) * errorMargin;
            const roundedB = Math.round(b / errorMargin) * errorMargin;
            return `${roundedR},${roundedG},${roundedB}`;
        }

        function mergeSimilarColors(colors) {
            const mergedColors = {};
            for (const color1 in colors) {
                let isMerged = false;
                for (const color2 in mergedColors) {
                    if (isSimilarColor(color1, color2)) {
                        mergedColors[color2] += colors[color1];
                        isMerged = true;
                        break;
                    }
                }
                if (!isMerged) {
                    mergedColors[color1] = colors[color1];
                }
            }
            return mergedColors;
        }

        function isSimilarColor(color1, color2) {
            const [r1, g1, b1] = color1.split(',').map(Number);
            const [r2, g2, b2] = color2.split(',').map(Number);
            return Math.abs(r1 - r2) <= errorMargin &&
                   Math.abs(g1 - g2) <= errorMargin &&
                   Math.abs(b1 - b2) <= errorMargin;
        }

        function displayColorLayers(colors, imageWidth, imageHeight) {
            const colorLayersDiv = document.getElementById('colorLayers');
            colorLayersDiv.innerHTML = '';

            for (const color in colors) {
                const colorLayerCanvas = document.createElement('canvas');
                colorLayerCanvas.width = imageWidth;
                colorLayerCanvas.height = imageHeight;
                colorLayerCanvas.classList.add('colorLayer');
                const colorLayerCtx = colorLayerCanvas.getContext('2d');
                const [r, g, b] = color.split(',').map(Number);
                const imageData = colorLayerCtx.createImageData(imageWidth, imageHeight);
                const data = imageData.data;
                for (let i = 0; i < data.length; i += 4) {
                    data[i] = r;
                    data[i + 1] = g;
                    data[i + 2] = b;
                    data[i + 3] = 255;
                }
                colorLayerCtx.putImageData(imageData, 0, 0);
                colorLayersDiv.appendChild(colorLayerCanvas);
            }
        }

        function extractColorPixels(imageData, color) {
            const width = imageData.width;
            const height = imageData.height;
            const colorLayerCanvas = document.createElement('canvas');
            const colorLayerCtx = colorLayerCanvas.getContext('2d');
            colorLayerCanvas.width = width;
            colorLayerCanvas.height = height;
            const imageDataCopy = new ImageData(new Uint8ClampedArray(imageData.data), width, height);
            const data = imageDataCopy.data;
            const colorComponents = color.split(',').map(Number);
            const r = colorComponents[0];
            const g = colorComponents[1];
            const b = colorComponents[2];

            for (let i = 0; i < data.length; i += 4) {
                const pixelR = data[i];
                const pixelG = data[i + 1];
                const pixelB = data[i + 2];
                if (Math.abs(pixelR - r) <= errorMargin && Math.abs(pixelG - g) <= errorMargin && Math.abs(pixelB - b) <= errorMargin) {
                    data[i + 3] = 255;
                } else {
                    data[i + 3] = 0;
                }
            }
            colorLayerCtx.putImageData(imageDataCopy, 0, 0);
            return colorLayerCanvas;
        }

        function displayColorImageLayers(colors, imageData) {
            const colorLayerImageDiv = document.getElementById('colorLayerImage');
            colorLayerImageDiv.innerHTML = '';

            for (const color in colors) {
                const colorLayerCanvas = extractColorPixels(imageData, color);
                colorLayerCanvas.classList.add('colorLayerImage');
                colorLayerImageDiv.appendChild(colorLayerCanvas);
            }
        }
    </script>
</body>
</html>