The core steps of color recognition are as follows: 1. After selecting the image, use FileReader API to convert the image into base64 format 2. Create an IMG tag and assign the contents of Base64 to the SRC attribute 3 of the IMG tag. Call the Canvas drawImage() method to make the Canvas draw the image 4. Call the Canvas getImageData() method to get the color value 5 for a pixel. Display the color value in RGB and hexadecimal format

Running effect

The initial page consists of a display box and a button to select an image. After selecting an image, move the mouse pointer to the image and the color value of the image will be displayed.

The source code:

<! doctypehtml>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width =device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Image color recognition</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            /*align-items: center; * /
            background: white;
            margin-top: 20px;
        }
        
        #color {
            height: 30px;
            line-height: 30px;
            text-align: center;
        }
        
        #canvas {
            border: 1px dashed # 000;
        }
        
        .tooltip {
            display: flex;
            justify-content: center;
            align-items: center;
            position: fixed;
            min-width: 150px;
            min-height: 80px;
            margin: 10px;
            padding: 10px 20px;
            border: 1px solid #b3c9ce;
            border-radius: 4px;
            color: #eee;
            font-size: 16px;
            box-shadow: 3px 3px 3px rgba(0.0.0.3);
            z-index: 9999999999999999999999;
        }
        
        .fileWrap {
            margin-left: 200px;
        }
    </style>
</head>

<body>


    <div class="wrapper">
        <canvas id="canvas" width="600" height="400"></canvas>
        <br>
        <br>
        <div class="fileWrap">
            <input type="file" onchange="selectImg(this)">
        </div>
        <br>
        <div id="color"></div>
        <br>
    </div>



    <script>
        var canvas = document.getElementById('canvas');
        var canvasW = canvas.width;
        var canvasH = canvas.height;
        var ctx = canvas.getContext('2d');
        var isSelectImg = false;


        function selectImg(that) {
            isSelectImg = true;
            // console.log("that: ", that);
            var file = that.files[0];
            // console.log(file);
            var reader = new FileReader();

            // console.log("reader: ", reader);
            reader.readAsDataURL(file);

            reader.onload = (e) = > {
                var img = new Image();
                img.src = reader.result;
                img.onload = () = > {
                    // console.log("img.width, img.height: ", img.width, img.height);
                    ctx.clearRect(0.0, canvasW, canvasH);
                    if (img.width < canvasW && img.height < canvasH) {
                        canvas.height = canvasH;
                        ctx.drawImage(img, 0.0, img.width, img.height);
                    } else {
                        canvas.height = canvasW * img.height / img.width; // Keep the image in shape
                        ctx.drawImage(img, 0.0, canvasW, canvas.height); }}}}// RGB to Hex
        function colorRGBtoHex(rgb_color) {
            if (/(^(*(RGB)\((*\d{1,3} *,){2} *\d{1,3} *\)) *$)/.test(rgb_color)) {
                var rgb = rgb_color.split(', ');
                var r = parseInt(rgb[0].split('(') [1]);
                var g = parseInt(rgb[1]);
                var b = parseInt(rgb[2].split(') ') [0]);
                var hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
                return hex;
            }
            return rgb_color;
        }



        // Follow the mouse movement of the tooltip
        function toolTip() {
            let tooltipElem, timer;
            let color = document.getElementById('color');
            document.onmouseover = function(e) {
                var target = e.target;

                if(! isSelectImg)return;
                if(target.tagName ! = ='CANVAS') {
                    return;
                }
                tooltipElem = document.createElement('div');
                tooltipElem.className = "tooltip";
                document.body.append(tooltipElem);

                document.onmousemove = function(e) {
                    tooltipElem.style.left = e.clientX + 'px';
                    tooltipElem.style.top = e.clientY + 'px';

                    var x = e.layerX;
                    var y = e.layerY;
                    var pixel = ctx.getImageData(x, y, 1.1);
                    // console.log("pixel: ", pixel);
                    var data = pixel.data;
                    var rgb =
                        'rgb(' + data[0] +
                        ', ' + data[1] +
                        ', ' + data[2] +
                        // ',' + (data[3] / 255) + // rgba changed to RGB
                        ') ';

                    // function throttling
                    clearInterval(timer);
                    timer = setTimeout(function() {
                    	// Display color values
                        color.style.background = rgb;
                        color.textContent = rgb;
                        tooltipElem.innerText = colorRGBtoHex(rgb);
                        tooltipElem.style.background = rgb;
                    }, 15)}};document.onmouseout = function() {
                if (tooltipElem) {
                    tooltipElem.remove();
                    tooltipElem = null;
                }
                document.onmousemove = null;
                clearInterval(timer)
            }
        }
        toolTip();
    </script>
</body>

</html>
Copy the code

Image color recognition upgrade version

Upgrade function: 1. Add a color and save it to the database 2. If the color in the picture is consistent with the existing color in the database, the color name is displayed

Running effect after the upgrade

The initial interfaceSelect an image (the image I chose is a screenshot from the color control)

To add a color, enter a color name and a color value, then click Save:

Refresh the page and you can see the new color at the end of the comparison:

Upgraded source code

Back-end Node.js startup file (using Express + MySQL):

let my_mysql      = require('mysql');
let express      = require('express');
let path      = require('path');
let conn = my_mysql.createConnection({
    host     : 'localhost'.user     : 'root'.password : '123456'.database : 'color'
});
conn.connect();

var app = express();

const bodyParser = require('body-parser');
app.use(bodyParser.json());// The data type is JSON
app.use(bodyParser.urlencoded({ extended: false }));// Parse post request data

app.use(express.static(path.join(__dirname, 'public')));



app.get('/getAllColor'.async function (req, res) {
    getAllColor(req, res);
})
app.post('/insertColor'.async function (req, res) {
    insertColor(req, res)
})




function getAllColor(req, res) {
    conn.query(`SELECT * FROM color`.function (err, result) {
        if (err) {
            res.send({code: 1.msg: 'Database query error'});
            console.log('[SELECT ERROR] - ', err.message);
            return;
        }
        // console.log("result: ", result);
        res.send(result)
    })
}



function insertColor(req, res) {
    console.log(req.body.name, req.body.value);
    var name = req.body.name;
    var value = req.body.value;

    if (name && name.length > 20) return false;
    if (value && value.length > 30) return false;

    let sql = "INSERT INTO color(name, value) VALUES(? ,?) ";
    let sqlVal = [name, value];
    console.log("sqlVal: ", sqlVal);
    conn.query(sql, sqlVal, function (err, result) {
        if (err) {
            console.log("err: ", err);
            res.send('Add failed')
            return false;
        } else {
            // console.log("result: ", result);
            res.send('Added successfully')
            return true; }})}var port = 4006;

console.log("Server startup time:".new Date().toLocaleString());
console.log("Open your browser and visit: http://localhost:"+port);


app.listen(port);

Copy the code

Database table design:

Vue + jQuery + Layer

<! doctypehtml>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width =device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Color identification</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            /*align-items: center; * /
            background: white;
            margin-top: 20px;
        }
        
        #color {
            height: 30px;
            line-height: 30px;
            text-align: center;
        }
        
        #canvas {
            border: 1px dashed # 000;
        }
        
        .tooltip {
            display: flex;
            justify-content: center;
            align-items: center;
            position: fixed;
            min-width: 150px;
            min-height: 80px;
            margin: 10px;
            padding: 10px 20px;
            border: 1px solid #b3c9ce;
            border-radius: 4px;
            color: #eee;
            font-size: 16px;
            box-shadow: 3px 3px 3px rgba(0.0.0.3);
            z-index: 9999999999999999999999;
        }
        
        .fileWrap {
            margin-left: 200px;
        }
        
        form input {
            height: 25px;
            width: 250px;
        }
        
        form div {
            text-align: center;
            margin-top: 5px;
            line-height: 25px;
            height: 25px;
        }
        
        .left {}
        
        #colorList {
            width: 350px;
            height: 500px;
            overflow: auto;
            margin-left: 20px;
        }
        
        #colorList .name.#colorList .value.#colorList .colors {
            display: inline-block;
            width: 100px;
            height: 30px;
            overflow: hidden;
            box-sizing: border-box;
        }
    </style>
    <script src="lib/vue.js"></script>
    <script src="lib/jq.js"></script>
    <script src="layer/layer.js"></script>
</head>

<body>


    <div class="left">
        <canvas id="canvas" width="600" height="400"></canvas>
        <br>
        <br>
        <div class="fileWrap">
            <input type="file" onchange="selectImg(this)">
        </div>

        <br>
        <div id="color"></div>
        <br>

        <form id="form">
            <input type="text" id="name" placeholder="Color name" autocomplete="off">
            <input type="text" id="value" oninput="realTimeShowColor(this.value)" placeholder="Color value (RGB and hexadecimal can be used)" autocomplete="off">
            <button type="button" onclick="insertColor()">Save color value</button>
            <div id="realTimeShowColorId"></div>
        </form>

    </div>


    <div class="right">
        <div id="colorList">
            <h2>Color contrast (click on color value to copy)</h2>
            <div>
                <span class="name">Color name</span>
                <span class="value">Color value</span>
                <span class="colors">Color effect</span>
            </div>
            <div v-for="color in colors">
                <span class="name" @click="copyColorValue">{{color.name}}</span>
                <span class="value" @click="copyColorValue">{{color.value}}</span>
                <span :style="'background:'+ color.value" class="colors"></span>
            </div>
        </div>
    </div>


    <script>
        var alert = layer.msg; // Override the browser's own alert
        var canvas = document.getElementById('canvas');
        var realTimeShowColorId = document.getElementById('realTimeShowColorId')
        var canvasW = canvas.width;
        var canvasH = canvas.height;
        var ctx = canvas.getContext('2d');
        var isSelectImg = false;
        // Match RGB or hexadecimal, RGB color values greater than 255 will be treated as 255, so more specific matching or judgment will not be done for the time being
        var regExp = / (^ (RGB \ [(\ d {1, 3}, {2} {1, 3} \ \ d)) $) | (^ (# [0-9 a - fA - F] {6}) $) | (^ (# [0-9 a - fA - F] {3}) $) /;


        function selectImg(that) {
            isSelectImg = true;
            // console.log("that: ", that);
            var file = that.files[0];
            // console.log(file);
            var reader = new FileReader();

            console.log("reader: ", reader);
            reader.readAsDataURL(file);

            reader.onload = (e) = > {
                var img = new Image();
                img.src = reader.result;
                img.onload = () = > {
                    // console.log("img.width, img.height: ", img.width, img.height);
                    ctx.clearRect(0.0, canvasW, canvasH);
                    if (img.width < canvasW && img.height < canvasH) {
                        canvas.height = canvasH;
                        ctx.drawImage(img, 0.0, img.width, img.height);
                    } else {
                        canvas.height = canvasW * img.height / img.width; // Keep the image in shape
                        ctx.drawImage(img, 0.0, canvasW, canvas.height); }}}}function insertColor() {
            var name = document.getElementById('name').value
            var value = document.getElementById('value').value

            if(! name) { alert('Color name cannot be empty')
                return;
            }

            value = value.replace(/\s/g.' '); // Remove whitespace
            if(! regExp.test(value)) { alert('Incorrect color input')
                return;
            }

            $.ajax({
                type: 'post'.url: '/insertColor'.data: {
                    name: name,
                    value: value
                },
                success(d) {
                    // console.log("d: ", d);
                    getAllColor();
                    document.forms[0].reset();
                    alert('Added successfully')}}}var vm = new Vue({
            el: '#colorList'.data: {
                colors: []},methods: {
                copyColorValue(e) {
                    console.log("that: ", e.target.textContent);
                    var input = document.createElement('input');
                    input.value = e.target.textContent;
                    document.body.appendChild(input)
                    input.select();
                    document.execCommand("copy");
                    input.remove();
                    alert('Copy successful ~')}},created() {
                // document.addEventListener('mousemove', function (e) {
                // console.log("e: ", e);
                // })}})function getAllColor() {
            $.ajax({
                url: '/getAllColor'.success(d) {
                    // console.log("getAllColor: ", d);
                    vm.colors = d;
                }
            })
        }
        getAllColor();



        // RGB to Hex
        function colorRGBtoHex(color) {
            if (/(^(*(RGB)\((*\d{1,3} *,){2} *\d{1,3} *\)) *$)/.test(color)) {
                var rgb = color.split(', ');
                var r = parseInt(rgb[0].split('(') [1]);
                var g = parseInt(rgb[1]);
                var b = parseInt(rgb[2].split(') ') [0]);
                var hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
                return hex;
            }
            return color;
        }


        function toolTip() {
            let tooltipElem, timer;
            let color = document.getElementById('color');
            document.onmouseover = function(e) {
                var target = e.target;

                if(! isSelectImg)return;
                if(target.tagName ! = ='CANVAS') {
                    return;
                }
                tooltipElem = document.createElement('div');
                tooltipElem.className = "tooltip";
                document.body.append(tooltipElem);

                document.onmousemove = function(e) {
                    tooltipElem.style.left = e.clientX + 'px';
                    tooltipElem.style.top = e.clientY + 'px';

                    var x = e.layerX;
                    var y = e.layerY;
                    var pixel = ctx.getImageData(x, y, 1.1);
                    // console.log("pixel: ", pixel);
                    var data = pixel.data;
                    var rgb =
                        'rgb(' + data[0] +
                        ', ' + data[1] +
                        ', ' + data[2] +
                        // ',' + (data[3] / 255) + // rgba changed to RGB
                        ') ';
                    color.style.background = rgb;
                    color.textContent = rgb;
                    tooltipElem.innerHTML = rgb;
                    tooltipElem.style.background = rgb;
                    // console.log("rgb: ", rgb);



                    // console.log(vm.colors);
                    let currentElemColor = colorRGBtoHex(rgb);
                    let colors = vm.colors;
                    clearInterval(timer);
                    timer = setTimeout(function() {
                        for (let i = 0; i < colors.length; i++) {
                            var hex = colorRGBtoHex(colors[i].value)
                                // console.log("hex: ", hex);
                                // console.log("colorRGBtoHex(rgb): ", colorRGBtoHex(rgb));
                            if (hex === currentElemColor) {
                                color.textContent = colors[i].name;
                                tooltipElem.innerHTML = colors[i].name;
                                break; }}},100)}};document.onmouseout = function() {
                if (tooltipElem) {
                    tooltipElem.remove();
                    tooltipElem = null;
                }
                document.onmousemove = null;
                clearInterval(timer)
            }
        }
        toolTip();


        function realTimeShowColor(value) {
            // console.log("value: ", value);
            value = value.replace(/\s/g.' '); // Remove whitespace
            if(! value) { realTimeShowColorId.style.background ='transparent'
                realTimeShowColorId.textContent = ' '
                return;
            }
            if (regExp.test(value)) {
                realTimeShowColorId.style.background = value
                realTimeShowColorId.textContent = 'Color effects'
            } else {
                realTimeShowColorId.style.background = 'transparent'
                realTimeShowColorId.textContent = 'Incorrect color value'}}</script>
</body>

</html>
Copy the code