Get the most dominant color!
Pyth, 18 bytes
FGITW.
?tJeM.MhZrS'Q8\=hJ
This is how it would theoretically work offline.
This is a proof that it works.
The two links differ by whether there is a "read file command" '
(single-quote).
JavaScript (ES6), 301 328 312 bytes
(u,b)=>{i=new Image;i.src=u;e=document.createElement`canvas`;c=e.getContext`2d`;i.onload=_=>{w=e.width=i.width;h=e.height=i.height;c.drawImage(i,0,0);d=c.getImageData(0,0,w,h).data;for(o={},i=0;i<d.length;)++o[s=d.slice(i,i+=4)]?0:o[s]=1;b(o[(a=Object.keys(o).sort((a,b)=>o[b]-o[a]))[0]]==o[a[1]]?"Equal":a[0])}}
Feel free to golf further, this feels as long as Java to me personally.
This supports transparent images so alpha channel is included in output value.
The reason it's longer than before is because now that I've tested, it requires the arguments to Image
to contain the attribute crossOrigin
, andgetImageData()
are not optional.
See Meta PCG for removal of CORS from byte count.
Usage
f("http://i.imgur.com/H5OmRVh.jpg", alert)
That will asynchronously alert
a color quadruplet or "Equal" after the image is loaded and counted.
The callback is not considered part of the program length because it is allowed as input by the OP in this special case.
How it works
It constructs an Image
, a Canvas
, and a CanvasRenderingContext2D
, then draws the image to the canvas after setting its width
and height
correctly. It then counts occurrences of each color by implicitly converting each quadruplet to a string and generating a hash of counters. After that, it sorts the hash keys by descending count before comparing the highest two occurrences and determining whether to return the first quadruplet string in the sorted array or the string "Equal"
.
If the demo below displays a SecurityError
, the domain of the image URL you chose does not support CORS.
Demo
f = (u, b) => {
let i = new Image;
i.crossOrigin = ''; // CORS added for demo
i.src = u;
let e = document.createElement `canvas`;
let c = e.getContext `2d`;
i.onload = _ => {
w = e.width = i.width;
h = e.height = i.height;
c.drawImage(i, 0, 0);
d = c.getImageData(0, 0, w, h).data;
for (o = {}, i = 0; i < d.length;)
++o[s = d.slice(i, i += 4)] ? 0 : o[s] = 1;
b(o[(a = Object.keys(o).sort((a, b) => o[b] - o[a]))[0]] == o[a[1]] ? "Equal" : a[0])
}
}
l = i => {
let p = i.nextElementSibling;
p.src = i.value;
f(`http://crossorigin.me/${i.value}`, c => p.nextElementSibling.value = c);
}
document.getElementById `i`.addEventListener('update', e => {
l(e.target)
})
Array.prototype.slice.call(document.querySelectorAll`.i`, 0, 3).forEach(l)
input {
display: block;
box-sizing: border-box;
width: 205px;
height: 18px;
}
input.o {
position: relative;
top: -36px;
}
img {
display: block;
position: relative;
box-sizing: border-box;
top: -18px;
left: 209px;
height: 40px;
}
<input class=i disabled value="http://i.stack.imgur.com/rqsAX.png">
<img>
<input class=o disabled>
<input class=i disabled value="http://i.stack.imgur.com/KECpJ.png">
<img>
<input class=o disabled>
<input class=i disabled value="http://i.stack.imgur.com/DRCWd.png">
<img>
<input class=o disabled>
<input class=i id=i placeholder="Try any image!">
<img>
<input class=o id=o disabled>
MATL, 30 26 23 bytes
Save some bytes by using mode with explicit output specification 6#XM
.
2#YiwX:6#XMgY)tn3>?x'='
Previously (26 byte solution)
2#YiwX:S&Y'tX>=Y)tn3>?x'='
Doesn't work online, because of imread
. imread
can take a path or directly read a url.
Explanation:
2#Yi % read image, returns a matrix of colours, and a matrix
% that indexes each pixel to the corresponding row of the colour matrix
w % swap elements in stack
X: % linearize index matrix to column array
6#XMg % use mode to find most common colour indices, convert to matrix (g)
Y) % get corresponding rows of colour matrix
tn3> % duplicate and see if it has more than 3 elements
? % if there is more than one most common colour
x % delete most common colours from stack
'=' % push string onto stack
% implicitly finish loop and display stack contents
Output is, for the first image, 1 0 0
(RGB triple), for the second =
, and for the third, 1 1 1
. For example, a screenshot form Matlab:
Note that you need to escape string delimiters when running MATL code from the Matlab command window, hence the ''=''
. The >
indicates MATL is asking for user input, in this I gave it the URL of the first test case, and the result is 1 0 0
.