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

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

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

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

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

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

Ответ 1

Это невозможно с 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);

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

Кроме того, вы никогда не сможете поддерживать IE < 9 (предполагая, что IE9 поддерживает холст), а использование Flash не поможет, поскольку оно не может считывать данные пикселов документа.

Ответ 2

Объединяя различные ссылки, найденные здесь в 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

Используя технику, называемую Timer Attack Attack, можно (сортировать) определять цвет любого пикселя, даже на iframes.

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

Подробнее в этом техническом документе (pdf): http://www.contextis.com/documents/2/Browser_Timing_Attacks.pdf

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

Ответ 4

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

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

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

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

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

Ответ 5

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

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

Надеюсь, что это поможет.

Ответ 6

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

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

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

Ответ 7

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

Ответ 8

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

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

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

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

Ответ 9

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

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

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

// 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 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;

Демо