Conteo de colores, ordenados por ocurrencias

14

Este es simple de describir y apenas podía creer que esto no se hubiera jugado antes:

Para una imagen determinada (cualquier formato que sea compatible con su idioma), busque los colores únicos y envíe una lista de los colores.

  • Imprima el código de color en RGB hexadecimal, que es un signo hash #seguido de 2 dígitos para R, 2 dígitos para G y 2 dígitos para B. ( #xxxxxxdonde x puede ser 0-9, AF y / o af).
  • El código hexadecimal irá seguido de un espacio y el recuento de píxeles decimales, luego una nueva línea ( \no \r\n).
  • La lista se ordenará por conteo descendente (el color más frecuente en la parte superior).
  • Si hay un empate (dos colores con la misma cantidad), el orden no es importante.
  • La imagen no contendrá transparencia, por lo que cualquier valor alfa no es importante. El valor alfa puede no ser parte de la salida.
  • Se debe admitir un tamaño de imagen de 4000x3000 (que puede ser importante para escribir definiciones)

Imagen de muestra "10red 20blue 30black 40white": Imagen de muestra 1

Rendimiento esperado:

#FFFFFF 40
#000000 30
#0000FF 20
#FF0000 10

Imagen de muestra "gradiente azul": Imagen de muestra 2

Una de las salidas esperadas (ya que el orden de los mismos colores puede variar):

#718DFF 19
#5571FF 15
#3855FF 11
#8DAAFF 11
#1C38FF 7
#AAAAFF 7
#8D8DFF 6
#AAC6FF 6
#C6C6FF 5
#C6E2FF 4
#001CFF 3
#E2E2FF 3
#FFFFFF 3

Imagen de muestra "testImage", amablemente proporcionada por @Luis Mendo :

Imagen de muestra 3

Rendimiento esperado:

#FFFFFF 18042
#000000 1754
#FF3300 204

Similar a esta pregunta , pero el resultado es texto, no una imagen.

Thomas Weller
fuente
count descendingEs un poco confuso. ¿Cómo lo solucionamos?
Rɪᴋᴇʀ
@ EᴀsᴛᴇʀʟʏIʀᴋ: descendente: color más frecuente en la parte superior
Thomas Weller
Bien, diría que eso tiene que ser un poco más claro. Tal vez decir algo como the most frequent colors at the top?
Rɪᴋᴇʀ
@ EᴀsᴛᴇʀʟʏIʀᴋ: Estoy de acuerdo, acabo de actualizar la pregunta para ambos
Thomas Weller,
1
Un par de casos de prueba sería bueno.
Martin Ender

Respuestas:

4

Mathematica, 91 bytes

StringRiffle@SortBy[Tally["#"<>IntegerString[#,16,2]&/@Join@@#~ImageData~"Byte"],-Last@#&]&

Utiliza un método completamente diferente de la respuesta de @ DavidC . A diferencia de ese, esto puede admitir imágenes con cualquier tamaño y color. Explicación:

#~ImageData~"Byte"                   Take the RGB values of the image...
Join@@(...)                          Flatten to a list of colors...
"#"<>IntegerString[#,16,2]&/@(...)   Convert each color to #012def format...
Tally[(...)]                         Convert to a list of {color, multiplicity}
                                      pairs (this does most of the work)...
SortBy[(...),-Last@#&]               Order by the multiplicity descending...
StringRiffle@(...)                   And create a string with the desired format.
LegionMammal978
fuente
Agradable. Me gusta cómo "Byte" devuelve los datos de la imagen.
DavidC
4

Bash + coreutils, 54

  • 7 bytes guardados gracias a @manatwork
grep -oE '#\w+'|sort|uniq -c|sort -nr|awk '$0=$2" "$1'

Esto supone la entrada STDIN del formato .txt de Imagemagick .

Ideona


Si el formato de entrada anterior es demasiado extenso, entonces podemos agregar la conversión de Imagemagick desde cualquier formato:

Bash + coreutils + Imagemagick, 71

convert $1 txt:-|grep -oE '#\w+'|sort|uniq -c|sort -nr|awk '$0=$2" "$1'

Aquí, el nombre de archivo de la imagen de entrada se pasa como un parámetro de línea de comandos.

Trauma digital
fuente
2
El OFS predeterminado de awk es un espacio, puede intercambiar `" "` por,
n0741337
1
O incluso más corta awkparte: awk '$0=$2" "$1'.
manatwork
3

JavaScript (ES6), 359 355 bytes

Guardado 4 bytes gracias a @Neil

u=>{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;i+=4)++o[s='#'+`00000${(d[i]<<16|d[i+1]<<8|d[i+2]).toString(16)} `.slice(-7)]?0:o[s]=1;Object.keys(o).sort((a,b)=>o[b]-o[a]).map(c=>console.log(c+o[c]))}}

Manifestación

f=u=>{i=new Image;i.crossOrigin='';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;i+=4)++o[s='#'+`00000${(d[i]<<16|d[i+1]<<8|d[i+2]).toString(16)} `.slice(-7)]?0:o[s]=1;Object.keys(o).sort((a,b)=>o[b]-o[a]).map(c=>console.log(c+o[c]))}}
f('http://i.imgur.com/acPudA9.gif')
<input value="https://i.imgur.com/acPudA9.gif" onchange="console.log('-------');f(this.value)">

Otros casos de prueba que cargué en imgur para admitir CORS:

Los datos de color específicos en estos dos parecen haber cambiado ligeramente al cargarlos por alguna razón, pero aún imprime la misma cantidad de ocurrencias para esos dos casos de prueba.

Patrick Roberts
fuente
Creo que |tiene menor prioridad que <<si lo usas en lugar de +eso, no necesitarás tantos ()s.
Neil
@ user2428118 la próxima vez agradecería si dejara dudas en un comentario y me pidiera que editara mi propia respuesta en lugar de editarla usted mismo. Realmente rompiste mi demo al eliminar <!-- language: lang-js -->del fragmento, deshabilitando efectivamente el JavaScript.
Patrick Roberts
@Patrick Lo siento, tendré más cuidado la próxima vez. Además, acabo de encontrar una manera de guardar algunos bytes:u=>{document.write`<img src=${u} id=i><canvas id=e>`;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;i+=4)++o[s='#'+`00000${(d[i]<<16|d[i+1]<<8|d[i+2]).toString(16)} `.slice(-7)]?0:o[s]=1;Object.keys(o).sort((a,b)=>o[b]-o[a]).map(c=>console.log(c+o[c]))}}
user2428118
2

Pyth , 29 bytes

jmj;_d_SrSm+\#.[\06.Hid256'Q8

Pruébalo en línea!

(El intérprete en línea no puede leer la imagen, por lo que eliminé esa parte e ingresé el resultado de la lectura de esa imagen, que es una lista de tripletes de colores. La parte responsable de leer la imagen es ' un solo colon).

Prueba de funcionalidad de 'un solo colon

Monja permeable
fuente
Necesita un santes 'Q, ya que una imagen se representa como una lista de listas de trillizos.
Jakube
Aquí hay una solución correcta (y más corta)V_SrS%L+\#*3"%02X"s'z8jd_N
Jakube el
2

Mathematica 103 92 bytes

{"#"<>IntegerString[255Round[List@@#],16,2],#2}&@@@DominantColors[#,9999,{"Color","Count"}]&

Ejemplo

Foto


Explicación

DominantColorsnormalmente devuelve una lista de colores y recuentos que representan los grupos principales en una imagen. Cuando el número de colores solicitados excede el número de colores en la imagen, se devuelven los colores de píxeles exactos. (Supongo que habrá menos de 10 000 colores en la imagen de entrada).

imagen


{"#"<>IntegerString[255Round[List@@#],16,2],#2} convierte los valores de color base 10 con valores hexadecimales.


Nota: solo hay 5 colores en la imagen del mandril. (Solía ColorQuantize[<image>,5]reducir la cantidad de colores en la imagen estándar del mandril).

DavidC
fuente
Acabo de jugar golf;)
LegionMammal978
Por un poquito. Pero su enfoque toma una cantidad ilimitada de colores.
DavidC
1

PowerShell v2 +, 187 bytes

$a=New-Object System.Drawing.Bitmap $args[0]
$b=@{}
0..($a.Height-1)|%{$h=$_;0..($a.Width-1)|%{$b["#"+-join($a.GetPixel($_,$h).Name[2..7])]++}}
$b.GetEnumerator()|Sort value -des|FT -h -a

Reutiliza casi todo el código de mi respuesta en Obtener el color más dominante . Por lo tanto, haga referencia a eso para obtener una explicación completa.

Los cambios aquí están en la indexación $ben la tercera línea para que coincida con los requisitos de formato de salida explícitas, y en la última línea que sortpor valueen -desorden cending, a continuación, canalizar a Format-Tablela -HideTableHeaders y-A utoSize como parámetros. Es muy raro usarlo realmente FTaquí en PPCG, ya que la salida está implícita al final de la ejecución, pero aquí es muy útil para garantizar que obtengamos solo la salida correcta de las partes.

Ejemplos

La primera es la imagen de prueba "roja" del desafío Color dominante, la segunda es la "imagen de prueba" de este desafío.

PS C:\Tools\Scripts\golfing> .\color-count.ps1 C:\Tools\Scripts\golfing\img\red.png

#ff0000 139876
#dcd9cf 3056  
#f2f1ed 1512  
#ffffff 1508  
#ffe6e6 1488  
#ffe3e3 8     
#eae8e2 4     
#fffbfb 4     


PS C:\Tools\Scripts\golfing> .\color-count.ps1 C:\Tools\Scripts\golfing\img\z07VA.gif

#ffffff 18042
#000000 1754 
#ff3300 204  
AdmBorkBork
fuente
1

Tcl / Tk , 134 bytes

console s
lmap s [concat {*}[[image c photo -fi $argv] d]] {dict inc D $s}
dict fo k\ v [lsort -int -s 2 -inde 1 -de $D] {puts $k\ $v}

des para data.

Tcl / Tk , 232 bytes

console s
set I [image c photo -fi $argv]
set i 0
time {set j 0
time {dict inc D #[join [lmap s [$I g $i $j] {format %02X $s}] ""]
incr j} [image h $I]
incr i} [image w $I]
dict fo k\ v [lsort -int -s 2 -inde 1 -de $D] {puts $k\ $v}

wish sort_pix.tcl QTE4O.png

ingrese la descripción de la imagen aquí


wish sort_pix.tcl 5s1Ob.png

ingrese la descripción de la imagen aquí


wish sort_pix.tcl z07VA.gif

ingrese la descripción de la imagen aquí

sergiol
fuente
1

Brain-Flak , 1110 bytes

{{}({}[(()()()()()){}])}{}(<>)<>([]){{}({}()<({}()<({}()<>)>)>)<>([])}{}<>{({}<({}<({}<(()()<>)>)>)>)<>{(<>)<>(()()()){({}[()]<<>({}<([([(({})<>[({})]<>)])]<>)<>{({}()<([{}])<>({}<>)<>>)<>}{}<>{}<>>{})({}<({}<({}<>)<>({}<>)<>({}<>)<>>)<>({}<>)<>({}<>)<>({}<>)>)<>({}<({}<>)<>({}<>)<>>)<>({}<>)<>({}<>)>)}{}<>((){[()](<{}>)}{})((){[()](<{}({}())<>{}{}{}>)}{}){{}(<<>(()()()){({}[()]<({}<(([])<{{}({}<>)<>([])}{}<>>)<>>)<>{({}[()]<({}<>)<>>)}{}<>>)}{}>)}{}<>({}<({}<>)<>({}<>)<>({}<>)<>>)<>({}<>)<>({}<>)<>({}<>)<>}({}<(([])<{{}({}<>)<>([])}{}<>>)<>>)<>{({}[()]<({}<>)<>>)}{}(()()()()){((({}[()])<{({}[()]<({}<({}<>)<>>)>)}{}>)<{({}[()]<<>({}<>)>)}{}>)}{}<>}{}<>(()()()())([][()])({}(<>))<>([()]{()<(({})){({}[()])<>}{}>}{}<><{}{}>){({}[()]<(<(()()()())([][()])({}(<>))><>([()]{()<(({})){({}[()])<>}{}>}{}<><{}{}>)<{({}[()]<([([({}<({}<({}<({}<(({})<>)<>>)>)>)>)<><({}<>)>]{}<(())>)](<>)){({}())<>}{}({}<><{}{}>){{}<>(<({}<({}<({}<({}<({}<({}<({}<({}<>)>)>)>)<>>)>)>)>)<>({}<({}<({}<({}<<>>)>)>)>)>)}{}({}<({}<({}<({}<>)>)>)>)<>>)}{}<>{}{}{}{}>[()]){({}[()]<({}<({}<({}<({}<>)>)>)>)<>>)}{}<>>)}{}{({}[()]<>)<>}<>

Pruébalo en línea!

Bueno, eso fue una aventura. Resulta que Brain-Flak no es muy bueno en el procesamiento de imágenes. ¿Quien sabe?

Comenzaré señalando que esto técnicamente no cumple con el formato de salida estricto solicitado. Si quiere que se cumpla, hágamelo saber e intentaré agregar el código de traducción. Por ahora genera números decimales: cada 4 números representa un color en el orden ROJO VERDE AZUL CONTEO.

A continuación, entrada. Los formatos de entrada permitidos eran más flexibles, por lo que utilicé el formato más fácil para que Brain-Flak analizara (que pude encontrar): Netpbm P6. Desafortunadamente, Brain-Flak no pudo analizar los números decimales del formato P3 porque todas las imágenes de Netpbm comienzan con el carácter Py Brain-Flak no puede manejar la entrada decimal de archivos que contienen caracteres no numéricos. Por lo tanto, se usó P6, porque P6 almacena información de color como bytes, que se tratan como números en el modo de entrada ASCII. Quedaba un desafío porque el estándar requería la información del encabezado, por lo que las entradas son archivos Netpbm válidos. no codificada de manera útil, pero afortunadamente no necesitaba ninguna de esa información, por lo que simplemente se descarta. Este programa no se adhiere completamente al estándar Netpbm porque no permite líneas nuevas dentro del encabezado, pero las líneas nuevas no son

Última advertencia, la versión en TIO en realidad no está configurada correctamente para la operación "oficial" porque (que yo sepa) no puedo suministrar archivos como entrada en TIO, ni podría suministrar bytes correspondientes a ASCII no imprimible en la entrada directa. Para la operación oficial, el -aindicador es necesario para tomar la entrada como bytes sin procesar y -fpara tomar la entrada de un archivo. En cambio, la entrada de muestra en el enlace TIO se tradujo manualmente del ejemplo en la página wiki de Netpbm .

Además, me gustaría agradecer al wiki de Brain-Flak por proporcionar fragmentos útiles de código para trabajar. En particular, la implementación de Bubble-Sort aquí fue instrumental para el paso final una vez que obtuve un recuento para cada color, ya que realmente no tenía idea de por dónde empezar. Se requirió una gran modificación, pero me alegro de no tener que comenzar desde cero.

Aquí está la versión no codificada y comentada del código. Brain-Flak es demasiado detallado para incluir una explicación formateada de manera útil en esta publicación, pero la versión no protegida de TIO contiene todo lo que incluiría en uno con mejor formato del que podría manejar aquí, así que si está interesado, tome un Mira.

Puede que todavía haya golf por hacer, mi respuesta anterior de Brain-Flak pasó por muchas revisiones, pero espero que las lecciones aprendidas allí le hayan dado un mejor punto de partida.

Kamil Drakari
fuente
0

Python 2, 186 bytes

import Image
I=Image.open(input()).convert('RGB')
w,h=I.size
r=['#'+('%0.2X'*3)%I.getpixel((i%w,i/h))for i in range(w*h)]
for a,b in sorted(set((r.count(v),v)for v in r))[::-1]:print b,a

Pruébalo en línea!

Descargo de responsabilidad: los resultados presentados son de una sola línea para facilitar la lectura. Las salidas de código resultan con separación de espacio y línea según lo solicitado por desafío.

Salida para 10red 20blue 30black 40white:

[('#FFFFFF', 40), ('#000000', 30), ('#0000FF', 20), ('#FF0000', 10)]

Salida para gradiente azul:

[('#718DFF', 19), ('#5571FF', 15), ('#8DAAFF', 11), ('#3855FF', 11), ('#AAAAFF', 7), ('#1C38FF', 7), ('#AAC6FF', 6), ('#8D8DFF', 6), ('#C6C6FF', 5), ('#C6E2FF', 4), ('#FFFFFF', 3), ('#E2E2FF', 3), ('#001CFF', 3)]

Salida para imagen de prueba

[('#FFFFFF', 18042), ('#000000', 1754), ('#FF3300', 204)]

Explicación:

w,h=I.size # field size stores tuple of values of width and height of image

I.getpixel((i%w,i/h)) # returns tuple of base10 RGB values

('%0.2X'*3) # format string to convert int into hex

set((r.count(v),v)for v in r) # generate set of unique pairs count-color 

sorted(set(...))[::-1] # apply sorted(), as it sorts set of tuples by firts elements and reverse sort

print b,a  # swap values in tuples and print
Zarigüeya muerta
fuente
0

Java (1.4+) , 483 428 bytes

import java.util.*;class I {public static void main(String[] a) throws Exception {java.awt.image.BufferedImage i = javax.imageio.ImageIO.read(new java.io.File(a[0]));Map m=new HashMap();String s;for(Integer x=0,y=0,c;y<i.getHeight();y++)for(x=0;x<i.getWidth();m.put(s=x.toHexString(((c=i.getRGB(x++,y))&0xff0000)>>16)+x.toHexString((c & 0xff00)>>8)+x.toHexString(c&0xff),m.get(s)==null?1:(int)m.get(s)+1));System.out.print(m);}}

Pruébalo en línea! (No funciona en línea)


Sin golf:

import java.util.*;

class I {
    public static void main(String[] a) throws Exception {
        java.awt.image.BufferedImage i = javax.imageio.ImageIO
                .read(new java.io.File(a[0]));
        Map m = new HashMap();
        String s;
        for (Integer x = 0, y = 0, c; y < i.getHeight(); y++)
            for (x = 0; x < i.getWidth(); m
                    .put(s = x.toHexString(((c = i.getRGB(x++, y)) & 0xff0000) >> 16)
                            + x.toHexString((c & 0xff00) >> 8)
                            + x.toHexString(c & 0xff), m.get(s) == null ? 1
                            : (int) m.get(s) + 1))
                ;
        System.out.print(m);
    }
}

La toString()salida del mapa es así:

{7c7c7c=6, 1d57a5=20468, 121212=7, d3d3d3=3, bdbdbd=9, 949494=2, 333=14, 626262=3, cacaca=2, 141414=5, fff=11, c9c9c9=1, e8e8e8=1, 919191=4, 161616=5, c2c2c2=1, 646464=7, 979797=12, fafafa=2, 808080=1, 7b7b7b=1, 484848=4, b9b9b9=2, f1f1f1=2, 6b6b6b=6, 363636=15, 262626=4, d8d8d8=2, 868686=4, 757575=1, 575757=3, a7a7a7=2, cecece=2, dcdcdc=2, c3c3c3=2, 1d1d1d=5, 727272=9, 656565=2, 3a3a3a=3, 7d7d7d=10, 393939=5, 797979=3, 222=31, 8f8f8f=2, 454545=4, 181818=9, 2e2e2e=2, 222222=1, 1c1c1c=19, b8b8b8=2, e1e1e1=5, 232323=5, 8a8a8a=3, 959595=7, 6a6a6a=9, 434343=7, 5c5c5c=3, 111=20, 909090=3, 424242=4, 212121=1, 1a1a1a=6, 202020=7, efefef=1, 565656=5, 6e6e6e=7, 767676=3, 323232=2, eee=5, 444=18, 2c62ab=1, 717171=2, b1b1b1=3, 6c6c6c=3, 545454=7, 515151=17, 2f2f2f=2, 4a4a4a=3, 888888=6, 6d6d6d=3, 898989=3, a3a3a3=5, 7e7e7e=9, ddd=9, b6b6b6=3, 2b2b2b=5, 313131=5, 8d8d8d=1, a2a2a2=2, 696969=3, a5a5a5=3, 4f4f4f=5, 828282=7, 191919=5, 606060=4, 6f6f6f=4, 8b8b8b=3, ebebeb=2, 555=19, 929292=3, 131313=11, 999999=5, d2d2d2=2, 444444=9, 474747=4, dddddd=1, 585858=8, 5a5a5a=3, 000=9887, afafaf=2, dfdfdf=3, 747474=3, 666666=4, a1a1a1=4, 2a2a2a=11, 4d4d4d=6, 818181=2, 878787=5, 215aa6=1, d9d9d9=4, b5b5b5=3, b4b4b4=3, 737373=4, aeaeae=3, bbb=15, 242424=4, 2d2d2d=8, 888=19, c1c1c1=1, 494949=9, dbdbdb=5, ccc=19, 5d5d5d=3, 5f5f5f=1, 414141=6, c8c8c8=3, aaa=16, 1e1e1e=3, 707070=2, 9e9e9e=2, 373737=7, 9d9d9d=2, 1b1b1b=4, 303030=7, 535353=10, 595959=2, 8e8e8e=3, 383838=5, 939393=18, 616161=2, 686868=6, dadada=1, e3e3e3=2, 5b5b5b=3, a4a4a4=5, 8c8c8c=5, a6a6a6=11, 292929=6, 4c4c4c=3, 151515=6, fefefe=2, 787878=2, 505050=2, e2e2e2=1, 1f1f1f=9, adadad=2, ababab=1, 5e5e5e=6, 252525=4, 4e4e4e=3, 282828=7, a8a8a8=4, 9c9c9c=3, aaaaaa=1, 101010=5, b7b7b7=2, 969696=6, 7f7f7f=4, 555555=2, a9a9a9=5, 343434=8, 999=17, 777777=3, ffffff=76669, f0f0f0=4, bbbbbb=1, 1e58a5=1, b3b3b3=4, 777=20, 636363=2, d4d4d4=1, 2c2c2c=5, 848484=1, 3c3c3c=3, bfbfbf=2, 3e3e3e=9, 333333=4, 7a7a7a=3, 858585=4, 4b4b4b=3, 272727=7, 111111=6, 666=13, 9b9b9b=1, bcbcbc=4, cfcfcf=2, 9a9a9a=1, 404040=21, 525252=3, 989898=4, 171717=5, 3b3b3b=2, c4c4c4=1, 3f3f3f=7, 464646=1, cdcdcd=2, b2b2b2=33, c5c5c5=2, bababa=2}

No publique 1.8 sugerencias de golf específicas, a menos que funcione en Java más antiguo, no quiero.

Ejemplo: Lambdas no funciona en más versiones de Java de las que funcionan.

Urna de pulpo mágico
fuente
" Por favor, no publique 1.8 sugerencias de golf específicas, a menos que funcione en Java anterior, no quiero " . Por curiosidad: ¿por qué Java 4 mientras Java 10 ya está disponible?
Kevin Cruijssen
Algunos campos de golf que deberían funcionar en Java 4 (creo): import java.util.*;class M{public static void main(String[]a)throws Exception{java.awt.image.BufferedImage i=javax.imageio.ImageIO.read(new java.io.File(a[0]));Map m=new HashMap();String s;for(Integer x=0,y=0,c;y<i.getHeight();y++)for(x=0;x<i.getWidth();m.put(s=x.toHexString((c&0xff0000)>>16)+x.toHexString((c&0xff00)>>8)+x.toHexString(c&0xff),m.get(s)==null?1:(int)m.get(s)+1))c=i.getRGB(x++,y);System.out.print(m);}}( 419 bytes )
Kevin Cruijssen
@KevinCruijssen Debido a que 1.8 fue, posiblemente, la mayor versión en términos de código que no se ejecutará con versiones anteriores. La mayoría de los otros lanzamientos fueron correcciones y adiciones de clases al JRE. 1.8 fue el menos compatible con los JRE anteriores.
Magic Octopus Urn
@KevinCruijssen x.toHexInteger fue más inteligente que una importación estática.
Magic Octopus Urn
Tampoco Java 3, ya que Java 3 ... de verdad ... tiene tan pocos atajos ...
Magia pulpo Urna
0

SmileBASIC, 165 bytes

DEF C A
L=LEN(A)DIM C[L],N[L]FOR J=0TO L-1FOR I=0TO U-1ON A[J]-C[I]GOTO@L
NEXT
U=U+1@L
C[I]=A[J]INC N[I]NEXT
RSORT.,U,N,C
FOR I=0TO U-1?"#";HEX$(C[I],6),N[I]NEXT
END

La imagen se proporciona como una matriz de valores de color ARGB de 32 bits (el valor alfa se recorta cuando el número se convierte en una cadena hexadecimal de 6 dígitos)

12Me21
fuente