2009-04-08 5 views
31

Sto generando alcuni grafici che richiedono una stringa esadecimale per i colori.Come si crea una stringa esadecimale casuale che rappresenta un colore?

Esempio:

<dataseries name="ford" color="FF00FF" /> 

sto creando questi dinamicamente, così desidero generare il codice esadecimale per ogni dataseries casuale.

Qual è il modo migliore per farlo?

+0

Ho appena notato che il mio esempio non è venuto attraverso. Sto indovinando questo perché era una stringa xml ... Oh beh, non importava dal momento che la risposta ha funzionato alla grande. – rahkim

+1

@rahkim - domanda aggiornata per risolvere il problema e aggiunto un titolo più significativo –

risposta

94

Il modo più semplice è utilizzare String.Format e utilizzare il formato esadecimale per l'argomento.

var random = new Random(); 
var color = String.Format("#{0:X6}", random.Next(0x1000000)); // = "#A197B9" 
+2

+1 È così incredibilmente semplice, chiaro e veloce. –

+0

Lo so, per prima cosa ho iniziato a pensare all'utilizzo di un array e di elementi di selezione, quindi ricordo che String.Format può eseguire esadecimali. – Samuel

+2

Correggetemi se ho torto, ma con quel codice, non genererete mai il valore 0xFFFFFF poiché il numero intero che passate al metodo Next è il limite superiore non inclusivo. Quindi avresti bisogno di random.Next (0x1000000) in modo che venga restituito 0xFFFFFF. –

4
Random rand = new Random(); // specify a seed 
int r = rand.Next(0x1000000); 
Console.WriteLine("#{0:X6}", r); 
+1

Questo non gestisce valori bassi. 0x00FFFF diventa #FFFF che non è uguale a # 00FFFF. – Samuel

15

IMO, puramente colori casuali potrebbero non essere preferibile in quanto avete bisogno dei colori che sono distinguibili in occhi umani.

Che ne dici di preimpostare un numero di colori e selezionarli casualmente?

Forse potresti trovare risposte migliori in alcune librerie di grafici open source.

+0

Questo sarebbe il metodo preferito, ma forse l'OP ha altri motivi per colori completamente casuali. – Samuel

+0

Ho pensato a questo poiché alcuni colori potrebbero fondersi insieme. Non ero sicuro di quanti preset, dato che potrei avere un numero molto alto di serie. – rahkim

+0

Un ibrido di preset e random può aiutare. Presenta accuratamente circa 10 bei colori. Vai per caso se di più. In generale, gli occhi inesperti iniziano a confondersi in una carta troppo colorata, quindi quali colori esatti utilizzati non sono veramente importanti – Canton

12

La risposta di Samuel è il modo migliore per farlo, ma assicurati che se stai generando i colori all'interno di un loop non crei un nuovo oggetto Random ogni volta perché new Random() semina il generatore utilizzando l'orologio di sistema. Il tuo loop funzionerà più velocemente di quanto il clock possa spuntare, quindi finirai per generare più volte gli stessi colori perché random viene seminato con lo stesso valore.

Dovrebbe essere qualcosa di simile:

int numColors = 10; 
var colors = new List<string>(); 
var random = new Random(); // Make sure this is out of the loop! 
for (int i = 0; i < numColors; i++) 
{ 
    colors.Add(String.Format("#{0:X6}", random.Next(0x1000000))); 
} 

anziché:

int numColors = 10; 
var colors = new List<string>(); 
for (int i = 0; i < numColors; i++) 
{ 
    var random = new Random(); // Don't put this here! 
    colors.Add(String.Format("#{0:X6}", random.Next(0x1000000))); 
} 
+0

Buona lettura della mente! –

+1

Questo spiega perché rahkim ottiene colori casuali quando si utilizza un punto di interruzione. lol – Samuel

+0

Questo non mi è nemmeno passato per la testa. Stai aggiungendo i colori a un elenco per un motivo?Solo buone pratiche, o c'è qualcosa che mi manca? – rahkim

11

Un buon modo di generare un bel set di colori è definire utilizzando saturazione fisso e la luminosità e variare la tonalità.

  1. Imposta la saturazione e la luminosità su qualcosa che ti piace, ad esempio il 50% di saturazione e il 90% di luminosità.
  2. Ora dividere i 360 gradi di tonalità in base al numero di colori distinti desiderati.
  3. colori scegliere da HSV che utilizzano tale intervallo per la tonalità e la fissa S e V.

Questo vi dà un bel set di colori, che tutti sembrano sono venuti dalla stessa 'set' - tutto pastello, o tutto intenso, o tutto bianco sporco, qualunque cosa. Ed è piuttosto semplice codificarlo se hai Color.FromHSV().

Probabilmente smette di funzionare quando si ottengono troppi colori, ma saranno indistinguibili. Ma probabilmente avrai comunque il problema.

In pseudo-codice:

Sat = 0.5 * 255 //assuming we want range 0-255... 
Brightness = 0.9 * 255 
NumberOfColours = 7 
HueSeparation = 360/7 
Colors = [] 
for (i = 0 ; i< NumberOfColours; i++) 
    Colors.Add(Color.FromHSV(HueSeparation * i, Sat, Brightness) 

o

n = 7 
Colors = [Color.FromHSV(x*360/n, 128, 230) for x in range(n)] 

(mi piace list comprehension ...)

+0

Idea pulita. Vorrei poterlo inserire nel codice. ;-) – rahkim

3

Ho notato che tu (Rahkim) hai commentato sul post di Greg che desideri inserire la sua idea (mantenendo costante la saturazione e il valore e semplicemente variando la tonalità ... una buona idea) nel codice. Puoi! O, piuttosto, qualcuno ha già per te!

Ho trovato questo post sul blog Converting HSV to RGB colour using C#, e sono sicuro che ci sono più là fuori. Probabilmente otterrai una suite di colori più bella in questo modo piuttosto che scegliendoli in modo totalmente casuale.

Inoltre, naturalmente, questo metodo rende più semplice per ottenere un bel set di colori ... dal momento che la tonalità va 0-359, si potrebbe fare qualcosa di simile a impostare il Hue qualcosa di simile:

Hue = (PreviousHue + 50) % 360; 

(Ho scelto 50 poiché non va in 360 in modo uniforme, quindi se andate oltre 360 ​​non inizierete a ripetere le tonalità all'istante. Dovreste giocherellare con il valore per ottenere una separazione ideale a seconda di quanti diversi colori che ti aspetti)

In questo modo non devi preoccuparti del caso in cui il codice seleziona in modo casuale due colori che sono molto vicini a un altro lei quando c'è ancora molto spazio "hue" inutilizzato.

+0

Mi piace. Mi dà una certa flessibilità. – rahkim

Problemi correlati