JavaScript eyedropper (скажите цвет пикселя под курсором мыши)

Я ищу "пипетка" инструмент, который дает мне шестнадцатеричное значение пикселя, под которым находится курсор мыши, в JavaScript для CMS.

для Firefox есть отличный ColorZilla расширение, которое делает именно это. Тем не менее, это FF только, конечно, и я бы очень хотел поставить инструмент вместе с CMS.

голландский разработчик имел очень умная идея использования комбинация Ajax и PHP imagecolorat() узнать цвет пикселя на изображении. но это ограничивает диапазон изображений, к которым я могу получить доступ на стороне сервера, и я действительно мечтаю о универсальном инструменте.

Я буду работать с одним из этих подходов, но предпочел бы кросс-браузер, Javascript или Flash-способ, который не требует серверной скрипки и установки расширений.

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

9 ответов


это невозможно с JavaScript, поскольку это противоречит междоменной безопасности. Было бы очень плохо, если бы вы знали, какие пиксели составляют изображение,http://some-other-host/yourPassword.png. Вы можете только сказать цвет пикселя под мышью, если мышь находится над холстом или элементом изображения того же домена (или элементом изображения другого домена, который обслуживается с Access-Control-Allow-Origin: * заголовок). В случае с холстом вы бы сделали canvasElement.getContext('2d').getImageData(x, y, 1, 1).data. В случае изображений вам придется нарисовать их на холсте с:

var canvas = document.createElement("canvas");
canvas.width = yourImageElement.width;
canvas.height = yourImageElement.height;
canvas.getContext('2d').drawImage(yourImageElement, 0, 0);

а затем просто используйте предыдущий метод, объясненный для холстов. Если вы должны иметь возможность конвертировать в различные представления значений цвета, попробуйте my цвета.js библиотека.

кроме того, вы никогда не сможете поддерживать IE


используя метод под названием Браузер Синхронизации Атаки, можно (вроде) определить цвет любого пикселя, даже на фреймы.

в принципе, этот метод измеряет время отображения SVG-фильтра на элементе, а не самого цвета (requestAnimationFrame() позволяет измерять время с гораздо большей точностью, чем setTimeout()). В зависимости от текущего цвета пикселя фильтр требует больше или меньше времени для применения. Это позволяет определить, является ли пиксель тот же цвет, что и известный цвет - например, черный или белый.

подробнее в этой Белой книге (pdf):http://www.contextis.com/documents/2/Browser_Timing_Attacks.pdf

кстати: да, это дыра в безопасности браузера, но я не вижу, как поставщики браузеров могут ее исправить.


объединение различных ссылок, найденных здесь в 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> над изображением, это тоже возможно. Надеюсь, я помог.


Я согласен с очень подробным ответом Ильи. Кроме того, я бы сказал, что вам не нужен холст, когда дело доходит до изображений. Как вы сами заявили, у вас есть эти изображения, доступные из php, и вы можете выполнить цветовой запрос на сервере.

Я бы предложил вам решить эту проблему с помощью внешнего инструмента - это делает его даже независимым от браузера (но зависимым от ОС): напишите небольшой инструмент (например, в c#) , который выполняет запрос цвета для вас, вызывается с помощью ярлыка и отправляет цвет на ваш сервер. Сделайте инструмент доступным для загрузки на вашей CMS.

еще один пример, который я использовал для CMS, был "украсть" цвета, проанализировав CSS: прецедент состоял в том, чтобы сделать цвета уже существующего веб-сайта доступными в качестве цветовой палитры для моего приложения:

  • Я попросил пользователя предоставить URL-адрес из целевой системы-в основном домашняя страница компании
  • Я проанализировал страницу, чтобы найти все определения цвета во всех встроенные стили и связанные стили
  • (вы можете легко расширить это на все ссылочные изображения)
  • в результате была хорошая цветовая палитра со всеми цветами coporate на выбор

может быть, это также решение для вашей CMS?


Я не знаю, возможно ли это, но если ваши страницы статичны, вы можете сохранить скриншот изображения каждого из них (или, может быть, один для каждого разрешения браузера/экрана? ) а затем используйте AJAX для отправки координат курсора на сервер и возврата цвета пикселя с помощью PHP imagecolorat().

чтобы сделать скриншоты, вы можете использовать селен IDE как описано здесь.

надеюсь, что это помогает.


добавить к предыдущим ответам --

один из способов мышления этой проблемы заключается в том, что вы хотите иметь возможность делать захват экрана 1px по 1px области. Довольно распространенный метод захвата областей экрана (например, из веб-систем отчетов об ошибках)-использование подписанного Java-апплета и java.ОУ.Робот для захвата изображения. Если вы подпишете апплет, ваши пользователи получат диалоговое окно " доверяете ли вы этому приложению "(с флажком " всегда доверяйте приложениям от этого издателя) а потом сможете пользоваться инструментом.

затем вы можете передать результат JavaScript с помощью LiveConnect (документы старые, но Java-апплеты все еще поддерживают это), или вы можете опубликовать его на своем сервере. Аналогично, вы можете вызвать апплет Java из JavaScript.


см. новый элемент ввода [type=color] HTML5:http://www.w3.org/TR/html-markup/input.color.html, http://demo.hongkiat.com/html5-form-input-type/index2.html.

теперь он работает по крайней мере в Chrome (протестирован в Ubuntu, должен работать и для Windows). Он запускает диалог выбора цвета обеспечивается операционной системой. Если в этом диалоговом окне есть пипетка (это для Gnome), то можно выбрать цвет из любой точки на вашем экран. Еще не кросс-браузер, но чистый и основанный на стандартах.


в качестве меры предосторожности вы не можете захватывать пиксели экрана с помощью Javascript (поэтому разработчики не могут делать снимки ваших личных данных), но вы можете сделать это во Flash-вы можете получить пиксельные данные в контейнере Flash с помощью flash.дисплей.класс BitmapData.

проверить http://www.sephiroth.it/tutorials/flashPHP/print_screen/ -- я использовал его в проектах Wysywig на основе Flash для сохранения изображений на сервере LAMP (PHP).

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

метод на основе холста, безусловно, будет хорошим при условии, что все ваши посетители имеют современные веб-браузеры, которые поддерживают тег canvas и JavaScript.


нет встроенного метода DOM для общего получения цвета элемента DOM (кроме изображений или <canvas>) в определенном месте пикселя.

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

используя HTML2Canvas (версия 0.5.0-beta3) вы можете сделать что-то вроде этого:--3-->

// Take "screenshot" using HTML2Canvas
var screenshotCanvas,
    screenshotCtx,
    timeBetweenRuns = 10,
    lastTime = Date.now();
function getScreenshot() {
    // Limit how soon this can be ran again
    var currTime = Date.now();
    if(currTime - lastTime > timeBetweenRuns) {
        html2canvas(document.body).then(function(canvas) {
            screenshotCanvas = canvas;
            screenshotCtx = screenshotCanvas.getContext('2d');
        });
        lastTime = currTime;
    }
}
setTimeout(function() { // Assure the initial capture is done
    getScreenshot();
}, 100);

// Get the user's click location
document.onclick = function(event) {
    var x = event.pageX,
        y = event.pageY;

    // Look what color the pixel at the screenshot is
    console.log(screenshotCtx.getImageData(x, y, 1, 1).data);
}


// Update the screenshot when the window changes size
window.onresize = getScreenshot;

демо