Passa ai contenuti principali

Briciole di WPF: Ma quanti colori vuoi?!?!?

Questa briciola è dedicata alla structure Color presente nel namespace System.Windows.Media.

Di fatto si tratta della nuova struttura di colore introdotta da WPF che viene utilizzata dal presentation framework al posto della vecchia Color del namespace System.Drawing.

Ci sono due grandi differenze “esteriori” tra le due strutture.

La prima differenza è che la vecchia struttura può rappresentare 16.777.216 di colori essendo le sue componenti RGB rappresentate da 1 Byte ciascuno (256 possibili valori). Ogni terna di valori RGB ha, inoltre, 256 possibili valori di trasparenza.

La nuova struttura, invece, ha anche la possibilità di esprimere le componenti RGB (e Alfa) con dei valori di tipo Single (solo positivi o nulli) e, quindi, in linea teorica con un range di colori molto più ampio. La nuova struttura nasce con lo scopo di supportare lo standard scRGB (wiki docet).

La struttura Color di WPF mette ancora a disposizione dello sviluppatore le proprietà (A, R, G, B) che riportano il singolo canale espresso con un byte, ma forniscono anche delle proprietà (ScA, ScR, ScG, ScB) che esprimono le componenti del colore con dei valori di tipo Single.

I due insiemi di proprietà sono tra loro sincronizzati nel senso che se impostiamo uno dei canali “vecchi” otteniamo che il corrispondente canale “nuovo” ha il proprio valore aggiornato (con un valore tra 0 e 1. La conversione in questo verso avviene con una funzione di normalizzazione che possiamo ricavare utilizzando Reflector:

  1. Private Shared Function sRgbToScRgb(ByVal bval As Byte) As Single
  2.     Dim num As Single = (CSng(bval) / 255.0!)
  3.     If (num <= 0) Then
  4.         Return 0.0!
  5.     End If
  6.     If (num <= 0.04045) Then
  7.         Return (num / 12.92!)
  8.     End If
  9.     If (num < 1.0!) Then
  10.         Return CSng(Math.Pow(((num + 0.055) / 1.055), 2.4))
  11.     End If
  12.     Return 1.0!
  13. End Function

dove bval è il valore del canale “vecchio” e il ritorno della funzione è il valore del canale “nuovo”.

Quando impostiamo, invece, una delle proprietà dei nuovi canali, anche le corrispettive proprietà dei vecchi canali vengono aggiornate. Stavolta la funzione utilizzata per l’aggiornamento è la seguente:

  1. Private Shared Function ScRgbTosRgb(ByVal val As Single) As Byte
  2.     If (val <= 0) Then
  3.         Return 0
  4.     End If
  5.     If (val <= 0.0031308) Then
  6.         Return CByte((((255.0! * val) * 12.92!) + 0.5!))
  7.     End If
  8.     If (val < 1) Then
  9.         Return CByte(((255.0! * ((1.055! * CSng(Math.Pow(CDbl(val), 0.41666666666666669))) - 0.055!)) + 0.5!))
  10.     End If
  11.     Return 255
  12. End Function

In questo caso val è il valore del “nuovo” canale, mentre il ritorno della funzione è il valore del “vecchio” canale.

Altra differenza tra la nuova Color e la vecchia è che nella prima sono state rimosse le proprietà statiche che definivano i cosiddetti “colori noti” (ad esempio Color.Red). E’ stata, in questo senso, creata una nuova classe (interamente costituita da proprietà statiche ) Colors che contiene queste definizioni.

Se apriamo con Reflector la nuova structure Color osserviamo che anche il modo con cui internamente sono memorizzati i canali è cambiato.

Nella Color del namespace Drawing i canali sono memorizzati in un unico oggetto di tipo In64, mentre nella nuova structure abbiamo due strutture private ognuna delle quali ha 4 attributi (single o byte) che identificano i canali.

Commenti

Post popolari in questo blog

VB for Dummies: La serializzazione – parte 2

Questo post è la continuazione del precedente post sulla serializzazione. In particolare vedremo la serializzazione SOAP e quella JSON.   Serializzazione SOAP La serializzazione SOAP è demandata alla classe SOAPFormatter contenuta nel namespace System.Runtime.Serialization.Formatters.Soap contenuto nella libreria omonima. Il formatter SOAP risale alle primissime versioni del framework e, purtroppo, da un certo punto in poi, pur non essendo stato dichiarato obsoleto, non è stato portato avanti nello sviluppo e non supporta alcuni tipi di dati usatissimi nel mondo .NET quali i generici e i nullable. Per questo motivo, non possiamo serializzare in formato SOAP (utilizzando il SOAPFormatter) la nostra Fattura (vedi post precedente) poichè questa ha una proprietà di tipo List(Of DettagliFattura) (generico).   Serializzazione JSON Il formato di serializzazione JSON (maggiori info qui ) è un formato testuale molto in voga nelle applicazioni AJAX. Si trata di un mod...

Recensione: Windows Runtime via C#

Può sembrare strano che un VB-ista legga un libro su C#, ma come diceva Sun Tzu: “ Se conosci il tuo nemico, conosci te stesso ”. A parte gli scherzi, il libro vale la pena di essere letto a prescindere dal linguaggio .NET con cui si lavora. Oltre  290 pagine dedicate agli aspetti fondamentali dello sviluppo con Windows Runtime per le Windows Store App. I prerequisiti per poter leggere il libro sono la conoscenza di C# e di Visual Studio e gli autori non danno per scontato quasi nulla partendo dai concetti di base quali il type system e i suoi principi (argomento che di solito è saltato a piedi pari da chi si avvicina al mondo WinRT dal framework completo e che, se non compreso, può dare problemi nello sviluppo quotidiano). Tra i concetti che possiamo definire “core”, troviamo anche i capitoli dedicati all’app packaging e al process model, entrambi ben strutturati e chiari. Già solo questi tre capitoli iniziali giustificherebbero, in un certo qual modo, l’acquisto del libro, ...

VB.NET for Dummies: Gli Eventi

Vorrei iniziare con questo post una serie dedicata ad aspetti di VB.NET di base che possono essere utile a coloro che si avvicinano al mondo .NET e che, in genere, non vengono trattati a livello base. La serie di post non ha la pretesa di essere assolutamente esaustivi sugli argomenti che tratterò In questo primo post parleremo degli eventi. Cosa sono e a cosa servono Un evento è la “notifica” dell’accadimento di qualcosa. Quando, ad esempio, premiamo un bottone della finestra di un’applicazione, dietro le quinte, il bottone stesso “notifica” al mondo circostante che qualcuno, in quell’istante, lo ha premuto. Sta, poi, al mondo circostante preoccuparsi di “intercettare” l’evento stesso per gestirlo (tramite un gestore di evento). Attenzione a non confondere la pressione del tasto con la “notifica” della pressione del tasto: l’evento è la “notifica” dell’accadimento, non l’accadimento stesso. Ma a cosa serve tutto ciò? Utilizzare gli eventi è un modo per disaccoppiare ...