Assegnare a un Oggetto ''Image'' i valori pixel contenuti in un'area di memoria puntata da un Puntatore

Da Gambas-it.org - Wikipedia.

Avendo un'area di memoria comunque riservata, contenente i valori pixel, utili per colorare un'immagine, è possibile assegnare - direttamente e senza alcun ciclo - tali valori a un Oggetto di tipo Image accedendo al secondo membro ("unsigned char *data") della Struttura GB_IMG del sorgente del dell'Oggetto Image di Gambas, dedicato alla memorizzazione dei dati pixel del predetto Oggetto Image. [Nota 1]

Per accedere a detto membro, sarà necessario ottenere innanzitutto l'indirizzo di memoria dell'Oggetto Image, e spostarsi successivamente all'indice uguale alla dimensione occupata da un tipo Puntatore moltiplicata per 2, che individua il byte ove inizia il valore dell'indirizzo di memoria dell'area di memoria riservata dedicata alla memorizzazione dei dati pixel dell'immagine. Per ottenere l'indirizzo di memoria dell'Oggetto Image, si userà il Metodo ".Address()" della Classe Object.
Quindi mediante la risorsa dei Memory Stream di accederà in Scrittura, avanzando di SizeOf(gb.Pointer) * 2 byte, alla predetta area di memoria del secondo membro della Struttura del sorgente dell'Image.
Si assegnerà in fine direttamente l'indirizzo dell'area di memoria, contenente i dati pixel, al suddetto secondo membro della Struttura del sorgente Image.

Mostriamo un semplice e pratico esempio, nel quale da un Oggetto Image di dimensioni 2x2, interamente di colore inizialmente trasparente, vengono assegnati i nuovi colori contenuti in un vettore di tipo Intero[].
(Questo esempio richiede che siano attivati anche i Componenti gb.image e gb.image.io)

Public Sub Main()
 
 Dim valori_pixel As Integer[]
 Dim im As Image
 Dim gb_img, secondo_membro As Pointer
 Dim st As Stream
 Dim i As Integer

' Imposta un'area di memoria con 2*2 valori pixel, ciascuno da 32-bit, da assegnare successivamente all'Image (i byte di ciascun valore/pixel, espresso in formato esadecimale, rappresentano: Alfa, B; G; R).
 valori_pixel = [&FF0000ff, &FF00ff00, &FFff0000, &FF00ffff]

' Crea l'Oggetto "Image" di dimensioni 2x2 pixel:
 im = New Image(2, 2, Color.White, Image.Standard)

' Accede alla Struttura GB_IMG del sorgente dell'Oggetto Image di Gambas:
 gb_img = Object.Address(im)

' Si sposta sul 2° membro (unsigned char *data) della Struttura GB_IMG e vi accede con la funzione "Pointer@()" per potervi scrivere successivamente nel codice i dati-byte dei pixel:
 secondo_membro = Pointer@(gb_img + (SizeOf(gb.Pointer) * 2))

' Crea una variabile di tipo "Stream" dall'indirizzo di memoria del 2° membro dell'Oggetto "Image" dei sorgenti di Gambas:
 st = Memory secondo_membro For Write
 
' Scrive nel 2° membro della Struttura GB_IMG i nuovi valori dei 4 pixel, costituenti l'Image, contenuti nel vettore "valori_pixel":
 Write #st, valori_pixel.Data, SizeOf(gb.Integer) * valori_pixel.Count
 st.Close
 
' Verifica i nuovi valori dei pixel costituenti l'Oggetto "Image":
 For Each i In im.Pixels
   Print Hex(i, 8)
 Next
 
' Salva la nuova "Image" come file immagine di tipo PNG, per poter vedere il risultato concreto:
 im.Save("/tmp/prova.png", 100)

End


Note

[1] Vedere assolutamente anche questa pagina della wiki: Configurazione, organizzazione ed impostazione dell'oggetto Image secondo i sorgenti di Gambas e le sue note a pie' di pagina.