Differenze tra le versioni di "Individuare i colori dei pixel di una immagine"

Da Gambas-it.org - Wikipedia.
Riga 146: Riga 146:
 
  '''End'''
 
  '''End'''
 
Per analogia con questa modalità segnaliamo anche la [[Individuare_il_colore_di_un_determinato_pixel|seguente pagina della WIKI]].
 
Per analogia con questa modalità segnaliamo anche la [[Individuare_il_colore_di_un_determinato_pixel|seguente pagina della WIKI]].
 
 
==Individuare i valori RGBA dei pixel di una immagine mediante le risorse del API di SDL2==
 
Con alcune risorse del API di ''SDL2'' è possibile conoscere i valori RGBA dei pixel di una immagine.
 
 
Per poter fruire in Gambas delle risorse di ''SDL'', è necessario installare e richiamare le seguenti librerie dinamiche condivise:
 
* "''libSDL2-2.0.so.0.2.0''"
 
* "''libSDL2_image-2.0.o.0.0.0''"
 
 
 
Mostriamo un semplice esempio pratico:
 
Library "libSDL2-2.0:0.2.0"
 
 
 
Public Struct SDL_Rect
 
  x As Integer
 
  y As Integer
 
  w As Integer
 
  h As Integer
 
End Struct
 
 
Public Struct SDL_Surface
 
  flags As Integer
 
  format As Pointer
 
  w As Integer
 
  h As Integer
 
  pitch As Integer
 
  pixels As Pointer
 
  userdata As Pointer
 
  locked As Integer
 
  lock_data As Pointer
 
  clip_rect As Struct SDL_Rect
 
  map As Pointer
 
  refcount As Integer
 
End Struct
 
 
Public Struct SDL_PixelFormat
 
  format As Integer
 
  palette As Pointer
 
  BitsPerPixel As Byte
 
  BytesPerPixel As Byte
 
  Rmask As Integer
 
  Gmask As Integer
 
  BMask As Integer
 
  AMask As Integer
 
  Rloss As Byte
 
  Gloss As Byte
 
  Bloss As Byte
 
  Aloss As Byte
 
  Rshift As Byte
 
  Gshift As Byte
 
  Bshift As Byte
 
  Ashift As Byte
 
  refcount As Integer
 
  next_ As Pointer
 
End Struct
 
 
Private Const SDL_INIT_VIDEO As Integer = &20
 
 
<FONT Color=gray>' ''int SDL_Init(Uint32 flags)''
 
' ''Initialize the SDL library.''</font>
 
Private Extern SDL_Init(flags As Integer) As Integer
 
 
<FONT Color=gray>' ''void SDL_Quit(void)''
 
' ''Clean up all initialized subsystems.''</font>
 
Private Extern SDL_Quit()
 
 
 
Library "libSDL2_image-2.0:0"
 
 
<FONT Color=gray>' ''SDL_Surface * IMG_Load(const char *file)''
 
' ''Load an image from an SDL data source.''</font>
 
Private Extern IMG_Load(_file As String) As SDL_Surface
 
 
 
'''Public''' Sub Main()
 
 
 
  Dim immagine As String
 
  Dim imago As SDL_Surface
 
  Dim pxfmt As SDL_PixelFormat
 
  Dim dati As Pointer
 
  Dim i As Integer
 
  Dim r, g, b, a As Byte
 
 
 
  immagine = "<FONT Color=gray>''/percorso/del/file/immagine''</font>"
 
 
 
  SDL_Init(SDL_INIT_VIDEO)
 
 
 
<FONT Color=gray>' ''Carica un'immagine:''</font>
 
  imago = IMG_Load(immagine)
 
  If IsNull(imago) Then Error.Raise("Impossibile caricare un'immagine !")
 
 
 
<FONT Color=gray>' ''Assegna il membro di tipo Puntatore della Struttura "SDL_Surface"  alla variabile di tipo della Struttura "SDL_PixelFormat",''
 
' ''affinché possa essere utilizzato comodamente il membro ".BytesPerPixel" della predetta Struttura "SDL_PixelFormat":''</font>
 
  pxfmt = imago.format
 
  Print "Formato immagine: "; pxfmt.BitsPerPixel; " bit per pixel"
 
 
 
  dati = imago.pixels
 
 
 
  For i = 0 To (imago.w * imago.h * 4) - 1 Step 4
 
    r = Byte@(dati + i)
 
    g = Byte@(dati + i + 1)
 
    b = Byte@(dati + i + 2)
 
    a = Byte@(dati + i + 3)
 
   
 
    Print "r: "; Hex(r, 2), i; "\ng: "; Hex(g, 2); "\nb: "; Hex(b, 2); "\na: "; Hex(a, 2)
 
    Print "\n"
 
    Sleep 0.3
 
  Next
 
     
 
<FONT Color=gray>' ''Libera la libreria "SDL2" e va in chiusura:''</font>
 
  SDL_Quit()
 
 
 
'''End'''
 
 
 
 
 
  
  

Versione delle 18:02, 17 mar 2018

Individuare i valori RGBA dei pixel di una immagine mediante le risorse native di Gambas

Per individuare i colori dei pixel di una immagine mediante le sole risorse native di Gambas, sono possibili almeno quattro modalità.

Si raccomanda la lettura - per le informazioni generali sulla gestione dei pixel in Gambas - della seguente pagina della documentazione ufficiale: Image Management In Gambas.


con la proprietà .Pixels della Classe Image

La proprietà .Pixels della Classe Image ritorna un vettore di tipo Integer[ ] contenente in ciascun elemento il valore (dunque a 32 bit) del colore di un pixel dell'immagine.

Esempio:

Public Sub Form_Open()

 Dim im As Image
 Dim i As Integer
 
  im = Image.Load("/percorso/del/file/immagine")
 
  For Each i In im.Pixels
    Print Hex(i, 8)
  Next

End


con la proprietà .Data della Classe Image e le funzioni di dereferenziazione

La proprietà .Data della Classe Image ritorna un Puntatore all'area di memoria dell'Oggetto "Image", contenente ii dati della variabile di tipo Image. E' dunque coì possibile per mezzo delle funzioni di dereferenziazione, native di Gambas, leggere all'interno dell'area puntata dal predetto Puntatore.

Nell'esempio che segue abbiamo una semplice immagine formata da 2 x 2 pixel dei seguenti colori: blu, giallo, rosso e verde. Saranno mostrati i valori in rappresentazione esadecimale dei quattro pixel.

Public Sub Button1_Click()
 
 Dim im As Image
 Dim i, fo As Integer
    
  im = Image.Load("/percorso/del/file/immagine")
  
  fo = Len(im.Format)
  
  For i = 0 To (im.W * im.H * fo) - 1 Step fo
    Print Hex(Int@(im.Data + i), 8)
  Next
  
End


con la proprietà .Data della Classe Image ed i Memory Stream

Questo esempio è simile al precedente, ma si userà la risorsa dei Memory Stream per leggere all'interno dell'area puntata dal predetto Puntatore. Sarà possibile altresì scrivervi modificando quindi il colore di uno o di più pixel dell'immagine.

Nell'esempio che segue abbiamo una semplice immagine formata da 2 x 2 pixel dei seguenti colori: blu, giallo, rosso e verde.

Public Sub Form_Open()
 
 With PictureBox1
   .X = 50
   .Y = 50
   .W = 40
   .H = 40
   .Stretch = True
 End With
 
End


Public Sub Button1_Click()

 Dim im As Image
 Dim st As Stream
 Dim fo, b As Byte
 Dim j As Integer
 
  im = Image.Load("/percorso/del/file/immagine")

  fo = Len(im.Format)
 
' Viene dereferenziato il "Puntatore", mostrando così tutti i valori dei colori dei pixel della variabile immagine:
  st = Memory im.Data For Read
 
  For j = 0 To (im.H * im.W * fo) - 1   ' La dimensione in byte effettiva di un'immagine si ottiene moltiplicando i pixel per la quantità di byte che compongono un singolo pixel (formato dei pixel)
    Read #st, b
    If j Mod 4 = 0 Then Print "------------------"
    Print j;; b;; Hex(b, 2)
  Next
 
  st.Close
 
' Mostra l'immagine come modificata:
  PictureBox1.Picture = im.Picture

End


puntando all'area di memoria della variabile di tipo Image

Nei precedenti due paragrafi abbiamo visto come Gambas mediante la proprietà .Data della Classe Image consenta di puntare alla sub-area di memoria di una variabile di tipo Image, e di leggere i valori corrispondenti ai colori dei pixel dell'immagine.

L'accesso a tale sub-area di memoria dell'area principale di memoria di una variabile di tipo Image può essere effettuato anche direttamente mediante i Puntatori e la dereferenzianzione dei medesimi.
Sappiamo, come già detto, che i valori dei colori dei pixel di una variabile di tipo Image sono contenuti in una specifica area di memoria riservata, il cui indirizzo è indicato al 17° byte (indice 16) dell'area di memoria principale della predetta variabile di tipo Image.

Mostriamo un esempio pratico, nel quale si userà la funzione di dereferenziazione Byte@( ):

Public Sub Form_Open()

 Dim im As Image
 Dim p1, p2 As Pointer
 Dim i As Integer
 
  im = Image.Load("/percorso/del/file/immagine")
  
  p1 = Object.Address(im)
  p2 = Pointer@(p1 + 16)
  
  For i = 0 To (im.W * im.H * Len(im.Format)) - 1
    Print i, Hex(Byte@(p2 + i), 2)
  Next 
  
End


individuando il colore di ciascun pixel mediante le sue coordinate x ed y

Questa modalità prevede l'individuazione del colore di ciascun pixel dell'immagine identificandolo attraverso le sue coordinate x ed y con la sintassi:

Image[x, y]


Esempio:

Public Sub Form_Open()

 Dim x, y As Byte
 Dim im As Image
 
  im = Image.Load("/percorso/del/file/immagine")
  
  For x = 0 To im.W - 1
    For y = 0 To im.h - 1
      Print Hex$(im[x, y], 6)
    Next
  Next


' Volendo usare un solo ciclo, potremo anche fare così, impostando in un vettore le coordinate dei pixel dell'immagine:
' Dim vett As Byte[] = [0, 0, 1, 1, 0, 1, 0, 1]
' Dim j As Byte
' Dim im As Image
'
'  im = Image.Load("/percorso/del/file/immagine")
'
'  For j = 0 To im.W * im.H - 1
'    Print Hex$(im[vett[j], vett[j + 4]], 6)
'  Next

End

Per analogia con questa modalità segnaliamo anche la seguente pagina della WIKI.



Note

[1] Per analogia di argomento si segnala anche la pagina: Individuare il colore di un determinato pixel.