Получить цвет пикселей с холста при наведении курсора - PullRequest
67 голосов
/ 18 июля 2011

Возможно ли получить пиксель значения RGB под мышью? Есть ли полный пример этого? Вот что у меня есть:

<script>
function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  var img = new Image();
  img.src = 'Your URL';

  img.onload = function(){
    ctx.drawImage(img,0,0);


  };

  canvas.onmousemove = function(e) {
        var mouseX, mouseY;

        if(e.offsetX) {
            mouseX = e.offsetX;
            mouseY = e.offsetY;
        }
        else if(e.layerX) {
            mouseX = e.layerX;
            mouseY = e.layerY;
        }
        var c = ctx.getImageData(mouseX, mouseY, 1, 1).data;

        $('#ttip').css({'left':mouseX+20, 'top':mouseY+20}).html(c[0]+'-'+c[1]+'-'+c[2]);
  };
}

</script>

Ответы [ 8 ]

129 голосов
/ 18 июля 2011

Вот полный, автономный пример. Сначала используйте следующий HTML-код:

<canvas id="example" width="200" height="60"></canvas>
<div id="status"></div>

Соответствующий JavaScript:

// set up some sample squares
var example = document.getElementById('example');
var context = example.getContext('2d');
context.fillStyle = "rgb(255,0,0)";
context.fillRect(0, 0, 50, 50);
context.fillStyle = "rgb(0,0,255)";
context.fillRect(55, 0, 50, 50);

$('#example').mousemove(function(e) {
    var pos = findPos(this);
    var x = e.pageX - pos.x;
    var y = e.pageY - pos.y;
    var coord = "x=" + x + ", y=" + y;
    var c = this.getContext('2d');
    var p = c.getImageData(x, y, 1, 1).data; 
    var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
    $('#status').html(coord + "<br>" + hex);
});

Приведенный выше код предполагает наличие jQuery и следующих служебных функций:

function findPos(obj) {
    var curleft = 0, curtop = 0;
    if (obj.offsetParent) {
        do {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
        } while (obj = obj.offsetParent);
        return { x: curleft, y: curtop };
    }
    return undefined;
}

function rgbToHex(r, g, b) {
    if (r > 255 || g > 255 || b > 255)
        throw "Invalid color component";
    return ((r << 16) | (g << 8) | b).toString(16);
}

Смотрите это в действии на JSFIDDLE:

7 голосов
/ 20 августа 2014

Я знаю, что это старый вопрос, но вот альтернатива.Я бы сохранил эти данные изображения в массиве, а затем при перемещении мыши по холсту:

var index = (Math.floor(y) * canvasWidth + Math.floor(x)) * 4
var r = data[index]
var g = data[index + 1]
var b = data[index + 2]
var a = data[index + 3]

Намного проще, чем получать imageData каждый раз.

5 голосов
/ 10 января 2012

Объединяя различные ссылки, найденные здесь, в StackOverflow (включая статью выше) и на других сайтах, я сделал это, используя javascript и JQuery:

<html>
<body>
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<script src="jquery.js"></script>
<script type="text/javascript">
    window.onload = function(){
        var canvas = document.getElementById('myCanvas');
        var context = canvas.getContext('2d');
        var img = new Image();
        img.src = 'photo_apple.jpg';
        context.drawImage(img, 0, 0);
    };

    function findPos(obj){
    var current_left = 0, current_top = 0;
    if (obj.offsetParent){
        do{
            current_left += obj.offsetLeft;
            current_top += obj.offsetTop;
        }while(obj = obj.offsetParent);
        return {x: current_left, y: current_top};
    }
    return undefined;
    }

    function rgbToHex(r, g, b){
    if (r > 255 || g > 255 || b > 255)
        throw "Invalid color component";
    return ((r << 16) | (g << 8) | b).toString(16);
    }

$('#myCanvas').click(function(e){
    var position = findPos(this);
    var x = e.pageX - position.x;
    var y = e.pageY - position.y;
    var coordinate = "x=" + x + ", y=" + y;
    var canvas = this.getContext('2d');
    var p = canvas.getImageData(x, y, 1, 1).data;
    var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
    alert("HEX: " + hex);
});
</script>
<img src="photo_apple.jpg"/>
</body>
</html>

Это моё полное решение. Здесь я использовал только холст и одно изображение, но если вам нужно использовать <map> поверх изображения, это тоже возможно.

3 голосов
/ 30 января 2017

вызов getImageData каждый раз замедляет процесс ... чтобы ускорить процесс, я рекомендую хранить данные изображения, а затем вы можете легко и быстро получить значение в пикселях, поэтому сделайте что-нибудь подобное для повышения производительности

// keep it global
let imgData = false;  // initially no image data we have

// create some function block 
if(imgData === false){   
  // fetch once canvas data     
  var ctx = canvas.getContext("2d");
  imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
}
    // Prepare your X Y coordinates which you will be fetching from your mouse loc
    let x = 100;   // 
    let y = 100;
    // locate index of current pixel
    let index = (y * imgData.width + x) * 4;

        let red = imgData.data[index];
        let green = imgData.data[index+1];
        let blue = imgData.data[index+2];
        let alpha = imgData.data[index+3];
   // Output
   console.log('pix x ' + x +' y '+y+ ' index '+index +' COLOR '+red+','+green+','+blue+','+alpha);
3 голосов
/ 15 апреля 2014

Быстрый ответ

context.getImageData(x, y, 1, 1).data; возвращает массив rgba.Например, [50, 50, 50, 255]


Вот версия функции @ lwburk rgbToHex, которая принимает массив rgba в качестве аргумента.

2 голосов
/ 01 апреля 2016

Вы можете попробовать color-sampler .Это простой способ выбрать цвет на холсте.См. демо .

1 голос
/ 01 января 2015

У меня есть очень простой рабочий пример получения цвета пикселей с холста.

Сначала немного базового HTML:

<canvas id="myCanvas" width="400" height="250" style="background:red;" onmouseover="echoColor(event)">
</canvas>

Затем JS, чтобы нарисовать что-то на холсте и получить цвет:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "black";
ctx.fillRect(10, 10, 50, 50);

function echoColor(e){
    var imgData = ctx.getImageData(e.pageX, e.pageX, 1, 1);
    red = imgData.data[0];
    green = imgData.data[1];
    blue = imgData.data[2];
    alpha = imgData.data[3];
    console.log(red + " " + green + " " + blue + " " + alpha);  
}

Вот рабочаяпример , просто посмотрите на консоль.

0 голосов
/ 06 марта 2019

@ Ответ Уэйна Беркетта - это хорошо.Если вы хотите также извлечь альфа-значение, чтобы получить цвет rgba, мы можем сделать это:

var r = p[0], g = p[1], b = p[2], a = p[3] / 255;
var rgba = "rgb(" + r + "," + g + "," + b + "," + a + ")";

Я разделил альфа-значение на 255, потому что объект ImageData хранит его как целое число от 0 до 255,но большинство приложений (например, CanvasRenderingContext2D.fillRect()) требуют, чтобы цвета были в допустимом формате CSS, где значение альфа находится в диапазоне от 0 до 1.

(Также помните, что если вы извлекаете прозрачный цвет, а затем рисуете егообратно на холст, он будет перекрывать любой ранее существовавший цвет, поэтому если вы нарисуете цвет rgba(0,0,0,0.1) поверх одного и того же пятна 10 раз, он будет черным.)

...