Conta-gotas de JavaScript (diga a cor do pixel sob o cursor do mouse)

Eu estou procurando uma ferramenta ” eyedropper “, que me dá o valor hexadecimal do pixel do cursor do mouse, em JavaScript para um CMS.

Para o Firefox, existe a excelente extensão do ColorZilla que faz exatamente isso. No entanto, é apenas FF, é claro, e eu realmente gostaria de entregar a ferramenta junto com o CMS.

Um desenvolvedor holandês teve a idéia muito inteligente de usar uma combinação de Ajax e imagecolorat() do PHP para descobrir a cor do Pixel em uma imagem. Mas isso limita o alcance das imagens que eu posso acessar do lado do servidor , e estou realmente sonhando com uma ferramenta universal.

Eu trabalharei com uma dessas abordagens, mas preferiria uma forma cross-browser, Javascript ou Flash que não requer nenhum trabalho do lado do servidor e nenhuma instalação de extensões.

Também estou interessado em qualquer solução específica do IE que faça o que o ColorZilla pode fazer – eu poderia viver apenas com suporte ao IE e ao FF, embora uma solução cross-browser seja, naturalmente, ideal.

Não é possível com JavaScript, pois vai contra a segurança entre domínios. Seria muito ruim se você soubesse quais pixels compunham a imagem, http://some-other-host/yourPassword.png . Você só pode informar a cor do pixel sob o mouse se o mouse estiver sobre uma canvas ou um elemento de imagem do mesmo domínio (ou um elemento de imagem de outro domínio que é servido com um Access-Control-Allow-Origin: * header). No caso da canvas, você faria canvasElement.getContext('2d').getImageData(x, y, 1, 1).data . No caso das imagens, você teria que desenhá-las em uma canvas com:

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

E então é só usar o método anterior explicado para canvass. Se você precisar converter em várias representações de valores de colors, tente minha biblioteca color.js .

Além disso, você nunca será capaz de suportar o IE <9 (assumindo que o IE9 suporta canvas) e usar o Flash não ajudará, já que ele não pode ler os dados de pixel do documento.

Usando uma técnica chamada Browser Timing Attack , é possível determinar a cor de qualquer pixel, mesmo em iframes.

Basicamente, essa técnica mede o tempo para renderizar um filtro SVG em um elemento, em vez da própria cor ( requestAnimationFrame() permite medir o tempo com uma precisão muito melhor que setTimeout() ). Dependendo da cor atual do pixel, o filtro demora mais ou menos tempo para ser aplicado. Isso permite determinar se um pixel é da mesma cor que uma cor conhecida – por exemplo, preto ou branco.

Mais detalhes neste white paper (pdf): http://www.contextis.com/documents/2/Browser_Timing_Attacks.pdf

A propósito: sim, essa é uma falha de segurança do navegador, mas não vejo como os fornecedores de navegadores podem corrigí-la.

Mesclando várias referências encontradas aqui no StackOverflow e em outros sites, eu fiz isso usando javascript e JQuery:

    Your browser does not support the canvas element.       

Esta é a minha solução completa. Aqui eu só usei canvas e uma imagem, mas se você precisar usar

sobre a imagem, também é possível. Espero ter ajudado.

Eu concordo com a resposta muito detalhada fornecida por Elias. Além disso, eu diria que você não precisa da canvas quando se trata de imagens. Como você mesmo afirmou, você tem essas imagens disponíveis no php e pode fazer a consulta de colors no servidor.

Eu sugiro que você lide com esse problema com uma ferramenta externa – isso torna mesmo navegador independente (mas dependente do sistema operacional): escrever uma pequena ferramenta (por exemplo em c #) que faz a consulta de colors para você, é invocada com um atalho e submete a cor para o seu servidor. Disponibilize a ferramenta como download no seu CMS.

Outra abordagem que usei para um CMS era “roubar” colors analisando o CSS: o caso de uso era para disponibilizar as colors de um site já existente como paleta de colors para meu aplicativo:

  • Pedi ao usuário para fornecer uma URL do sistema de destino – principalmente a home page da empresa
  • Analisei a página para encontrar todas as definições de colors em todos os estilos inline e estilos vinculados
  • (você pode facilmente estender isso para todas as imagens referenciadas)
  • o resultado foi uma paleta de colors agradável com todas as colors coporate para escolher

Talvez seja também uma solução para o seu CMS?

Não sei se isso é viável, mas se as suas páginas são estáticas você pode salvar uma captura de canvas de cada uma delas (ou talvez uma para cada navegador / resolução de canvas?) E usar o AJAX para enviar as coordenadas do cursor para o servidor e retornar a cor do pixel com o imagecolorat() do PHP.

Para tirar as capturas de canvas, você pode usar o Selenium IDE, como descrito aqui .

Espero que ajude.

Para adicionar as respostas anteriores –

Uma maneira de pensar sobre esse problema é que você deseja fazer uma captura de canvas de uma região de 1 px por 1 px. Uma técnica bastante comum para capturar regiões de canvas (por exemplo, dentro de sistemas de relatórios de bugs baseados na Web) é usar um applet Java assinado e java.awt.Robot para capturar a imagem. Se você assinar o applet, seus usuários receberão uma checkbox de diálogo “você confia neste aplicativo” (com a checkbox de seleção “sempre confiar nos apps deste editor”) e, em seguida, poderão usar a ferramenta.

Você pode então passar o resultado para o JavaScript usando o LiveConnect (os documentos são antigos, mas os applets Java ainda suportam isso), ou você pode publicá-lo em seu servidor. Da mesma forma, você pode chamar o applet Java do JavaScript.

Veja a nova input [type = color] Elemento HTML5: http://www.w3.org/TR/html-markup/input.color.html , http://demo.hongkiat.com/html5-form-input-type /index2.html .

Agora funciona pelo menos no Chrome (testado no Ubuntu, deve funcionar para o Windows também). Inicia o diálogo de seleção de colors fornecido pelo sistema operacional . Se houver um conta-gotas nessa checkbox de diálogo (é para o Gnome), é possível escolher uma cor em qualquer ponto da canvas . Não cross-browser ainda, mas limpo e baseado em padrões.

Como precaução de segurança, você não pode capturar pixels de canvas com Javascript (para que os desenvolvedores não possam tirar instantâneos de seus dados pessoais), mas você PODE fazê-lo no Flash – você pode obter dados de pixel no contêiner Flash usando o flash.display Classe .BitmapData.

Confira http://www.sephiroth.it/tutorials/flashPHP/print_screen/ – usei-o em projetos WYSYWIG baseados em Flash para salvar imagens em um servidor LAMP (PHP).

O problema com o uso do Flash é que ele não é suportado nativamente em dispositivos iOS, que são extremamente populares agora e merecem ser desenvolvidos. O flash está a caminho dos tubos.

O método baseado em canvas certamente será bom, desde que todos os visitantes tenham navegadores atualizados que suportem a tag da canvas e o JavaScript.

Não existe um método DOM para genericamente obter a cor de um elemento DOM (diferente de imagens ou um ) em um local de pixel específico.

Assim, para fazer isso, devemos usar algo como HTML2Canvas ou DOM Panda para obter uma “captura de canvas” do nosso site, obter o local do clique do usuário e obter a cor do pixel da “captura de canvas” naquele local específico.

Usando HTML2Canvas (versão 0.5.0-beta3) você pode fazer algo parecido com isto:

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

Demonstração