Gestire un oggetto Image agendo direttamente sulle risorse dei sorgenti Gambas

Da Gambas-it.org - Wikipedia.

I dati di un oggetto di tipo Image sono gestiti mediante alcune risorse presenti nei file sorgenti "gb.image.h " e "gambas.h ". [Nota 1]
In particolare i dati di un oggetto Image sono immagazzinati nella Struttura GB_IMG, scritta in C, presente nel predetto file gb.image.h, e che qui mostriamo:

typedef
       struct GB_IMG {
               GB_BASE ob;                               // la Struttura di riferimento del membro "ob" è: "typedef struct _CLASS", contenuta nel file header "gbx_class.h", riga 250
               unsigned char *data;                      // points at the image data
               int width;                                // image width in pixels
               int height;                               // image height in pixels
               int format;                               // image format (RGB, BGR, RGBA...)   Vedi l'elenco sotto il paragrafo "Constants used by image data format" nel file header "gb.image.h"
               GB_IMG_OWNER *owner;                      // owner of the data, NULL means gb.image
               void *owner_handle;                       // handle for the owner
               GB_IMG_OWNER *temp_owner;                 // owner of the temporary handle that does not own the data
               void *temp_handle;                        // temporary handle
               unsigned modified : 1;                    // data has been modified by gb.image
               unsigned sync : 1;                        // data must be synchronized by calling GB_IMG_OWNER.sync()
               unsigned is_void : 1;                     // void image (no data)
               }
       GB_IMG;

Agendo - in lettura ed in scrittura - su questa Struttura, possiamo ottenere dati dall'immagine o scriverne nuovi, così modificandola.


Lettura dei dati

Di seguito mostriamo un semplice esempio, nel quale leggeremo alcuni dati di una immagine agendo sull'area di memoria della predetta Struttura GB_IMG:

 Public Sub Form_Open()

 Dim im As Image
 Dim p1, p2 As Pointer
 Dim spost As Integer
   
 im = Image.Load("/percorso/del/file/immagine")
     
' Punta all'oggetto "Image":
 p1 = Object.Address(im)
  
 spost = SizeOf(gb.Pointer) * 3
  
' Punta al dato relativo al tipo di oggetto (ossia: "Image"):
 Print String@(Pointer@(Pointer@(p1) + spost))
  
' Punta al dato relativo alla larghezza dell'immagine in pixel:
 Print Int@(p1 + spost); " pixel"
  
' Punta al dato relativo all'altezza dell'immagine in pixel:
 Print Int@(p1 + spost + 4); " pixel"
  
' Punta al dato relativo al formato dell'immagine:
 Print Int@(p1 + spost + 8)
  
' Punta al dato relativo al corrente Componente di Gambas che sta gestendo l'oggetto "Image":
 Print String@(Pointer@(Pointer@(p1 + (SizeOf(gb.Pointer) * 5))))
  
End


Scrittura dei dati

In questo esempio, invece, procederemo a scrivere dei valori nell'area di memoria puntata dal membro "unsigned char *data" della Struttura GB_IMG, modificando così il colore dei pixel dell'immagine caricata:

Public Sub Form_Open()

 Dim im As Image
 Dim p1, p2 As Pointer
 Dim st As Stream
 
 im = Image.Load("/percorso/del/file/immagine")
     
' Punta all'oggetto "Image":
 p1 = Object.Address(im)
  
' Punta all'area di memoria (puntata dal membro "*data" della Struttura GB_IMG) dei dati che rappresentano ai pixel dell'immagine:
 p2 = Pointer@(p1 + (SizeOf(gb.Pointer) * 2))
  
' Utilizziamo ovviamente i "Memory Stream" per scrivere nell'area di memoria puntata dal "Puntatore":
 st = Memory p2 For Write
  
' Modifichiamo il primo pixel, che è quello posto nell'angolo in alto a sinistra dell'immagine, scrivendo il valore corrispondente al colore "giallo", ed avendo cura di porre il canale "alfa" (primo byte a sinistra) al valore massimo 255 (&FF). [Nota 2]
 Write #st, &FF00FFFF As Integer
 st.Close

' Verifichiamo l'avvenuta scrittura/modifica leggendo il valore del primo pixel:
 Print Hex(Int@(p2), 8)

' Verifichiamo l'avvenuta scrittura/modifica, inoltre, mostrando l'immagine in una "PictureBox" e salvandola in nuovo file immagine:
 PictureBox1.Picture = im.Picture
 im.Save("/tmp/immagine.png", 100)
  
End


Note

[1] Si rinvia per identico argomento alle seguenti pagine della WIKI:

[2] Vedere anche: https://gambaswiki.org/wiki/doc/imageconv