Differenze tra le versioni di "Modificare i colori dei pixel di un'immagine con la proprietà .Data della Classe Image ed i Memory Stream"

Da Gambas-it.org - Wikipedia.
Riga 62: Riga 62:
 
   PictureBox1.Picture = im.Picture
 
   PictureBox1.Picture = im.Picture
 
   
 
   
 +
'''End'''
 +
 +
 +
Di seguito un altro esempio pratico, nel quale:
 +
* sarà creato un Oggetto di tipo "Image" di dimensioni 3x3 pixel;
 +
* l'immagine sarà colorata di rosso;
 +
* sarà modificato il pixel, che appare come centrale nell'immagine visiva, ossia il 5° pixel, assegnandogli la massima trasparenza (canale Alfa = &h00).
 +
E' necessario attivare anche i Componenti di Gambas ''gb.image'' e ''gb.image.io'' .
 +
'''Public''' Sub Main()
 +
 +
  Dim im As Image
 +
  Dim st As Stream
 +
 
 +
<FONT Color=gray>' ''Crea un Oggetto "Image" di dimensioni 3x3 pixel:''</font>
 +
  im = New Image(3, 3)
 +
 
 +
<FONT Color=gray>' ''Colora l'intera immagine di rosso:''</font>
 +
  im = im.Fill(Color.Red)
 +
 +
<FONT Color=gray>' ''Viene salvata questa "prima" versione dell'immagine creata, interamente colorata di rosso:''</font>
 +
    im.Save("/tmp/prima.png", 100)
 +
 
 +
<FONT Color=gray>' ''Con i "Memory Stream" accede alla memoria dell'Oggetto di tipo "image"' mediante la proprietà ".Data" della sua corrispondente variabile.''
 +
' ''In particolare la proprietà ".Data" dell'Oggetto "Image" è sostanzialmente un Puntatore, giacché essa restituisce l'indirizzo di memoria dell'area,''
 +
' ''ove tale Oggetto conserva i dati afferenti ai pixel dell'immagine.''</font>
 +
  st = Memory im.Data For Write
 +
 +
<FONT Color=gray>' ''Individua il byte di memoria, ove hanno inizio i valori del pixel, al quale modificare i valori.''
 +
' ''Il byte di memoria va individuato tenendo conto del "formato" dell'immagine, ossia di quanti byte è formato un singolo pixel, moltiplicato per il numero indicizzato del pixel da modificare.''</font>
 +
  Seek #st, 4 * Len(im.Format)
 +
 
 +
<FONT Color=gray>' ''Scrive nella porzione, come sopra individuata, di memoria il nuovo valore del pixel interessato.''
 +
' ''Per attribuire la trasparenza, il byte (del pixel) corrispondente al canale "Alfa" dovrà essere impostato a zero.''</font>
 +
  Write #st, 0 As Integer
 +
  st.Close
 +
 
 +
<FONT Color=gray>' ''Salva l'immagine per andarla a vedere:''</font>
 +
  im.Save("/tmp/bucata.png", 100)
 +
 
 
  '''End'''
 
  '''End'''

Versione delle 13:25, 20 feb 2018

E' possibile modificare i colori dei pixel di un'immagine utilizzando la proprietà .Data della Classe Image ed i Memory Stream.

La proprietà .Data della Classe Image ritorna un Puntatore ai dati della variabile di tipo Image. Si potrà, quindi, per mezzo dei Memory Stream 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: rosso, verde, blu e giallo. Si procederà con il vedere quei quattro pixel ed a cambiare - subito dopo - il colore del pixel blu nel colore rosso:

Private im As Image


Public Sub Form_Open()
 
  im = Image.Load("/percorso/del/file/immagine")
  
  With PictureBox1
    .X = 50
    .Y = 50
    .W = im.W
    .H = im.H
  End With
  
  PictureBox1.Picture = im.Picture
  
End


Public Sub Button1_Click()

 Dim st As Stream
 Dim fo, b As Byte
 Dim j As Integer
  
  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 Write
 
  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


  Print "------------------"

' Viene modificato il colore del pixel che occupa 4 byte a partire dal 9° byte:
  Seek #st, 8
' Viene cambiato il colore blu nel colore rosso (se il formato è "diverso" dal "BGR", allora il primo byte a sinistra è relativo al valore "alfa" !):
  Write #st, &FFFF0000 As Integer
  
' Vengono nuovamente letti i valori dei colori dopo la modifica del terzo pixel:
  Seek #st, 0
  For j = 0 To (im.H * im.W * fo) - 1
    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


Di seguito un altro esempio pratico, nel quale:

  • sarà creato un Oggetto di tipo "Image" di dimensioni 3x3 pixel;
  • l'immagine sarà colorata di rosso;
  • sarà modificato il pixel, che appare come centrale nell'immagine visiva, ossia il 5° pixel, assegnandogli la massima trasparenza (canale Alfa = &h00).

E' necessario attivare anche i Componenti di Gambas gb.image e gb.image.io .

Public Sub Main()
 Dim im As Image
 Dim st As Stream
 
' Crea un Oggetto "Image" di dimensioni 3x3 pixel:
  im = New Image(3, 3)
  
' Colora l'intera immagine di rosso:
  im = im.Fill(Color.Red)
' Viene salvata questa "prima" versione dell'immagine creata, interamente colorata di rosso:
   im.Save("/tmp/prima.png", 100)
  
' Con i "Memory Stream" accede alla memoria dell'Oggetto di tipo "image"' mediante la proprietà ".Data" della sua corrispondente variabile.
' In particolare la proprietà ".Data" dell'Oggetto "Image" è sostanzialmente un Puntatore, giacché essa restituisce l'indirizzo di memoria dell'area,
' ove tale Oggetto conserva i dati afferenti ai pixel dell'immagine.
  st = Memory im.Data For Write
' Individua il byte di memoria, ove hanno inizio i valori del pixel, al quale modificare i valori.
' Il byte di memoria va individuato tenendo conto del "formato" dell'immagine, ossia di quanti byte è formato un singolo pixel, moltiplicato per il numero indicizzato del pixel da modificare.
  Seek #st, 4 * Len(im.Format)
  
' Scrive nella porzione, come sopra individuata, di memoria il nuovo valore del pixel interessato.
' Per attribuire la trasparenza, il byte (del pixel) corrispondente al canale "Alfa" dovrà essere impostato a zero.
  Write #st, 0 As Integer
  st.Close
  
' Salva l'immagine per andarla a vedere:
  im.Save("/tmp/bucata.png", 100)
  
End