FreeBASIC – salvare e caricare immagini

Dopo aver imparato come creare una immagine, oggi vedremo come salvarla in un file utilizzando il formato bitmap e quindi come poterla caricare per usi successivi.

Come salvare una immagine

L’istruzione per salvare una qualsiasi immagine è la funzione bsave.

La funzione restituisce il valore 0 (zero) se il salvataggio è andato a buon fine, altrimenti viene restituito un codice di errore.

Vediamo l’uso di questa istruzione con un semplice esempio:

screen 19, 32, 1

''dimensiona la variabile per gestire il
''valore restituito dalla funzione bsave
dim risultato as long

''dimensiona la variabile di tipo puntatore
''per l'indirizzo di memoria
dim immagine1 as any ptr

''crea l'immagine
immagine1 = imagecreate(200, 200, rgb(255,0,0))
if immagine1 = 0 then
  print "Creazione dell'immagine non riuscita!"
  sleep
else
  ''disegna un cerchio verde al centro
  circle immagine1, (100, 100), 50, rgb(0,255,0)
  ''inserisce l'immagine all'interno
  ''della finestra grafica
  put(150, 150), immagine1
end if

print "Premi un tasto per salvare l'immagine."
sleep

''salva l'immagine
risultato = bsave("immagine.bmp", immagine1)
if risultato <> 0 then
  print "Salvataggio dell'immagine non riuscito!"
else
  print "L'immagine e' stata correttamente salvata."
end if

sleep

Ora, se il salvataggio è riuscito, andiamo a rinominare il file della nostra immagine modificandolo poi con un qualsiasi programma di grafica prima di provare a caricarlo.

Come caricare una immagine

L’istruzione per caricare le immagini è bload.

Aggiungiamo ora questo blocco di codice in fondo al programma che abbiamo appena provato:

print "Premi un tasto per caricare l'immagine"
print "modificata in una nuova posizione."
sleep

risultato = bload("immagine2.bmp", immagine1)
if risultato <> 0 then
  print "Caricamento dell'immagine non riuscito!"
  sleep
else
  print "L'immagine e' stata correttamente caricata."
  ''inserisce l'immagine all'interno
  ''della finestra grafica
  put(300, 50), immagine1
  print "Premi un tasto per uscire."
  sleep
  ''distrugge l'immagine per liberare la memoria
  imagedestroy immagine1
end if

Se tutto è andato a buon fine dovremmo essere riusciti a visualizzare, in una diversa posizione dello schermo, la nostra immagine modificata.

Bene. Anche per oggi possiamo ritenerci soddisfatti. Un altro piccolo passo è stato fatto nel percorso di apprendimento del FreeBASIC. 🙂

FreeBASIC – creare una immagine

Spesso può rivelarsi utile creare una immagine in memoria invece che disegnarla direttamente sullo schermo grafico.

Poi, una volta creata, sarà possibile richiamarla attraverso il suo indirizzo di memoria.

Questo procedimento, oltre a velocizzare il disegno delle immagini, rende possibile vari effetti grafici che possono migliorare l’efficacia e la qualità dei nostri programmi.

Possiamo immaginare ciascuna immagine come una tela contenuta all’interno di una cornice avente delle specifiche dimensioni (larghezza e altezza); la tela potrà essere colorata o trasparente.

Come creare una immagine

La funzione che ci permette di creare un’immagine è imagecreate disponibile in due versioni:

screen 19, 32, 1

''dimensiona due variabili di tipo puntatore
''per gli indirizzi di memoria
dim immagine1 as any ptr
dim immagine2 as any ptr

''I versione con i seguenti argomenti:
''- larghezza
''- altezza
''- colore dello sfondo
immagine1 = imagecreate(200, 200, rgb(255,0,0))
if immagine1 = 0 then
  print "Creazione dell'immagine 1 non riuscita!"
  sleep
else
  ''disegna un cerchio verde al centro
  circle immagine1, (100, 100), 50, rgb(0,255,0)
  ''inserisce l'immagine all'interno
  ''della finestra grafica
  put(150, 150), immagine1
  ''distrugge l'immagine per liberare la memoria
  imagedestroy immagine1
end if

''II versione con l'aggiunta di un quarto argomento:
''- profondità di colore
immagine2 =imagecreate(200, 200, rgb(0,255,0), 32)
if immagine2 = 0 then
  print "Creazione dell'immagine 2 non riuscita!"
  sleep
else
  ''disegna un cerchio rosso al centro
  circle immagine2, (100, 100), 50, rgb(255,0,0)
  ''inserisce l'immagine all'interno
  ''della finestra grafica
  put(300, 300), immagine2
  ''distrugge l'immagine per liberare la memoria
  imagedestroy immagine2
end if

sleep

Note sulla istruzione imagecreate

  • L’istruzione va utilizzata soltanto dopo aver definito la modalità grafica: e quindi sia la risoluzione dello schermo che la risoluzione grafica.
  • Se il colore dello sfondo non viene specificato, il valore predefinito sarà trasparente e quindi in pratica sarà visibile il colore di sfondo della finestra grafica.
  • Se l’istruzione dovesse fallire, viene restituito il valore null (0), altrimenti viene restituito l’indirizzo di memoria dell’immagine.

Per fare le cose per bene, occorre anche ricordarsi di distruggere le immagini create in modo tale da liberare la memoria. Per farlo si utilizza l’istruzione imagedestroy.

Bene. Per oggi possiamo fermarci qui. Nel prossimo articolo impareremo a salvare e caricare le immagini.

FreeBASIC – Grafica [3]

Dopo aver parlato della risoluzione dello schermo (modalità grafica) e della risoluzione grafica (profondità di colore), in questo articolo continueremo l’esplorazione della istruzione screen giocando con il suo terzo attributo: quello che specifica il numero di pagine video con cui si vuole lavorare.

Pagine video

In FreeBASIC è possibile lavorare con più pagine video.

Quindi, oltre alla normale procedura che prevede di disegnare su una pagina mentre questa è già visibile a schermo, avendo a disposizione più pagine video, si può per esempio disegnare su una pagina mentre se ne sta rendendo visibile un’altra su cui si era disegnato in precedenza.

Qual è il vantaggio?

Lo “spettatore” si gode lo spettacolo sul palcoscenico (pagina visibile), mentre nel retropalco (pagina di lavoro) si prepara la scenografia successiva. 😉

Come definire il numero di pagine video

Per definire il numero delle pagine video che necessitano al nostro programma basta scriverlo come terzo attributo dell’istruzione screen:

'Imposta 3 pagine video con la modalità grafica 19 per
'una risoluzione dello schermo di 800x600 pixels e
'la profondità di colore a 32bpp.
screen 19, 32, 3

Se questo attributo viene omesso, il nostro programma avrà comunque una pagina video di default.

Come specificare la pagina di lavoro e quella visibile

Se il nostro programma ha una sola pagina video, le istruzioni per il disegno agiranno e saranno visibili su questa pagina, ma se possiamo disporre di più pagine video, allora dovremo gestire sia la pagina di lavoro che la pagina visibile.

Per farlo si usa la subroutine screenset che ha due attributi: il primo per definire la pagina di lavoro, il secondo quella visibile. Vediamo alcuni esempi:

screen 19, 32, 2 'per definire due pagine video
screenset 0, 0 'disegna e visualizza la I p.v.
screenset 0, 1 'disegna sulla I p.v. mentre visualizza la II
screenset 1, 0 'disegna sulla II p.v. mentre visualizza la I
screenset 1, 1 'disegna e visualizza la II p.v.

Come è facile notare da questa porzione di codice, l’identificativo delle schede video parte dal valore 0 (zero).

Nel programma dei 3 cerchi colorati riportato più sotto ne vedremo un possibile utilizzo.

Un po’ di grafica 2D

Iniziamo ad avvicinarci alla grafica 2D utilizzando una delle funzioni per il disegno 2D: la funzione circle.

Funzione circle

La funzione circle permette di disegnare cerchi ed ellissi.

Sintassi

Un uso semplificato è questo:

circle (coordinata x, coordinata y), raggio, [colore]

I valori relativi alle coordinate x e y del centro del cerchio e quello del raggio sono obbligatori, mentre l’attributo del colore è opzionale: se omesso sarà quello del primo piano corrente impostabile con la funzione color().

Nell’esempio che vedremo più sotto ci baseremo sul modello di colori RGB utilizzando la funzione rgb() passandole tre attributi che rappresentano rispettivamente la componente rossa, quella verde e quella blu. Il range dei valori ammessi per questi attributi va da 0 a 255.

Programma dei 3 cerchi colorati

'Imposta 3 pagine video con la modalità grafica 19 per
'una risoluzione dello schermo di 800x600 pixels e
'la profondità di colore a 32bpp.
screen 19, 32, 3

'Imposta come pagina di lavoro la prima (valore 0).
screenset 0
'Disegna 255 cerchi al centro dello schermo, di
'raggio e tono di colore rosso crescenti.
for i as integer = 1 to 255
  circle (400,300), i, RGB(i,0,0)
next i

'Imposta come pagina di lavoro la seconda (valore 1).
screenset 1
'Disegna 255 cerchi al centro dello schermo, di
'raggio e tono di colore verde crescenti.
for i as integer = 1 to 255
  circle (400,300), i, RGB(0,i,0)
next i

'Imposta come pagina di lavoro la terza (valore 2).
screenset 2
'Disegna 255 cerchi al centro dello schermo, di
'raggio e tono di colore blu crescenti.
for i as integer = 1 to 255
  circle (400,300), i, rgb(0,0,i)
next i

'Doppio ciclo per rendere alternativamente visibili,
'una volta al secondo, le tre pagine. Il ciclo si
'ripete per 3 volte.
for i as integer = 1 to 3
  for j as integer = 0 to 2
    screenset ,j
    sleep 1000 'pausa di un secondo
  next j
next i

Un po’ ipnotico. No? 🙂

Nel prossimo articolo vedremo come impostare alcune proprietà della finestra grafica.

FreeBASIC – Grafica [1]

E così siamo finalmente arrivati a parlare di grafica.

Disegnare delle semplici figure 2D sullo schermo e interagire con queste sarà l’obiettivo principale di questa nuova serie di articoli.

Come è ormai nostra abitudine, partiamo subito con qualcosa di concreto.

Come creare una finestra grafica

La prima cosa che ci serve è creare una finestra grafica su cui poi andremo a disegnare.

Per farlo si utilizza l’istruzione screen.

screen 16
print "Ecco la mia prima finestra grafica in"
print "modalita' 16: ovvero con risoluzione 512x384 pixels."
sleep 'istruzione per sospendere l'esecuzione del programma

Dare un titolo alla finestra grafica

Per abbellire la nostra finestra grafica diamole un titolo sfruttando la subroutine windowtitle:

windowtitle("La mia prima finestra")
screen 19
sleep

Modalità grafica

Il numero subito dopo l’istruzione screen definisce la modalità grafica (mode) sulla base delle seguenti due tabelle:

Le modalità dalla 1 alla 13 sono compatibili anche con i vecchi programmi scritti con il glorioso QuickBASIC, mentre le nuove modalità dalla 14 alla 21 sono specifiche del FreeBASIC. Sarà proprio su queste ultime che ci concentreremo.

Le due tabelle ci mostrano con chiarezza che più la modalità scelta sarà alta, più grandi saranno le dimensioni digitali della nostra finestra: ovvero la risoluzione dello schermo (resolution).

La dimensione digitale di uno schermo (nel nostro caso della finestra) è espressa come numero di pixels orizzontali e verticali (p.e. 512×384).

Scriviamo ora un semplice programma per visualizzare una finestra in tutte e sedici le diverse modalità. Per farlo sfrutteremo un array e un ciclo for.

'dimensiona un array con tutte le modalità grafiche
 dim mode_array (1 to 16) as integer

 'assegna i valori
 mode_array(1) = 1
 mode_array(2) = 2
 mode_array(3) = 7
 mode_array(4) = 8
 mode_array(5) = 9
 mode_array(6) = 11
 mode_array(7) = 12
 mode_array(8) = 13
 mode_array(9) = 14
 mode_array(10) = 15
 mode_array(11) = 16
 mode_array(12) = 17
 mode_array(13) = 18
 mode_array(14) = 19
 mode_array(15) = 20
 mode_array(16) = 21

 'visualizza con un ciclo le varie finestre
 for i as integer = lbound(mode_array) to ubound(mode_array)
   screen mode_array(i)
   print "Finestra grafica in modalita': "; mode_array(i)
   print "---"
   print "premi un taso per continuare…"
   sleep 'sospende l'esecuzione del programma
 next i

Funzione screenres

Le modalità grafiche che abbiamo visto hanno delle dimensioni digitali preimpostate, ma se volessimo creare una finestra grafica di dimensioni diverse?

Niente panico! FreeBASIC viene in nostro aiuto con la funzione screenres che ci permette proprio di definire le dimensioni digitali che vogliamo.

Questa funzione restituisce il valore 0 (zero) se le dimensioni digitali specificate sono realizzabili dal nostro computer, altrimenti viene restituito un numero che specifica il tipo di errore.

Per la gestione degli errori si rimanda ad un futuro articolo.

Dopo aver provato il codice più sotto, provate a specificare per esempio un numero negativo come larghezza o come altezza:

''crea una finestra grafica larga 800px e alta 50px 
select case screenres(800,50)
  case 0 ''tutto OK
    print "Ecco una strana finestra grafica!"
  case else ''errore
    beep
    print "Non posso creare la finestra grafica che desideri."
end select
sleep ''rimani in pausa

Bene. Per oggi ci fermiamo qui.

Nel prossimo articolo parleremo della risoluzione grafica: ovvero della qualità delle immagini. 🙂