Created
June 9, 2011 19:42
-
-
Save nmaier/1017533 to your computer and use it in GitHub Desktop.
Dominant FavIcon color, see dominantColor_opt; optimized processing + IMO better results on black/gray; requires chrome privs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<style type="text/css"> | |
body { | |
-moz-column-count: 4; | |
} | |
</style> | |
<script type="text/javascript;version=1.8"> | |
function getDominantColor(aImg) { | |
let canvas = document.createElement("canvas"); | |
canvas.height = aImg.height; | |
canvas.width = aImg.width; | |
let context = canvas.getContext("2d"); | |
context.drawImage(aImg, 0, 0); | |
// keep track of how many times a color appears in the image | |
let colorCount = {}; | |
let maxCount = 0; | |
let dominantColor = ""; | |
// data is an array of a series of 4 one-byte values representing the rgba values of each pixel | |
let data = context.getImageData(0, 0, aImg.height, aImg.width).data; | |
for (let i = 0; i < data.length; i += 4) { | |
// ignore transparent pixels | |
if (data[i+3] == 0) | |
continue; | |
let color = data[i] + "," + data[i+1] + "," + data[i+2]; | |
// ignore white | |
if (color == "255,255,255") | |
continue; | |
colorCount[color] = colorCount[color] ? colorCount[color] + 1 : 1; | |
// keep track of the color that appears the most times | |
if (colorCount[color] > maxCount) { | |
maxCount = colorCount[color]; | |
dominantColor = color; | |
} | |
} | |
let rgb = dominantColor.split(","); | |
return rgb; | |
} | |
function getDominantColor_opt(aImg) { | |
let canvas = document.createElement("canvas"); | |
canvas.height = aImg.height; | |
canvas.width = aImg.width; | |
let context = canvas.getContext("2d"); | |
context.drawImage(aImg, 0, 0); | |
// keep track of how many times a color appears in the image | |
let colorCount = {}; | |
let maxCount = 0; | |
let dominantColor = 0; | |
// data is an array of a series of 4 one-byte values representing the rgba values of each pixel | |
let data = context.getImageData(0, 0, aImg.height, aImg.width).data; | |
let cc, color, r, b, g, a; | |
for (let i = 0, e = data.length; i < e;) { | |
r = data[i++]; | |
g = data[i++]; | |
b = data[i++]; | |
a = data[i++]; | |
// transparent | |
if (a < 10) { | |
continue; | |
} | |
// bright | |
if (r < 10 && g < 10 && b < 10) { | |
continue; | |
} | |
// dark | |
if (r > 250 && g > 250 && b > 250) { | |
continue; | |
} | |
// gray | |
if (Math.abs(r - g) < 10 && Math.abs(g - b) < 10 && Math.abs(r - b) < 10) { | |
continue; | |
} | |
color = (r << 16) + (g << 8) + b; | |
cc = colorCount[color] = colorCount[color] + 1 || 1; | |
// keep track of the color that appears the most times | |
if (cc > maxCount) { | |
maxCount = cc; | |
dominantColor = color; | |
} | |
} | |
return dominantColor ? [dominantColor >> 16, (dominantColor >> 8) & 255, dominantColor & 255] : [128, 128, 128]; | |
} | |
function bench(func, iterations, aImg) { | |
Components.utils.forceGC(); | |
// precompile | |
for (let i = 0; i < 2; ++i) { | |
func(aImg); | |
} | |
// run | |
let s = new Date().getTime(); | |
for (let i = 0; i < iterations; ++i) { | |
func(aImg); | |
} | |
let e = new Date().getTime(); | |
console.log(func.name, func(aImg), s, e, (e - s) + "ms", ((e - s) / iterations).toFixed(4) + "ms"); | |
Components.utils.forceGC(); | |
return ((e - s) / iterations); | |
} | |
let known = {}; | |
function putImage() { | |
let [rgb_ref, rgb_opt] = [ | |
getDominantColor(this), | |
getDominantColor_opt(this) | |
].map(function(e) e.join(",")); | |
let div = document.createElement("div"); | |
div.style.margin = "1ex"; | |
div.style.padding = "1ex"; | |
if (rgb_ref != rgb_opt) { | |
div.style.borderLeft = "2px solid red"; | |
} | |
else { | |
div.style.borderLeft = "2px solid transparent"; | |
} | |
for each (let rgb in [rgb_ref, rgb_opt]) { | |
let img = this.cloneNode(false); | |
img.style.padding = "6px"; | |
img.style.margin = "2ex"; | |
img.style.background = "-moz-linear-gradient(rgba(" + rgb + ",0.15), rgba(" + rgb + ",0.33))"; | |
img.style.border = "1px solid rgb(" + rgb + ")"; | |
img.style.borderRadius = "5px"; | |
img.setAttribute("alt", rgb); | |
img.setAttribute("title", rgb); | |
div.appendChild(img); | |
} | |
document.body.appendChild(div); | |
} | |
let iterations = 100; | |
let imgs = ["https://tn123.org/favicon.ico", | |
"https://bugzilla.mozilla.org/extensions/BMO/web/images/bugzilla.png", | |
"http://www.facebook.com/favicon.ico", | |
"http://twitter.com/favicon.ico", | |
"http://mail.google.com/favicon.ico", | |
"http://google.com/favicon.ico", | |
"http://vbulletin.com/favicon.ico", | |
"http://dailymile.com/favicon.ico", | |
"http://getfirebug.com/img/favicon.ico", | |
"https://github.com/favicon.ico", | |
"http://mozilla.com/favicon.ico", | |
"http://mozilla.org/favicon.ico", | |
"http://mozillalabs.com/wp-content/themes/labs2.0/favicon.png", | |
"https://static-cdn.addons.mozilla.net/media/img/favicon.ico", | |
"http://mozdev.org/favicon.ico", | |
"http://en.wikipedia.org/favicon.ico", | |
"http://www.google.com/images/icons/product/chrome-16.png", | |
"http://www.opera.com/favicon.ico", | |
"http://www.microsoft.com/favicon.ico", | |
"http://yahoo.com/favicon.ico", | |
"http://baidu.com/favicon.ico", | |
"http://www.volkswagen.com/favicon.ico", | |
"http://www.quibblo.com/favicon.ico", | |
"http://sstatic.net/stackoverflow/img/favicon.ico", | |
]; | |
// top sites | |
imgs = imgs.concat(['http://Domain/favicon.ico', 'http://facebook.com/favicon.ico', 'http://youtube.com/favicon.ico', 'http://live.com/favicon.ico', 'http://baidu.com/favicon.ico', 'http://blogspot.com/favicon.ico', 'http://wikipedia.org/favicon.ico', 'http://qq.com/favicon.ico', 'http://twitter.com/favicon.ico', 'http://msn.com/favicon.ico', 'http://yahoo.co.jp/favicon.ico', 'http://taobao.com/favicon.ico', 'http://amazon.com/favicon.ico', 'http://sina.com.cn/favicon.ico', 'http://linkedin.com/favicon.ico', 'http://bing.com/favicon.ico', 'http://wordpress.com/favicon.ico', 'http://ebay.com/favicon.ico', 'http://yandex.ru/favicon.ico', 'http://microsoft.com/favicon.ico', 'http://163.com/favicon.ico', 'http://paypal.com/favicon.ico', 'http://mail.ru/favicon.ico', 'http://fc2.com/favicon.ico', 'http://flickr.com/favicon.ico', 'http://imdb.com/favicon.ico', 'http://vkontakte.ru/favicon.ico', 'http://craigslist.org/favicon.ico', 'http://apple.com/favicon.ico', 'http://bbc.co.uk/favicon.ico', 'http://sohu.com/favicon.ico', 'http://livejasmin.com/favicon.ico', 'http://go.com/favicon.ico', 'http://conduit.com/favicon.ico', 'http://youku.com/favicon.ico', 'http://tudou.com/favicon.ico', 'http://soso.com/favicon.ico', 'http://ask.com/favicon.ico', 'http://aol.com/favicon.ico', 'http://xvideos.com/favicon.ico', 'http://cnn.com/favicon.ico', 'http://hotfile.com/favicon.ico', 'http://megaupload.com/favicon.ico', 'http://xhamster.com/favicon.ico', 'http://mediafire.com/favicon.ico', 'http://pornhub.com/favicon.ico', 'http://myspace.com/favicon.ico', 'http://tumblr.com/favicon.ico', 'http://espn.go.com/favicon.ico', 'http://godaddy.com/favicon.ico', 'http://adobe.com/favicon.ico', 'http://about.com/favicon.ico', 'http://ameblo.jp/favicon.ico', 'http://4shared.com/favicon.ico', 'http://zedo.com/favicon.ico', 'http://rakuten.co.jp/favicon.ico', 'http://livejournal.com/favicon.ico', 'http://ebay.de/favicon.ico', 'http://orkut.com.br/favicon.ico', 'http://doubleclick.com/favicon.ico', 'http://youporn.com/favicon.ico', 'http://wordpress.org/favicon.ico', 'http://ifeng.com/favicon.ico', 'http://yieldmanager.com/favicon.ico', 'http://cnet.com/favicon.ico', 'http://uol.com.br/favicon.ico', 'http://thepiratebay.org/favicon.ico', 'http://livedoor.com/favicon.ico', 'http://sogou.com/favicon.ico', 'http://rapidshare.com/favicon.ico', 'http://imageshack.us/favicon.ico', 'http://nytimes.com/favicon.ico', 'http://amazon.de/favicon.ico', 'http://alibaba.com/favicon.ico', 'http://weather.com/favicon.ico', 'http://megavideo.com/favicon.ico', 'http://ezinearticles.com/favicon.ico', 'http://netflix.com/favicon.ico', 'http://ebay.co.uk/favicon.ico', 'http://mozilla.com/favicon.ico', 'http://ehow.com/favicon.ico']); | |
let img = new Image(); | |
img.onload = function() { | |
let ref = bench(getDominantColor, iterations, this); | |
let opt = bench(getDominantColor_opt, iterations, this); | |
console.log(ref.toFixed(3), "vs", opt.toFixed(3), ((ref - opt) * 100.0 / ref).toFixed(2) + "%"); | |
for each (let i in imgs) { | |
let img = new Image(); | |
img.onload = putImage; | |
img.src = i; | |
} | |
} | |
img.src = imgs[0]; | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment