2011-10-13 10 views
7

Questo è legato alla CSS codici colore:Come i browser gestiscono rgb (percentuale); per strani numeri

Per hexcode possiamo rappresentare 16.777.216 colori da # 000000 a #FFFFFF

Secondo W3C Spec, percentuali RGB validi si inseriscono in un range da (0,0% al 100,0%) essenzialmente dandoti 1,003,003,001 combinazioni di colori. (1001^3)

Secondo le specifiche:

valori al di fuori della gamma dispositivo devono essere tagliate o mappata nel gamut quando la gamma è nota: i valori di rosso, verde e blu devono essere modificato per rientrare nell'intervallo supportato da il dispositivo. Gli agenti degli utenti possono eseguire una mappatura dei colori di qualità superiore da una gamma all'altra . Per un tipico monitor CRT, la cui gamma di dispositivo è lo stesso di sRGB, le quattro regole di seguito sono equivalenti:

Sono dubbioso se i browser in realtà possono rendere tutti questi valori. (ma se lo fanno per favore dimmi e ignora il resto di questo post)

Suppongo che ci sia qualche mappatura da rgb (percentuale) a esadecimale. (Ma ancora una volta Im non realmente sicuro di come funziona questo)

Idealmente mi piacerebbe scoprire la funzione rgb (in percentuale) -> HEX

Se dovessi indovinare sarebbe probabilmente uno di questi 3.

1) rotonda alla HEX più vicino

2) CEIL alla HEX più vicino

3) FLOOR alla HEX più vicino

il problema è che ho bisogno di essere precisi sulla mappatura e non ho idea di dove cercare. Non c'è modo in cui i miei occhi possano differenziare il colore a quel livello, ma forse c'è un modo intelligente per testare ognuno di questi 3.

Potrebbe anche dipendere dal browser. Questo può essere testato?

EDIT:

Firefox seems to round from empirical testing. 

EDIT:

sto guardando attraverso il codice sorgente di Firefox in questo momento,

nsColor.h 
// A color is a 32 bit unsigned integer with four components: R, G, B 
// and A. 
typedef PRUint32 nscolor; 

Sembra Fiefox ha spazio solo per 255 valori per ogni R, G e B. Accenno che l'arrotondamento potrebbe essere la risposta, ma forse qualcosa che viene fatto con il canale alfa.

+3

Se non riesci a distinguere tra '# 000000' e' # 000001', perché hai bisogno della formula esatta? Anche un modo tortuoso di test sarebbe quello di visualizzare un blocco del colore, premere Print Screen e utilizzare lo strumento eyedropper di un programma di grafica per scoprire il valore esadecimale risultante. – Toomai

+0

Sto lavorando su un tipo di parser, immagino, ovviamente l'utente finale non dovrebbe essere in grado di distinguere tra # 000000 e # 000001, ma il codice deve essere equivalente su tutti gli account. Mi piace l'idea del eyedropper come primo passo, grazie! – Ray

+0

Se la specifica non specifica una mappatura, quindi mi aspetto che dipenda dal browser, o almeno se non dipende dal browser, quindi è solo una coincidenza che non lo sia. Immagino che finché sei coerente, sei il più preciso possibile. Hai controllato con firebug o alcuni di questi sullo stile calcolato per vedere come va a finire? – jswolf19

risposta

1

Credo di avere trovato una soluzione per Firefox in ogni modo, pensavo ti avrebbe fatto piacere un follow-up:

Guardando attraverso il codice sorgente ho trovato un file:

nsCSSParser.cpp

Per ogni rgb percentuali esegue le seguenti operazioni:

  1. Si prende il componente percentuale moltiplica per 255.0f
  2. memorizza in un galleggiante
  3. passa in una funzione NSToIntRound
  4. Il risultato di NSToIntRound viene memorizzato in un tipo di dati intero a 8 bit, prima che sia combinato con gli altri 2 componenti e un canale alfa

alla ricerca di maggiori dettagli su NSToIntRound:

nsCoord.h 
inline PRInt32 NSToIntRound(float aValue) 
{ 
    return NS_lroundf(aValue); 
} 

NSToIntRound è una funzione wrapper per NS_lroundf

nsMathUtils.h 
inline NS_HIDDEN_(PRInt32) NS_lroundf(float x) 
{ 
    return x >= 0.0f ? PRInt32(x + 0.5f) : PRInt32(x - 0.5f); 
} 

Questa funzione è in realtà molto intelligente, mi ha portato un po 'per decifrare (non lo faccio hanno davvero un buon background in C++).

Supponendo x è positivo

aggiunge 0.5f a x e poi getta in un numero intero

Se la parte frazionaria di x è inferiore a 0,5, aggiungendo 0,5 non cambierà l'intero e l'frazionaria parte viene troncata,

In caso contrario, il valore intero viene urtato di 1 e la parte frazionaria viene troncata.

  1. Quindi la percentuale di ciascun componente viene prima moltiplicato per 255.0f
  2. Poi arrotondato e gettati in un intero a 32 bit
  3. E poi gettato di nuovo in un intero a 8 bit

Sono d'accordo con la maggior parte delle tu che dici che questo sembra essere un problema dipendente dal browser, quindi farò qualche ulteriore ricerca su altri browser.

Grazie mille!

Problemi correlati