Differenze tra le versioni di "Passare direttamente ad un oggetto Image i dati grezzi dei pixel di una DrawingArea mediante le risorse del API di X11"

Da Gambas-it.org - Wikipedia.
 
(12 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
 
Per passare ad un oggetto ''Image'' i dati grezzi dei pixel del disegno presente in una ''DrawingArea'', senza creare preliminarmente in ausilio un file immagine, si potranno utilizzare le risorse del API della libreria di X11.
 
Per passare ad un oggetto ''Image'' i dati grezzi dei pixel del disegno presente in una ''DrawingArea'', senza creare preliminarmente in ausilio un file immagine, si potranno utilizzare le risorse del API della libreria di X11.
  
In particolare si avranno almeno due modalità. In entrambe le modalità si dovrà richiamare in Gambas la libreria dinamica condivisa: "''libX11.so.6.3.0''" , e sarà opportuno utilizzare un Componente Gambas delle librerie grafiche QT (''gb.qt4'' oppure ''gb.qt5'').
+
In particolare si avranno almeno due modalità. In entrambe le modalità si dovrà richiamare in Gambas la libreria dinamica condivisa: "''libX11.so.6.3.0'' " , e sarà opportuno utilizzare un Componente Gambas delle librerie grafiche QT (''gb.gui.qt'' oppure ''gb.qt5'').
  
 +
==Passare i dati all'indirizzo dell'area di memoria restituito dalla Proprietà ".Data" dell'Oggetto "Image"==
 +
La prima modalità prevede il passaggio dei dati dei pixel all'indirizzo dell'area di memoria restituito dalla proprietà ''.Data'' dell'oggetto ''Image''.
  
==Passare i dati all'indirizzo dell'area di memoria restituito dalla proprietà ''.Data'' dell'oggetto ''Image''==
+
Si tratta di creare un Oggetto di tipo "Image", avente le medesime dimensioni della "DrawingArea", e di passare direttamente all'area di memoria puntata dalla proprietà ".Data" di detta variabile di tipo "Image" i dati grezzi dei pixel ottenuti dalla "DrawingArea" e contenuti nell'area di memoria riservata, puntata dal "Puntatore" restituito dalla funzione esterna "XGetImage()" della libreria di X11. Tutti i dati precedenti relativi ai pixel, comunque contenuti dalla variabile "Image", saranno sostituiti dai nuovi dati dei pixel afferenti al disegno presente nella ''DrawingArea''.
La prima modaltà prevede il passaggio dei dati dei pixel all'indirizzo dell'area di memoria restituito dalla proprietà ''.Data'' dell'oggetto ''Image''.
 
  
Si tratta di creare un ogetto di tipo ''Image'', avente le medesime dimensioni della ''DrawingArea'', e di passare direttamente all'area di memoria puntata dalla proprietà ''.Data'' di detta variabile di tipo ''Image'' i dati grezzi dei pixel ottenuti dalla ''DrawingArea'' e contenuti nell'area di memoria riservata, puntata dal ''Puntatore'' restituito dalla funzione ''XGetImage( )'' della libreria di X11. Tutti i dati precedenti relativi ai pixel, comunque contenuti dalla variabile ''Image'', saranno sostituiti dai nuovi dati dei pixel afferenti al disegno presente nella ''DrawingArea''.
+
Mostriamo un esempio pratico (è necessario porre sul "Form" una "DrawingArea" ed una "PictureBox").
 
+
  Library "libX11:6.4.0"
 
 
Mostriamo un esempio pratico (è necessario porre sul ''Form'' una ''DrawingArea'', un ''Button'' ed una ''PictureBox'').
 
  Library "libX11:6.3.0"
 
 
   
 
   
 
  Private Enum XYBitmap = 0, XYPixmap, ZPixmap
 
  Private Enum XYBitmap = 0, XYPixmap, ZPixmap
Riga 17: Riga 15:
 
  <FONT Color=gray>' ''Display *XOpenDisplay(char *display_name)''
 
  <FONT Color=gray>' ''Display *XOpenDisplay(char *display_name)''
 
  ' ''Opens a connection to the X server that controls a display.''</font>
 
  ' ''Opens a connection to the X server that controls a display.''</font>
  Private Extern XOpenDisplay(display_name As String) As Pointer
+
  Private Extern XOpenDisplay(display_name As Pointer) As Pointer
 
   
 
   
 
  <FONT Color=gray>' ''unsigned long XAllPlanes()''
 
  <FONT Color=gray>' ''unsigned long XAllPlanes()''
Riga 25: Riga 23:
 
  <FONT Color=gray>' ''XImage *XGetImage(Display *display, Drawable d, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, int format)''
 
  <FONT Color=gray>' ''XImage *XGetImage(Display *display, Drawable d, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, int format)''
 
  ' ''Returns a pointer to an XImage structure.''</font>
 
  ' ''Returns a pointer to an XImage structure.''</font>
  Private Extern XGetImage(display As Pointer, d As Long, xI As Integer, yI As Integer, wid As Integer, hei As Integer, plane_mask As Long, formatI As Integer) As Pointer
+
  Private Extern XGetImage(display As Pointer, d As Long, x As Integer, y As Integer, width As Integer, height As Integer, plane_mask As Long, format_ As Integer) As Pointer
 
    
 
    
 
  <FONT Color=gray>' ''XCloseDisplay(Display *display)''
 
  <FONT Color=gray>' ''XCloseDisplay(Display *display)''
Riga 39: Riga 37:
 
     .Y = 10
 
     .Y = 10
 
     .W = 400
 
     .W = 400
     .H = 300
+
     .H = 420
 
     .Background = Color.White
 
     .Background = Color.White
 +
  End With
 +
  With PictureBox1
 +
    .X = DrawingArea1.W + 20
 +
    .Y = DrawingArea1.Y
 +
    .W = DrawingArea1.W
 +
    .H = DrawingArea1.H
 
   End With
 
   End With
 
    
 
    
Riga 49: Riga 53:
 
    
 
    
 
   Dim colori As Integer[] = [Color.Blue, Color.Green, Color.Yellow, Color.Red]
 
   Dim colori As Integer[] = [Color.Blue, Color.Green, Color.Yellow, Color.Red]
   Dim p As Float[] = [0, 0.34, 0.67, 1]
+
   Dim ff As Float[] = [0, 0.34, 0.67, 1]
 
    
 
    
 
  <FONT Color=gray>' ''Disegnamo all'interno della "DrawingArea":''</font>
 
  <FONT Color=gray>' ''Disegnamo all'interno della "DrawingArea":''</font>
  With Paint
+
  With Paint
    .Brush = .LinearGradient(10, 40, 300, 40, colori, p)
+
    .Brush = .LinearGradient(10, 40, 300, 40, colori, ff)
    .Rectangle(10, 40, 300, 40)
+
    .Rectangle(10, 40, 300, 40)
    .Fill
+
    .Fill
 
  <FONT Color=gray>' ''Imposta il colore dei caratteri:''</font>
 
  <FONT Color=gray>' ''Imposta il colore dei caratteri:''</font>
    .Brush = .Color(Color.Red)  
+
    .Brush = .Color(Color.Red)  
 
  <FONT Color=gray>' ''Imposta il tipo di carattere:''</font>
 
  <FONT Color=gray>' ''Imposta il tipo di carattere:''</font>
    .Font.Name = "Arial"  
+
  .Font.Name = "Arial"  
 
  <FONT Color=gray>' ''Imposta la dimensione dei caratteri:''</font>
 
  <FONT Color=gray>' ''Imposta la dimensione dei caratteri:''</font>
    .Font.Size = 16
+
  .Font.Size = 16
  <FONT Color=gray>' ''Scrive sull'Area di Disegno il seguente testo di caratteri nella posizione X, Y all'interno di un quadrilatero virtuale W, H''
+
  <FONT Color=gray>' ''Scrive sull'Area di Disegno il seguente testo di caratteri nella posizione X, Y all'interno di un quadrilatero virtuale W, H con i metodi .RichText  e .Text, ma occorrerà uno ".Stroke" a seguire (però .Stroke tende a dare l'effetto del grassetto):''</font>
' ''con i metodi .RichText  e .Text, ma occorrerà uno ".Stroke" a seguire (però .Stroke tende a dare l'effetto del grassetto):''</font>
+
  .RichText("testo con r i chText", 200, 20, 16, 100)
    .RichText("Testo con RichText", 200, 20, 16, 100)
+
  .Text("Testo con Text", 10, 30, 20, 20)
    .Text("Testo con Text", 10, 30, 20, 20)
+
  .Stroke
    .Stroke
 
 
  <FONT Color=gray>' ''...oppure (meglio, perché non dà l'effetto del grassetto) ".fill":''</font>
 
  <FONT Color=gray>' ''...oppure (meglio, perché non dà l'effetto del grassetto) ".fill":''</font>
    .Fill
+
  .Fill
 
  <FONT Color=gray>' ''Con il metodo .DrawText non è necessario l'uso di ".Stroke", né di ".Fill":''</font>
 
  <FONT Color=gray>' ''Con il metodo .DrawText non è necessario l'uso di ".Stroke", né di ".Fill":''</font>
    .DrawText("Testo con DrawText", 10, 10, 20, 20)
+
  .DrawText("Testo con DrawText", 10, 10, 20, 20)
    .End
+
  .End
 
   End With
 
   End With
 
    
 
    
 
  '''End'''
 
  '''End'''
 
   
 
   
+
  '''Public''' Sub PictureBox1_MouseDown() <FONT Color=gray>' ''Cliccando sulla "PictureBox" avviene il passaggio dei dati grezzi dei pixel''</font>
  '''Public''' Sub Button1_Click()
 
 
   
 
   
 
   Dim dsp, XImage, dati_imm As Pointer
 
   Dim dsp, XImage, dati_imm As Pointer
Riga 84: Riga 86:
 
   Dim i As Integer
 
   Dim i As Integer
 
    
 
    
  dsp = XOpenDisplay(Null)
+
  dsp = XOpenDisplay(0)
  If dsp = 0 Then Error.Raise("Impossibile aprire una connessione al server X !")
+
  If dsp == 0 Then Error.Raise("Impossibile aprire una connessione al server X !")
 
    
 
    
  <FONT Color=gray>' ''Otteniamo un puntatore alla "Struttura" contenente i dati dell'immagine disegnata nella "DrawingArea":''</font>
+
  <FONT Color=gray>' ''Ottiene un puntatore alla "Struttura" contenente i dati dell'immagine disegnata nella "DrawingArea":''</font>
  XImage = XGetImage(dsp, DrawingArea1.Handle, 0, 0, DrawingArea1.W, DrawingArea1.H, XAllPlanes(), ZPixmap)
+
  XImage = XGetImage(dsp, DrawingArea1.Handle, 0, 0, DrawingArea1.W, DrawingArea1.H, XAllPlanes(), ZPixmap)
  If XImage = 0 Then Error.Raise("Impossibile ottenere un 'Puntatore' ai dati dell'immagine della DrawingArea !")
+
  If XImage == 0 Then Error.Raise("Impossibile ottenere un 'Puntatore' ai dati dell'immagine della DrawingArea !")
 
    
 
    
  <FONT Color=gray>' ''Otteniamo l'indirizzo di memoria dei dati grezzi dell'immagine puntati dalla Struttura "XImage":''</font>
+
  <FONT Color=gray>' ''Ottiene l'indirizzo di memoria dei dati grezzi dell'immagine puntati dalla Struttura "XImage":''</font>
  dati_imm = Pointer@(XImage + 16)
+
  dati_imm = Pointer@(XImage + (SizeOf(gb.Pointer) * 2))
 +
  If dati_imm == 0 Then Error.Raise("Errore !")
 
    
 
    
  <FONT Color=gray>' ''Creiamo un semplice oggetto di tipo "Image":''</font>
+
  <FONT Color=gray>' ''Crea un semplice oggetto di tipo "Image":''</font>
  im = New Image(DrawingArea1.W, DrawingArea1.H)
+
  im = New Image(DrawingArea1.W, DrawingArea1.H)
  If IsNull(im) Then Error.Raise("Impossibile creare un oggetto 'Image' !")
+
  If IsNull(im) Then Error.Raise("Impossibile creare un oggetto 'Image' !")
 
    
 
    
  <FONT Color=gray>' ''Utilizziamo ovviamente i "Memory Stream" per scrivere nell'area di memoria dell'oggetto "Image", destinata ai dati''
+
  <FONT Color=gray>' ''Utilizza i "Memory Stream" per scrivere nell'area di memoria dell'oggetto "Image", destinata ai dati attinenti ai pixel, il cui indirizzo di memoria è ritornato dalla proprietà ".Data" della variabile di tipo "Image":''</font>
' ''attinenti ai pixel, il cui indirizzo di memoria è ritornato dalla proprietà ".Data" della variabile di tipo "Image":''</font>
+
  st = Memory im.Data For Write
  st = Memory im.Data For Write
 
 
    
 
    
  For i = 0 To im.W * im.H * Len(im.Format)
+
  For i = 0 To im.W * im.H * (im.Depth / 8)
    Write #st, Byte@(dati_imm + i) As Byte
+
    Write #st, Byte@(dati_imm + i) As Byte
  Next
+
  Next
 
    
 
    
  st.Close
+
  st.Close
 
    
 
    
  <FONT Color=gray>' ''Come verifica finale mostriamo in una "PictureBox" i dati contenuti nella variabile di tipo "Image",''
+
  <FONT Color=gray>' ''Come verifica finale mostriamo in una "PictureBox" i dati contenuti nella variabile di tipo "Image", dopo averla convertita opportunamente in una variabile di tipo "Picture":''</font>
' ''dopo averla convertita opportunamente in una variabile di tipo "Picture":''</font>
+
  PictureBox1.Image = im
  PictureBox1.Picture = im.Picture
 
 
    
 
    
 
  <FONT Color=gray>' ''Va in chiusura:''</font>
 
  <FONT Color=gray>' ''Va in chiusura:''</font>
  XCloseDisplay(dsp)
+
  XCloseDisplay(dsp)
 
    
 
    
 
  '''End'''
 
  '''End'''
  
  
 +
==Passare i dati all'area di memoria puntata dal membro "''*data'' " della Struttura "''GB_IMG'' " dichiarata nel file sorgente "gb.image.h"==
 +
La seconda modalità prevede l'assegnazione dei dati dei pixel della "DrawingArea" all'area di memoria puntata dal membro "''*data'' " della Struttura "''GB_IMG'' " contenuta nel file sorgente "''.../main/lib/image/gb.image.h'' ". <SUP>&#91;[[#Note|nota 1]]&#93;</sup>
  
==Passare i dati all'area di memoria puntata dal membro "''*data''" della Struttura "''GB_IMG''" dichiarata nel file sorgente ''gb.image.h''==
+
Mostriamo di seguito un semplice esempio, nel quale disegneremo all'interno di una "DrawingArea" una riga colorata con tutta la gamma dei colori dal blu al rosso. Successivamente, cliccando sulla "PictureBox" l'immagine del disegno presente nella "DrawingArea" sarà mostrato in una "PictureBox".
La seconda modalità prevede l'assegnazione dei dati dei pixel della ''DrawingArea'' all'area di memoria puntata dal membro "''*data''" della Struttura "''GB_IMG''" contenuta nel file sorgente "''.../main/lib/image/gb.image.h''". <SUP>&#91;[[#Note|nota 1]]&#93;</sup>
 
 
 
 
 
Mostriamo di seguito un semplice esempio, nel quale disegneremo all'interno di una ''DrawingArea'' una riga colorata con tutta la gamma dei colori dal blu al rosso. Al termine salveremo in un file immagine il disegno presente nella ''DrawingArea''.
 
 
<BR>Funziona solo su sistemi a 64-bit.
 
<BR>Funziona solo su sistemi a 64-bit.
  Library "libX11:6.3.0"
+
  Library "libX11:6.4.0"
 
   
 
   
 
  Private Enum XYBitmap = 0, XYPixmap, ZPixmap
 
  Private Enum XYBitmap = 0, XYPixmap, ZPixmap
Riga 131: Riga 130:
 
  <FONT Color=gray>' ''Display *XOpenDisplay(char *display_name)''
 
  <FONT Color=gray>' ''Display *XOpenDisplay(char *display_name)''
 
  ' ''Opens a connection to the X server that controls a display.''</font>
 
  ' ''Opens a connection to the X server that controls a display.''</font>
  Private Extern XOpenDisplay(display$ As String) As Pointer
+
  Private Extern XOpenDisplay(display_name As Pointer) As Pointer
 
   
 
   
 
  <FONT Color=gray>' ''unsigned long XAllPlanes()''
 
  <FONT Color=gray>' ''unsigned long XAllPlanes()''
Riga 139: Riga 138:
 
  <FONT Color=gray>' ''XImage *XGetImage(Display *display, Drawable d, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, int format)''
 
  <FONT Color=gray>' ''XImage *XGetImage(Display *display, Drawable d, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, int format)''
 
  ' ''Returns a pointer to an XImage structure.''</font>
 
  ' ''Returns a pointer to an XImage structure.''</font>
  Private Extern XGetImage(displayP As Pointer, d As Long, xI As Integer, yI As Integer, wid As Integer, hei As Integer, plane_mask As Long, formatI As Integer) As Pointer
+
  Private Extern XGetImage(displayP As Pointer, d As Long, x As Integer, y As Integer, width As Integer, height As Integer, plane_mask As Long, format_ As Integer) As Pointer
 
    
 
    
 
  <FONT color=gray>' ''XCloseDisplay(Display *display)''
 
  <FONT color=gray>' ''XCloseDisplay(Display *display)''
 
  ' ''Closes the connection to the X server for the display specified in the Display structure and destroys all windows.''</font>
 
  ' ''Closes the connection to the X server for the display specified in the Display structure and destroys all windows.''</font>
  Private Extern XCloseDisplay(displayP As Pointer)
+
  Private Extern XCloseDisplay(display As Pointer)
 
   
 
   
 
    
 
    
 
  '''Public''' Sub Form_Open()
 
  '''Public''' Sub Form_Open()
 
    
 
    
   DrawingArea1.Background = Color.White
+
   With DrawingArea1
+
    .X = 10
  '''End'''
+
    .Y = 10
+
    .W = 320
 +
    .H = 120
 +
    .Background = Color.White
 +
  End With
 +
  With PictureBox1
 +
    .X = DrawingArea1.X
 +
    .Y = DrawingArea1.H + 40
 +
    .W = DrawingArea1.W
 +
    .H = DrawingArea1.H
 +
    .Background = Color.White
 +
  End With
 +
 
 +
  '''End'''  
 
   
 
   
 
  '''Public''' Sub DrawingArea1_Draw()
 
  '''Public''' Sub DrawingArea1_Draw()
 
    
 
    
 
   Dim c As Integer[] = [Color.Blue, Color.Green, Color.Yellow, Color.Red]
 
   Dim c As Integer[] = [Color.Blue, Color.Green, Color.Yellow, Color.Red]
   Dim p As Float[] = [0, 0.34, 0.67, 1]
+
   Dim ff As Float[] = [0, 0.34, 0.67, 1]
 
      
 
      
 
  <FONT Color=gray>' ''Disegnamo all'interno della "DrawingArea":''</font>
 
  <FONT Color=gray>' ''Disegnamo all'interno della "DrawingArea":''</font>
  With Paint
+
  With Paint
    .Brush = .LinearGradient(10, 40, 300, 40, c, p)
+
    .Brush = .LinearGradient(10, 40, 300, 40, c, ff)
    .Rectangle(10, 40, 300, 40)
+
    .Rectangle(10, 40, 300, 40)
    .Fill
+
    .Fill
    .End
+
    .End
  End With
+
  End With
 
   
 
   
 
  '''End'''
 
  '''End'''
 
   
 
   
+
  '''Public''' Sub PictureBox1_MouseDown() <FONT Color=gray>' ''Cliccando sulla "PictureBox" avviene il passaggio dei dati grezzi dei pixel''</font>
  '''Public''' Sub Button1_Click()
 
 
    
 
    
 
   Dim dsp, XImage, imago, p, p1 As Pointer
 
   Dim dsp, XImage, imago, p, p1 As Pointer
Riga 177: Riga 187:
 
   Dim im As Image
 
   Dim im As Image
 
      
 
      
  dsp = XOpenDisplay(Null)
+
  dsp = XOpenDisplay(0)
  If dsp = 0 Then Error.Raise("Impossibile aprire una connessione al server X !")
+
  If dsp == 0 Then Error.Raise("Impossibile aprire una connessione al server X !")
 
      
 
      
 
  <FONT Color=gray>' ''Otteniamo un puntatore alla "Struttura" contenente i dati dell'immagine disegnata nella "DrawingArea":''</font>
 
  <FONT Color=gray>' ''Otteniamo un puntatore alla "Struttura" contenente i dati dell'immagine disegnata nella "DrawingArea":''</font>
  XImage = XGetImage(dsp, DrawingArea1.Handle, 0, 0, DrawingArea1.W, DrawingArea1.H, XAllPlanes(), ZPixmap)
+
  XImage = XGetImage(dsp, DrawingArea1.Handle, 0, 0, DrawingArea1.W, DrawingArea1.H, XAllPlanes(), ZPixmap)
  If XImage = 0 Then Error.Raise("Impossibile ottenere un 'Puntatore' ai dati dell'immagine della DrawingArea !")
+
  If XImage == 0 Then Error.Raise("Impossibile ottenere un 'Puntatore' ai dati dell'immagine della DrawingArea !")
 
    
 
    
 
  <FONT Color=gray>' ''Otteniamo l'indirizzo di memoria dei dati grezzi dell'immagine puntati dalla Struttura "XImage":''</font>
 
  <FONT Color=gray>' ''Otteniamo l'indirizzo di memoria dei dati grezzi dell'immagine puntati dalla Struttura "XImage":''</font>
  imago = Pointer@(XImage + 16)
+
  imago = Pointer@(XImage + 16)
 +
  If imago == 0 Then Error.Raise("Errore !")
 
      
 
      
  bb = New Byte[]     
+
  bb = New Byte[]     
 
    
 
    
  For i = 0 To (DrawingArea1.W * DrawingArea1.H * 4) - 1
+
  For i = 0 To (DrawingArea1.W * DrawingArea1.H * 4) - 1
    bb.Push(Byte@(imago + i))
+
    bb.Push(Byte@(imago + i))
  Next
+
  Next
 
      
 
      
  im = New Image(DrawingArea1.W, DrawingArea1.H)
+
  im = New Image(DrawingArea1.W, DrawingArea1.H)
 
      
 
      
  p = Object.Address(im)
+
  p = Object.Address(im)
 
      
 
      
  p1 = Pointer@(p + 16)
+
  p1 = Pointer@(p + (SizeOf(gb.Pointer) * 2))
 
      
 
      
  <FONT Color=gray>' ''Scriviamo i dati immagine grezzi, ottenuti dalla funzione XGetImage(), nell'area di memoria''
+
  <FONT Color=gray>' ''Scriviamo i dati immagine grezzi, ottenuti dalla funzione XGetImage(), nell'area di memoria puntata dal membro "*data" della Struttura "GB_IMG" contenuta nel file sorgente ".../main/lib/image/gb.image.h":''</font>
' ''puntata dal membro "*data" della Struttura "GB_IMG" contenuta nel file sorgente ".../main/lib/image/gb.image.h":''</font>
+
  st = Memory p1 For Write
  st = Memory p1 For Write
+
  bb.Write(st, 0, bb.Count)
  bb.Write(st, 0, bb.Count)
+
  st.Close
  st.Close
 
 
    
 
    
  <FONT Color=gray>' ''Come verifica finale mostriamo in una "PictureBox" i dati contenuti nella variabile di tipo "Image",''
+
  <FONT Color=gray>' ''Come verifica finale mostriamo in una "PictureBox" i dati contenuti nella variabile di tipo "Image", dopo averla convertita opportunamente in una variabile di tipo "Picture":''</font>
' ''dopo averla convertita opportunamente in una variabile di tipo "Picture":''</font>
+
  PictureBox1.Image = im
  PictureBox1.Picture = im.Picture
 
 
 
 
    
 
    
 
  <FONT Color=gray>' ''Va in chiusura:''</font>
 
  <FONT Color=gray>' ''Va in chiusura:''</font>
  XCloseDisplay(dsp)
+
  XCloseDisplay(dsp)
 
   
 
   
 
  '''End'''
 
  '''End'''
 
  
  

Versione attuale delle 15:49, 1 mag 2023

Per passare ad un oggetto Image i dati grezzi dei pixel del disegno presente in una DrawingArea, senza creare preliminarmente in ausilio un file immagine, si potranno utilizzare le risorse del API della libreria di X11.

In particolare si avranno almeno due modalità. In entrambe le modalità si dovrà richiamare in Gambas la libreria dinamica condivisa: "libX11.so.6.3.0 " , e sarà opportuno utilizzare un Componente Gambas delle librerie grafiche QT (gb.gui.qt oppure gb.qt5).

Passare i dati all'indirizzo dell'area di memoria restituito dalla Proprietà ".Data" dell'Oggetto "Image"

La prima modalità prevede il passaggio dei dati dei pixel all'indirizzo dell'area di memoria restituito dalla proprietà .Data dell'oggetto Image.

Si tratta di creare un Oggetto di tipo "Image", avente le medesime dimensioni della "DrawingArea", e di passare direttamente all'area di memoria puntata dalla proprietà ".Data" di detta variabile di tipo "Image" i dati grezzi dei pixel ottenuti dalla "DrawingArea" e contenuti nell'area di memoria riservata, puntata dal "Puntatore" restituito dalla funzione esterna "XGetImage()" della libreria di X11. Tutti i dati precedenti relativi ai pixel, comunque contenuti dalla variabile "Image", saranno sostituiti dai nuovi dati dei pixel afferenti al disegno presente nella DrawingArea.

Mostriamo un esempio pratico (è necessario porre sul "Form" una "DrawingArea" ed una "PictureBox").

Library "libX11:6.4.0"

Private Enum XYBitmap = 0, XYPixmap, ZPixmap

' Display *XOpenDisplay(char *display_name)
' Opens a connection to the X server that controls a display.
Private Extern XOpenDisplay(display_name As Pointer) As Pointer

' unsigned long XAllPlanes()
' Returns a value with all bits set to 1 suitable for use in a plane argument to a procedure.
Private Extern XAllPlanes() As Long

' XImage *XGetImage(Display *display, Drawable d, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, int format)
' Returns a pointer to an XImage structure.
Private Extern XGetImage(display As Pointer, d As Long, x As Integer, y As Integer, width As Integer, height As Integer, plane_mask As Long, format_ As Integer) As Pointer
 
' XCloseDisplay(Display *display)
' Closes the connection to the X server for the display specified in the Display structure and destroys all windows.
Private Extern XCloseDisplay(display As Pointer)


Public Sub Form_Open()

' Imposta alcune proprietà della "DrawingArea":
 With DrawingArea1
   .X = 10
   .Y = 10
   .W = 400
   .H = 420
   .Background = Color.White
 End With
 With PictureBox1
   .X = DrawingArea1.W + 20
   .Y = DrawingArea1.Y
   .W = DrawingArea1.W
   .H = DrawingArea1.H
 End With
 
End


Public Sub DrawingArea1_Draw()
 
 Dim colori As Integer[] = [Color.Blue, Color.Green, Color.Yellow, Color.Red]
 Dim ff As Float[] = [0, 0.34, 0.67, 1]
  
' Disegnamo all'interno della "DrawingArea":
 With Paint
   .Brush = .LinearGradient(10, 40, 300, 40, colori, ff)
   .Rectangle(10, 40, 300, 40)
   .Fill
' Imposta il colore dei caratteri:
   .Brush = .Color(Color.Red) 
' Imposta il tipo di carattere:
  .Font.Name = "Arial" 
' Imposta la dimensione dei caratteri:
  .Font.Size = 16
' Scrive sull'Area di Disegno il seguente testo di caratteri nella posizione X, Y all'interno di un quadrilatero virtuale W, H con i metodi .RichText  e .Text, ma occorrerà uno ".Stroke" a seguire (però .Stroke tende a dare l'effetto del grassetto):
  .RichText("testo con r i chText", 200, 20, 16, 100)
  .Text("Testo con Text", 10, 30, 20, 20)
  .Stroke
' ...oppure (meglio, perché non dà l'effetto del grassetto) ".fill":
  .Fill
' Con il metodo .DrawText non è necessario l'uso di ".Stroke", né di ".Fill":
  .DrawText("Testo con DrawText", 10, 10, 20, 20)
  .End
 End With
  
End

Public Sub PictureBox1_MouseDown()  ' Cliccando sulla "PictureBox" avviene il passaggio dei dati grezzi dei pixel

 Dim dsp, XImage, dati_imm As Pointer
 Dim im As Image
 Dim st As Stream
 Dim i As Integer
  
 dsp = XOpenDisplay(0)
 If dsp == 0 Then Error.Raise("Impossibile aprire una connessione al server X !")
  
' Ottiene un puntatore alla "Struttura" contenente i dati dell'immagine disegnata nella "DrawingArea":
 XImage = XGetImage(dsp, DrawingArea1.Handle, 0, 0, DrawingArea1.W, DrawingArea1.H, XAllPlanes(), ZPixmap)
 If XImage == 0 Then Error.Raise("Impossibile ottenere un 'Puntatore' ai dati dell'immagine della DrawingArea !")
  
' Ottiene l'indirizzo di memoria dei dati grezzi dell'immagine puntati dalla Struttura "XImage":
 dati_imm = Pointer@(XImage + (SizeOf(gb.Pointer) * 2))
 If dati_imm == 0 Then Error.Raise("Errore !")
  
' Crea un semplice oggetto di tipo "Image":
 im = New Image(DrawingArea1.W, DrawingArea1.H)
 If IsNull(im) Then Error.Raise("Impossibile creare un oggetto 'Image' !")
  
' Utilizza i "Memory Stream" per scrivere nell'area di memoria dell'oggetto "Image", destinata ai dati attinenti ai pixel, il cui indirizzo di memoria è ritornato dalla proprietà ".Data" della variabile di tipo "Image":
 st = Memory im.Data For Write
  
 For i = 0 To im.W * im.H * (im.Depth / 8)
   Write #st, Byte@(dati_imm + i) As Byte
 Next
  
 st.Close
 
' Come verifica finale mostriamo in una "PictureBox" i dati contenuti nella variabile di tipo "Image", dopo averla convertita opportunamente in una variabile di tipo "Picture":
 PictureBox1.Image = im
  
' Va in chiusura:
 XCloseDisplay(dsp)
  
End


Passare i dati all'area di memoria puntata dal membro "*data " della Struttura "GB_IMG " dichiarata nel file sorgente "gb.image.h"

La seconda modalità prevede l'assegnazione dei dati dei pixel della "DrawingArea" all'area di memoria puntata dal membro "*data " della Struttura "GB_IMG " contenuta nel file sorgente ".../main/lib/image/gb.image.h ". [nota 1]

Mostriamo di seguito un semplice esempio, nel quale disegneremo all'interno di una "DrawingArea" una riga colorata con tutta la gamma dei colori dal blu al rosso. Successivamente, cliccando sulla "PictureBox" l'immagine del disegno presente nella "DrawingArea" sarà mostrato in una "PictureBox".
Funziona solo su sistemi a 64-bit.

Library "libX11:6.4.0"

Private Enum XYBitmap = 0, XYPixmap, ZPixmap

' Display *XOpenDisplay(char *display_name)
' Opens a connection to the X server that controls a display.
Private Extern XOpenDisplay(display_name As Pointer) As Pointer

' unsigned long XAllPlanes()
' Returns a value with all bits set to 1 suitable for use in a plane argument to a procedure.
Private Extern XAllPlanes() As Long

' XImage *XGetImage(Display *display, Drawable d, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, int format)
' Returns a pointer to an XImage structure.
Private Extern XGetImage(displayP As Pointer, d As Long, x As Integer, y As Integer, width As Integer, height As Integer, plane_mask As Long, format_ As Integer) As Pointer
 
' XCloseDisplay(Display *display)
' Closes the connection to the X server for the display specified in the Display structure and destroys all windows.
Private Extern XCloseDisplay(display As Pointer)

 
Public Sub Form_Open()
  
 With DrawingArea1
   .X = 10
   .Y = 10
   .W = 320
   .H = 120
   .Background = Color.White
 End With
 With PictureBox1
   .X = DrawingArea1.X
   .Y = DrawingArea1.H + 40
   .W = DrawingArea1.W
   .H = DrawingArea1.H
   .Background = Color.White
 End With
 
End 

Public Sub DrawingArea1_Draw()
  
 Dim c As Integer[] = [Color.Blue, Color.Green, Color.Yellow, Color.Red]
 Dim ff As Float[] = [0, 0.34, 0.67, 1]
   
' Disegnamo all'interno della "DrawingArea":
 With Paint
   .Brush = .LinearGradient(10, 40, 300, 40, c, ff)
   .Rectangle(10, 40, 300, 40)
   .Fill
   .End
 End With

End

Public Sub PictureBox1_MouseDown()  ' Cliccando sulla "PictureBox" avviene il passaggio dei dati grezzi dei pixel
 
 Dim dsp, XImage, imago, p, p1 As Pointer
 Dim bb As Byte[]
 Dim i As Integer
 Dim st As Stream
 Dim im As Image
   
 dsp = XOpenDisplay(0)
 If dsp == 0 Then Error.Raise("Impossibile aprire una connessione al server X !")
   
' Otteniamo un puntatore alla "Struttura" contenente i dati dell'immagine disegnata nella "DrawingArea":
 XImage = XGetImage(dsp, DrawingArea1.Handle, 0, 0, DrawingArea1.W, DrawingArea1.H, XAllPlanes(), ZPixmap)
 If XImage == 0 Then Error.Raise("Impossibile ottenere un 'Puntatore' ai dati dell'immagine della DrawingArea !")
 
' Otteniamo l'indirizzo di memoria dei dati grezzi dell'immagine puntati dalla Struttura "XImage":
 imago = Pointer@(XImage + 16)
 If imago == 0 Then Error.Raise("Errore !")
    
 bb = New Byte[]    
  
 For i = 0 To (DrawingArea1.W * DrawingArea1.H * 4) - 1
   bb.Push(Byte@(imago + i))
 Next
   
 im = New Image(DrawingArea1.W, DrawingArea1.H)
   
 p = Object.Address(im)
   
 p1 = Pointer@(p + (SizeOf(gb.Pointer) * 2))
   
' Scriviamo i dati immagine grezzi, ottenuti dalla funzione XGetImage(), nell'area di memoria puntata dal membro "*data" della Struttura "GB_IMG" contenuta nel file sorgente ".../main/lib/image/gb.image.h":
 st = Memory p1 For Write
 bb.Write(st, 0, bb.Count)
 st.Close
  
' Come verifica finale mostriamo in una "PictureBox" i dati contenuti nella variabile di tipo "Image", dopo averla convertita opportunamente in una variabile di tipo "Picture":
 PictureBox1.Image = im
  
' Va in chiusura:
 XCloseDisplay(dsp)

End


Note

[1] Al riguardo vedasi anche la pagina della Wiki: Gestire un oggetto Image agendo direttamente sulle risorse dei sorgenti Gambas