JavaScript (ES6), 383 377 354 bayt
f=s=>{d=document,i=new Image,i.src=s,i.onload=$=>{c=d.createElement`canvas`,x=c.getContext`2d`,c.width=w=i.width,c.height=h=i.height,x.drawImage(i,0,0),D=x.getImageData(0,0,w,h),t=D.data,t.set([].concat(...[...t].map((v,i,T)=>i%4?[,,,0]:T.slice(i,i+4)).sort((a,b)=>a.some((v,i)=>k=v-b[i])&&k)).slice(12*w*h)),x.putImageData(D,0,0),d.body.appendChild(c)}}
Çalıştırılabilir demo:
f=function(s) {l=[i=new Image].slice,i.crossOrigin="anonymous",i.src=s,i.onload=function($){d=document,c=d.createElement`canvas`,c.width=w=i.width,c.height=h=i.height,x=c.getContext`2d`,x.drawImage(i,0,0),D=x.getImageData(0,0,w,h),t=D.data,t.set([].concat.apply([],l.call(t).map((v,i)=>i%4?[0,0,0,0]:l.call(t,i,i+4)).sort((a,b)=>a.reduce((A,v,i)=>A||v-b[i],0))).slice(3*t.length)),x.putImageData(D,0,0),d.body.appendChild(c)}}
$("img").click(function() { f(this.src); })
canvas { padding-right: 4px; } img { cursor: pointer; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f4/The_Scream.jpg/114px-The_Scream.jpg"> <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/6/67/Claude_Monet_La_Grenouill%C3%A9re.jpg/193px-Claude_Monet_La_Grenouill%C3%A9re.jpg"> <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/cc/Grant_Wood_-_American_Gothic_-_Google_Art_Project.jpg/120px-Grant_Wood_-_American_Gothic_-_Google_Art_Project.jpg"><br>
Bu kod nasıl çalışır getImageData
formun bir dizisini almak için kullanmaktır
[R,G,B,A,
R,G,B,A,
R,G,B,A,
...]
Ve map
bu bir form dizisine
[[R,G,B,A],[0,0,0,0],[0,0,0,0],[0,0,0,0],
[R,G,B,A],[0,0,0,0],[0,0,0,0],[0,0,0,0],
[R,G,B,A],[0,0,0,0],[0,0,0,0],[0,0,0,0],
...]
Böylece R değerleri, RGBA kümesinin dizilerine eşlenir ve B, G ve A değerleri minimum değer sıfır dizilerine dönüşür. Bu diziyi sıraladığımızda, tüm [0,0,0,0]
diziler en alt seviyeye, gerçek değer dizileri ise en üstte sıralanır:
[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],
[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],
[0,0,0,0],..., [R,G,B,A],[R,G,B,A],[R,G,B,A],...]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
extract & flatten these sorted pixels
Dizinin ilk dördüncü kısmını gözden geçiririz (yarattığımız boş değerleri kaybetmek için), onu düzleştirir [].concat.apply
ve ilk formun bir dizisini tekrar buluruz , ancak bu sefer sıralanır.
Boşluk ve yorumlarla hafifçe çözüldü:
f=s=>{
// first, load image, then do everything else onload
i=new Image,
i.src = s,
i.onload=$=>{
// set up the canvas
d=document,
c=d.createElement`canvas`,
w=c.width=i.width,
h=c.height=i.height,
x=c.getContext`2d`,
// draw image to canvas and capture pixel data
x.drawImage(i,0,0),
D=x.getImageData(0,0,w,h),
t=D.data,
// set pixel data to...
t.set(
// the flattened array...
[].concat(...
// that is a mapping of the pixel data...
[...t].map(
// that clumps RGBA families into subarrays
// by replacing every fourth value with [R,G,B,A]
// and all other values to [0,0,0,0]...
(v,i,T)=>i%4?[,,,0]:T.slice(i,i+4)
)
// and is then sorted...
.sort(
// by reducing each array to a positive, negative, or zero
// by comparing R,G,B,& A until the first nonzero difference
(a,b)=>a.some((v,i)=>k=v-b[i])&&k
)
)
// then eliminate the low-sorted empty [0,0,0,0] values we created,
// leaving only the top fourth, with real values
// (note that 3*4*w*h is the same as 3*t.length)
.slice(3*4*w*h)
),
// now that `t` is set, store `D` in canvas
x.putImageData(D,0,0),
// show canvas
d.body.appendChild(c)
}
}
Tarayıcıların çoğu bu görüntüyü büyük resimler için çalıştırmakta başarısız olabilir, çünkü çok sayıda argüman iletir [].concat
. Tarayıcı ortamı tüm argümanlar için yeterli belleğe izin vermediğinde, alternatif bir yaklaşım, toplam 361 baytlık bir skor için, RGBA değerlerini ilk dördüncü dizilerden tekrar diziye yeniden eşlemektir :
f=s=>{d=document,i=new Image,i.src=s,i.onload=$=>{c=d.createElement`canvas`,x=c.getContext`2d`,c.width=w=i.width,c.height=h=i.height,x.drawImage(i,0,0),D=x.getImageData(0,0,w,h),t=D.data,t.set([...t].map((v,i,T)=>i%4?[,,,0]:T.slice(i,i+4)).sort((a,b)=>a.some((v,i)=>k=v-b[i])&&k).map((v,i,A)=>A[3*w*h+(i>>2)][i%4])),x.putImageData(D,0,0),d.body.appendChild(c)}}
Biz sadece yerine [].concat(...{stuff}).slice(12*w*h)
sahip {stuff}.map((v,i,A)=>A[3*w*h+(i>>2)][i%4])
.)