2011-01-10 24 views
9

Recentemente mi sono imbattuto in un grafico a colori .NET in base al loro valore di tonalità e luminosità. Ciò che mi ha colpito è il folle grafico in scala di grigi. Ad esempio, DarkGray è in realtà più leggero di Gray? Inoltre, non riesco a vedere alcuna logica nella gradazione dei valori rgb, va da 0 a 105 a 128?Creazione di una classe GrayScaleBrushes

0 : Black 
105 : DimGray 
128 : Gray 
169 : DarkGray! 
192 : Silver 
211 : LightGray 
220 : Gainsboro 
245 : Ghostwhite 
255 : White 

http://sites.google.com/site/cdeveloperresources/

color chart - see link above

Quello che voglio è una classe GrayScaleBrushes che si comporta esattamente come la classe Brushes, ma con il mio schema personalizzato, come:

GrayScaleBrushes.Pct05 
GrayScaleBrushes.Pct10 
GrayScaleBrushes.Pct15 
..all the way to.Pct95 
... 
ie: e.FillRectangle(GrayScaleBrushes.Pct05, exampleRect); 

come fare quello, assicurandosi che i pennelli si dispongano correttamente?

Modifica: La classe .NET Brushes ha il seguente aspetto (disassemblata mediante riflettore).

public sealed class Brushes 
{ 
    // Fields 
    private static readonly object AliceBlueKey = new object(); 

    // Methods 
    private Brushes() 
    { 
    } 

    // Properties 
    public static Brush AliceBlue 
    { 
     get 
     { 
      Brush brush = (Brush) SafeNativeMethods.Gdip.ThreadData[AliceBlueKey]; 
      if (brush == null) 
      { 
       brush = new SolidBrush(Color.AliceBlue); 
       SafeNativeMethods.Gdip.ThreadData[AliceBlueKey] = brush; 
      } 
      return brush; 
     } 
    } 
} 

SafeNativeMethods sembra inaccessibile per me. Supponiamo che abbia appena restituito un SolidBrush in un metodo statico, che avrebbe risolto il problema? (E come testare questo?)

public sealed class GrayScaleBrushes 
{ 
    private static SolidBrush pct05 = null; 

    public static SolidBrush Pct05 
    { 
     get 
     { 
      if (pct05 == null) 
      { 
       int rgbVal = GetRgbValFromPct(5); 
       pct05 = new SolidBrush(Color.FromArgb(rgbVal, rgbVal, rgbVal)); 
      } 
      return pct05; 
     } 
    } 

    private static int GetRgbValFromPct(int pct) 
    { 
     return 255 - (int)(((float)pct/100f) * 255f); 
    } 
} 
+8

Per il motivo 'DarkGray> Gray', vedere Wikipedia: http://en.wikipedia.org/wiki/X11_color_names#Color_names_that_clash_between_X11_and_HTML.2FCSS –

risposta

1

Il SafeNativeMethods è in questo caso solo una semplice cache che contiene una copia del pennello. Quindi una seconda chiamata al getter della proprietà non creerà una nuova istanza. Invece restituirà sempre lo stesso pennello.

per raggiungere questo obiettivo si potrebbe riscrivere la funzione forse in questo modo:

public static class GrayScaleBrushes 
{ 
    private static SolidBrush _Pct05; 

    public static SolidBrush Pct05 
    { 
     get 
     { 
      if (_Pct05 == null) 
      { 
       var value = GetRgbValFromPct(5); 
       _Pct05 = new SolidBrush(Color.FromArgb(value, value, value)); 
      } 

      return _Pct05; 
     } 
    } 

    private static int GetRgbValFromPct(int pct) 
    { 
     // no need to convert to float and back to int again 
     return 255 - ((pct * 255)/100); 
    } 
} 

Questa soluzione creerà le scale di grigio in base alle esigenze, ma dai costi di controllo per il null ogni volta che viene chiamato. È possibile ottenere questo problema velocità cambiando di nuovo un problema memoria adottando un approccio come questo:

public static class GrayScaleBrushes 
{ 
    public static readonly SolidBrush Pct05; 

    static GrayScaleBrushes() 
    { 
     var value = GetRgbValFromPct(5); 
     Pct05 = new SolidBrush(Color.FromArgb(value, value, value)); 
    } 
} 

ma credo che in questo caso è solo una questione di gusto, causa né la velocità né la la memoria sarà un vero problema in entrambi i casi.

1

La classe Brushes è statico non può che perdere un piccolo numero di risorse corrispondenti al numero di colori definiti in modo da lasciare solo quelle risorse essere puliti all'uscita applicazione. Invece ti preoccupi di assicurarti che i tuoi pennelli non siano effettivamente creati a meno che non siano referenziati. Ciò velocizzerà l'avvio e assicurerà che i colori non utilizzati non consumino risorse.

1

mi sento di raccomandare il seguente:

Crea un GrayScaleBrushes classe statica

Creare una statica Dizionario con la percentuale di intensità (int) come la chiave,

Creare una singola statica indicizzato proprietà ' Pct 'che useresti come GrayScaleBrushes.Pct [10] che restituirebbe la voce del dizionario.

Ora si può fare come ha detto Oliver e creare le voci del dizionario al volo come vengono chiamate, oppure è possibile utilizzare un costruttore statico per scorrere tra le 20 voci e aggiungerle al dizionario.

Questo metodo vi eviterà di dover creare e mantenere le 20 proprietà dispari. Saluti.

Problemi correlati