Mappare un immagine. - pagina vista: volte

Da una interessante idea che ho trovato sul sito "http://www.j-walk.com/ss/excel" nasce questo esercizio che sfrutta la "mappatura" di una immagine inserita su un foglio di lavoro, per far eseguire specifiche istruzioni.

Qualsiasi cosa noi vediamo sul monitor è una immagine, non solo le foto. Per semplificare, diremo che ogni immagine è formata da un insieme di punti (pixel), ed avremo tanti punti quanti ne corrispondono alla "risoluzione video" che teniamo impostata per il nostro monitor. Quindi possiamo dire che se teniamo una risoluzione 800 x 600, vedremo una immagine formata da 800 punti in orizzontale, e da 600 punti in verticale.

Il programma che ci consente di visualizzare l'immagine, per mostrarcela, utilizza istruzioni che determinano per ogni punto (pixel) dell'immagine stessa, la coordinata del punto (cioè la sua posizione a schermo), oltre al colore che il punto dovrà avere.

A noi non interessa conoscere la compilazione di quelle istruzioni, ma capire solo come si definiscono le coordinate dei pixel in una immagine. Per definire una coordinata si usano due lettere:

  • la lettera Y - con Y si indica il numero di punti (o pixel) che distano dal bordo superiore dell'immagine, e serve quindi a localizzare una posizione verticale nell'immagine.

  • la lettera X - con X si indica il numero di punti (o pixel) che distano dal bordo sinistro dell'immagine, e serve quindi a localizzare una posizione orizzontale nell'immagine.

Questa premessa, per molti pellegrini non necessaria, ci serve comunque per avvicinarci al tema dell'articolo: identificare le coordinate di un'immagine che avremo inserito su un foglio di lavoro, per far eseguire istruzioni in vba al semplice clik su uno (o più punti) prefissati, nell'immagine .

E' una valida alternativa all'uso di pulsanti, commandbutton, selezione di celle, ecc. ecc, per "innescare" l'esecuzione di macro; oltretutto può far diventare simpatica l'esecuzione di procedure, in funzione di ciò che l'immagine rappresenterà.

Ma vediamo in breve un paio di esempi; supponiamo di avere inserito su un foglio un'immagine di una cartina geografica:

avremo predisposto tanti fogli rinominandoli con i nomi delle città dove avremo clienti (o depositi, o agenti, o informazioni turistiche, o elenchi di alberghi, di farmacie, o di tutto ciò che vorrete); qualunque sia il motivo che ci spinge, lo scopo sarà questo: cliccare sul nome di una città (sulla cartina) ed ottenere la selezione del foglio corrispondente. O ancora, una immagine nella quale avremo scritto (per farlo va bene anche il programma Paint, di default installato insieme al sistema operativo) i nomi di persone o collaboratori, (o ecc. ecc.):

anche qui li scopo potrà essere quello di selezionare il foglio (opportunamente rinominato) corrispondente ad un nome cliccato nell'immagine (ma potrà essere qualunque istruzione da correlare ad un valore stringa, numerico, o data/ora).

Avremo bisogno nei due casi, di conoscere le coordinate relative al nome di una città, o il nome di un collaboratore, coordinate relative all'immagine stessa, cioè conoscere ad esempio le coordinate relative alla città di "Pistoia", oppure al nome "pippo" all'interno delle rispettive immagini.

Per ottenere un'immagine è anche possibile seguire questi passaggi: è possibile "catturare" ciò che vediamo sul monitor (per esempio una cartina trovata su internet) premendo il tasto "Stamp" presente sulla nostra tastiera; questa azione di fatto memorizza nelle ClipBoard (in memoria) l'intera schermata (tutto ciò che abbiamo a video in quel momento); apriamo quindi il programma Paint (dal menù Start/Programmi/Accessori/Paint), e nel programma aperto, dal suo menù "Modifica" scegliamo "Incolla": vedremo che l'immagine che abbiamo in memoria sarà ora visualizzata all'interno di Paint; poichè l'immagine conterrà cose che non ci servono, useremo ora lo strumento "Seleziona" (l'icona del rettangolino tratteggiato che vediamo nella parte sinistra, nella casella degli strumenti); clicchiamo sullo strumento "Seleziona" e spostandoci sull'immagine, selezioniamo, trascinando, l'area della parte di immagine che ci interessa; ci spostiamo quindi sul menù "Modifica", clicchiamo su "Copia", indi andiamo sul menù File/Nuovo, diremo no alla richiesta di salvare l'immagine originaria, e con la nuova finestra ora creata, dal menù "Modifica" sceglieremo "Incolla". Vedremo l'immagine rappresentata dalla selezione poco prima fatta, e a questo punto salveremo con nome. Questa sarà l'immagine che useremo sul foglio.

Vediamo intanto come procedere: avremo bisogno di inserire su un foglio, prendendolo da "Strumenti di Controllo", un "controllo" "Immagine". Questo "controllo" fa parte degli ActiveX (come tutti i ""controlli" presi da "Strumenti di Controllo", e non da "Moduli") e come tale, possiede delle "proprietà" e degli "eventi". Sfrutteremo la sua proprietà "Picture" fornendogli il percorso e il nome del file immagine che vorremo vedere. Posizioneremo e dimensioneremo, trascinando, il controllo "Image1" (questo sarà il suo nome), fino a contenere con precisione l'immagine collegata (la foto scelta).

Ora dobbiamo impostare le istruzioni che ci consentano di reperire le coordinate che ci interessano. Per questa routine (che serve solo a questo, e potrà poi essere cancellata), sfruttiamo l'evento MouseDown dell'oggetto Image1, che avendo come argomenti (di default) i valori X e Y, ci consente di ottenere in restituzione le coordinate corrispondenti al punto nel quale cliccheremo (MouseDown = Mouse giù). Inseriamo l'istruzione per avere un messaggio con le coordinate, così:

  • Private Sub Image1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    MsgBox Y & "x" & X
    End Sub

e ad ogni click, avremo le coordinate (con la Y la posizione verticale, con la X la orizzontale), esempio (la freccia bianca indica il punto dove si è cliccato); ricordo che le coordinate sono relative alla posizione selezionata all'interno dell'immagine, non relative alla posizione dell'immagine sul foglio.

 abbiamo cliccato su Pistoia

 abbiamo cliccato su Firenze

 

Per istruire condizioni legate all'identificazione del punto selezionato (cliccato) sul'immagine, useremo il Select Case (vedi articolo "Select Case-Struttura" in questa sezione), inserito nell'evento Image1_MouseMove.

Solo che non useremo condizioni che si basino su un punto corrispondente alle coordinate precise, bisognerebbe essere dei "tiratori scelti" per cliccare su un preciso punto per far "scattare" le istruzioni relative,     ma useremo la sintassi "inferiore a..  ( < )". Vediamo come agire:

  • istruiremo tanti Case Y che identifichino una linea corrispondente alla posizione verticale, nell'esempio della città di Pistoia, corrispondente al valore 21,75, e useremo un valore leggermente superiore, ad esempio 23 oppure 25.

  • poi nidifichiamo tanti Case X corrispondenti alle posizioni orizzontali, nell'esempio della città di Pistoia, corrispondente al valore 43,5, anche qui usando un valore leggermente superiore, per esempio 45.

  • usando ora istruzioni: <25 e <45  comprenderemo un'area che sicuramente sarà compresa nella zona "Pistoia" che cliccheremo.

Vediamo un'esempio di istruzione: useremo l'evento MouseMove dell'oggetto Image1, che si verifica quando muoveremo il mouse sopra l'immagine; questo ci consente di assegnare, ad una variabile che avremo dimensionato come Public (useremo la variabile chiamata "Dove"), il valore corrispondente al nome il cui "punto" avremo selezionato, e di cui esiste un foglio con lo stesso nome :

  • Private Sub Image1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    Select Case Y
    Case Is < 25
          Select Case X
          Case Is < 45: Dove =  "Pistoia"
          End Select

  • '....ecc. ecc.
    End Select
    End Sub

in pratica facciamo controllare se il valore Y corrispondente al punto in cui cliccheremo sul quadratino che  identifica Pistoia (coordinata verticale), rientra nel valore 25 (quindi se è inferiore a 25), se corrisponde, allora si innesca la condizione di verifica della coordinata X (coordinata orizzontale): se anche questa rientra nel valore 50 (inferiore a 50), allora la variabile "Dove" sarà uguale al nome  Pistoia".

Ora dovremo usare un'altro evento dell'oggetto Image1, l'evento Click. Sarà in questo evento che inseriamo l'istruzione che leggendo il nome contenuto nella variabile "Dove", selezionerà il foglio corrispondente, così:

  • Private Sub Image1_Click()
    If Dove <> "" Then Sheets(Dove).Activate
    End Sub

Vediamo ora il totale delle procedure:

Non scordiamo di scrivere nella sezione "Generale - Dichiarazioni" del modulo del foglio sul quale abbiamo l'immagine, il dimensionamento della variabile pubblica "Dove" , così:

  • Public Dove As String

poi la routine assegnata all'evento MouseMove: inseriamo anche dei Case Else per rendere vuota la stringa nella variabile Dove, nel caso si selezionino zone non previste dai Case :

  • Private Sub Image1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    Select Case Y
    Case Is < 10: Dove = ""
     'se il valore della coordinata Y è fuori mappatura, "Dove" sarà vuota
    Case Is < 35
        Select Case X
        Case Is < 45: Dove = "Pistoia"
        Case Else: Dove = ""
        End Select
    Case Is < 45
        Select Case X
        Case Is < 97: Dove = "Prato"
        Case Else: Dove = ""
        End Select
    Case Is < 62
        Select Case X
        Case Is < 108: Dove = "Campi"
        Case Is < 130: Dove = "Sesto"
        Case Else: Dove = ""
        End Select
    Case Is < 87
        Select Case X
       Case Is < 124: Dove = "Scandicci"
       Case Is < 180: Dove = "Firenze"
       Case Is < 195: Dove = "Pontassieve"
       Case Else: Dove = ""
       End Select
    End Select
    End Sub

ed infine la routine per la selezione dei fogli :

  • Private Sub Image1_Click()
    If Dove <> "" Then Sheets(Dove).Activate  '
    se Dove è diverso da vuoto, allora selezioniamo il foglio rappresentato 'dalla variabile Dove
    End Sub

L'esercizio non è difficile, bisogna solo avere un pò di pazienza nel reperire prima le coordinate Y X relative ai punti da sfruttare, e fare poi qualche "aggiustamento" nell'assegnazione dei valori ai Select Case considerando sempre un pò di tolleranza nei valori, ma stare attenti a non accavallare aree vicine. Ricordo ancora di non mandare in esecuzione la macro assegnata al MouseDown, dopo che ci saremo annotati tutte le coordinate, basta anche solo "apiciarla", mettendo un apice ad inizio istruzione, così:

  • ' MsgBox Y & "x" & X

File scaricabile e consultabile:

nome file dimensione n.download
Mappatura.zip 36 Kb

 

Buon lavoro.

prelevato sul sito www.ennius.altervista.org