There is a picture, I want to determine the predominant color on it. Or how it is done in Yandex. Dzena

enter image description here

As you can see, where the text is superimposed on it there is a color that covers the image so that the text is clearly visible, the color (background) under the text is always different, I noticed that it depends on the image.

How to do this using css or jquery?

  • Did not look towards the finished packages? - Alexandr Tovmach
  • @AlexandrTovmach and they already have? :) - iKey
  • npmjs.com/package/fast-average-color . To google more in this direction npm average color , there are several packages - Alexandr Tovmach
  • Do you pull the content from somewhere, or publish it? - teran
  • there is still such a solution lokeshdhakar.com/projects/color-thief - Vladimir

1 answer 1

I used the function from this example for the exact same task.

http://jsfiddle.net/xLF38/818/

 function getAverageRGB(imgEl) { var blockSize = 5, // only visit every 5 pixels defaultRGB = {r:0,g:0,b:0}, // for non-supporting envs canvas = document.createElement('canvas'), context = canvas.getContext && canvas.getContext('2d'), data, width, height, i = -4, length, rgb = {r:0,g:0,b:0}, count = 0; if (!context) { return defaultRGB; } height = canvas.height = imgEl.naturalHeight || imgEl.offsetHeight || imgEl.height; width = canvas.width = imgEl.naturalWidth || imgEl.offsetWidth || imgEl.width; context.drawImage(imgEl, 0, 0); try { data = context.getImageData(0, 0, width, height); } catch(e) { /* security error, img on diff domain */ return defaultRGB; } length = data.data.length; while ( (i += blockSize * 4) < length ) { ++count; rgb.r += data.data[i]; rgb.g += data.data[i+1]; rgb.b += data.data[i+2]; } // ~~ used to floor values rgb.r = ~~(rgb.r/count); rgb.g = ~~(rgb.g/count); rgb.b = ~~(rgb.b/count); return rgb; } //ВЫЗОВ var rgb = getAverageRGB(document.getElementById('img')); document.body.style.backgroundColor = 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')'; 

There is a nuance, it works only for images that pull up from the same domain. The code has a comment security error, img on diff domain . If anyone knows how to cure it - correct my answer.

In practice, it is also necessary to select the text color for the base color, at least in the context of dark to light and light to dark.

  • 1. About security error, img on diff domain - use images from a domain, for example /img.png or base64 code. 2. Regarding the "contrast", if the "strict" (black, white), then here is the condition color = (r > 127 || g > 127 || b > 127) ? 'black' : 'white'; color = (r > 127 || g > 127 || b > 127) ? 'black' : 'white'; - CbIPoK2513
  • one
    Based on this answer, I wrote thisCbIPoK2513
  • one
    @ CbIPoK2513 is a great example. I offer only a slightly more accurate formula for contrast color = (r * 299 + g * 587 + b * 114) / 1000) > 127 ? 'black' : 'white'; color = (r * 299 + g * 587 + b * 114) / 1000) > 127 ? 'black' : 'white'; it takes into account that the channels have different perceptions of brightness. - Talleyran