In questo secondo articolo vedremo come ottenere un display numerico a 7 segmenti (di una sola cifra).
La struttura dell'immagine GIF che utilizzeremo, in grandezza naturale e opportunamente ingrandita, e' la seguente:
E questi sono i codici dell'immagine visualizzati con un qualunque editor esadecimale:
La prima parte, di 13 bytes, contiene informazioni generali sull'immagine: tipo, versione, dimensioni, ecc.
La terza parte contiene altre informazioni, caratteri di controllo, e la codifica compressa LZW dei pixel dell'immagine.
La parte centrale, evidenziata in colore verde, contiene sedici gruppi di tre byte con le informazioni sui colori utilizzati dall'immagine (denominata Palette). In questa immagine sono stati utilizzati i 16 colori standard di windows (ci sono 16 gruppi di 3 bytes con le informazioni di colore). Per ogni colore sono riportate le quantita' di rosso, verde e giallo. In questo caso il primo gruppo (00 00 00) corrisponde al nero, il secondo (80 00 00) al rosso scuro, il terzo (00 80 00) al verde scuro, e cosi' via fino all'ultimo (FF FF FF) che corrisponde al bianco.
Come si puo' notare dal confronto fra l'immagine e la sua Palette, il primo segmento del display ha il colore dato dal gruppo di codici con indice 1 (ricordiamo che solitamente gli indici partono da 0), il secondo segmento ha il colore del gruppo 2, e cosi' via.
Pertanto ipotizziamo di assegnare ai gruppi di colori corrispondenti agli indici 1,3,6 un colore scelto da noi e a tutti gli altri gruppi un colore di sfondo... otterremo di visualizzare la cifra 7 (i segmenti sono numerati a partire dall'alto e da sinistra verso destra).
Dalla teoria alla pratica... Esaminiamo il codice. (Il commento e' inserito all'interno del codice stesso)
<%
' Dichiaro le variabili utilizzate
Dim Valore, Colore, Sfondo
Dim Image, Index, Carattere, Cifra, Posiz
' Un Array di dieci elementi (vedremo dopo a quale uso)
Dim Segmenti(9)
' Per la Palette mi serve un Array di 16 elementi (0-15)
Dim Palette(15)
' Riporto in esadecimale i bytes dell'immagine
' per semplicita' ho sostituito i bytes della Palette
' originale con la stringa "[Palette]"
Image = "4749463839610E001500B30000[Palette]2C0000" & _
"00000E001500000452F0C949ABBD32E8CDA7785C3748C217" & _
"06CF303EE557A96B6BC16439ABB54BD1EC47FCC0D44A022C" & _
"122885C2C3783418244965C5F97C442D546812EBD44A2959" & _
"ABF2402E3FBAD647797D384FD86C8C7C3E8900003B"
' Lo script va richiamato impostando i parametri
' "Valore", "Colore" e "Sfondo"
' Qui leggo i colori richiesti e li trasformo in Maiuscolo
' ATTENZIONE: per semplicita' non verifico la sintassi
' (i caratteri compresi fra 0-9,A-F)
Colore = UCase(Request.QueryString("Colore"))
Sfondo = UCase(Request.QueryString("Sfondo"))
' Default: verde su nero
If Colore="" Then Colore = "00FF00"
If Sfondo="" Then Sfondo = "000000"
' Preventivamente imposto tutti i colori della Palette
' al colore di sfondo
For Index=0 to 15
Palette(Index)=Sfondo
Next
' adesso imposto la tabella "Segmenti" che mi indichi quali
' "led" devo "accendere" per visualizzare ciascuna cifra.
Segmenti(0)="123567"
Segmenti(1)="36"
Segmenti(2)="13457"
Segmenti(3)="13467"
Segmenti(4)="2346"
Segmenti(5)="12467"
Segmenti(6)="124567"
Segmenti(7)="136"
Segmenti(8)="1234567"
Segmenti(9)="123467"
' Leggo il numero da visualizzare e lo trasformo in intero
Valore = CInt(Request.QueryString("Valore"))
' Prelevo dalla tabella la definizione
' del carattere che mi occorre
Cifra=Segmenti(Valore)
' Eseguo un ciclo per impostare il colore dei segmenti
' da "accendere" per visualizzare il numero richiesto
' scorro la lista
For Index = 1 to Len(Cifra)
' numero del segmento
Posiz = CInt(Mid(Cifra,Index,1))
' imposto il colore
Palette(Posiz) = Colore
Next
' sostituisco la Palette con una stringa ottenuta
' concatenando tutti gli elementi dell'Array "Palette"
Image = Replace(Image, "[Palette]", Join(Palette, ""))
' A questo punto sono pronto per trasmettere
' (da qui in poi e' identico alla prima lezione...)
' Intestazione: comunico al browser
' la natura dei dati che seguono
Response.ContentType = "image/gif"
' trasmetto l'immagine:
' ottengo ciascun byte ricreandolo a partire da una coppia
' di simboli esadecimali contenuti nella stringa Image
For Index = 1 To Len(Image) step 2
' Passaggio intermedio: ottengo una stringa del tipo "&hXX"
' che esprime un valore esadecimale
Valore = "&h" & Mid(Image, Index, 2))
' Ricavo il byte creando un carattere di valore ASCII
' corrispondente al valore esadecimale ottenuto
Carattere = ChrB(Valore)
' trattandasi di dati binari non si puo' utilizzare
' Response.Write perche tratta solo caratteri
' ASCII standard e non estesi
Response.BinaryWrite(Carattere)
' Ripeto il ciclo fino alla fine dei dati da inviare
Next
%>
Ed ecco lo stesso codice ripulito e senza commenti:
<%
<%
Dim Image, Colore, Sfondo, Index, Valore, Cifra
Dim Segmenti(9), Palette(15)
Image="4749463839610E001500B30000[Palette]2C0000" & _
"00000E001500000452F0C949ABBD32E8CDA7785C3748C217" & _
"06CF303EE557A96B6BC16439ABB54BD1EC47FCC0D44A022C" & _
"122885C2C3783418244965C5F97C442D546812EBD44A2959" & _
"ABF2402E3FBAD647797D384FD86C8C7C3E8900003B"
Colore=UCase(Request.QueryString("Colore"))
Sfondo=UCase(Request.QueryString("Sfondo"))
If Colore="" Then Colore="00FF00"
If Sfondo="" Then Sfondo="000000"
For Index=0 to 15
Palette(Index)=Sfondo
Next
Segmenti(0)="123567"
Segmenti(1)="36"
Segmenti(2)="13457"
Segmenti(3)="13467"
Segmenti(4)="2346"
Segmenti(5)="12467"
Segmenti(6)="124567"
Segmenti(7)="136"
Segmenti(8)="1234567"
Segmenti(9)="123467"
Valore = CInt(Request.QueryString("Valore"))
Cifra=Segmenti(Valore)
For Index = 1 to Len(Cifra)
Palette(CInt(Mid(Cifra,Index,1))) = Colore
Next
Image = Replace(Image, "[Palette]", Join(Palette, ""))
Response.ContentType = "image/gif"
For Index = 1 To Len(Image) step 2
Response.BinaryWrite(ChrB("&h" & Mid(Image,Index,2)))
Next
%>
Salviamo tutto con il nome Led16.asp
L'immagine originale occupa 157 bytes, tutto il codice meno di 2000 bytes, ... ma contiene tutti numeri di tutti i colori...
Ed ora come esempio di utilizzo... un contatore:
<img
src="Led16.asp?Colore=FF0000&Sfondo=000000&Valore=1"><img
src="Led16.asp?Colore=FFFF00&Sfondo=000000&Valore=2"><img
src="Led16.asp?Colore=00FF00&Sfondo=000000&Valore=3"><img
src="Led16.asp?Colore=0066FF&Sfondo=000000&Valore=4"><img
src="Led16.asp?Colore=FF00FF&Sfondo=000000&Valore=5">
Da js:
<script>
numero="1234567890";
for (i=0;i<numero.length;i++) {
document.write("<img src='Led16.asp?Valore="+numero.charAt(i)+"'>");
}
</script>