Gestire un oggetto Image agendo direttamente sulle risorse dei sorgenti Gambas
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:
- Configurazione, organizzazione ed impostazione dell'oggetto Image secondo i sorgenti di Gambas
- Leggere le informazioni di una Image dalle sue risorse dei sorgenti di Gambas
[2] Vedere anche: https://gambaswiki.org/wiki/doc/imageconv