Ottenere il valore di un pixel in una DrawingArea mediante le funzioni esterne del API di X11

Da Gambas-it.org - Wikipedia.

Per ottenere il valore di un pixel presente in una DrawingArea, è possibile utilizzare alcune funzioni esterne della libreria di X11. Ciò è possibile, in quanto la DrawingArea non è nient'altro che una finestra come le altre, avente un proprio numero identificativo, sulla quale si potrà agire con la predetta libreria di X11.

Sarà necessario richiamare nell'applicativo Gambas la libreria di X attualmente: "libX11.so.6.3.0"


Mostriamo di seguito un breve codice, nel quale disegneremo all'interno di una DrawingArea una riga colorata con tutta la gamma dei colori dal blu al rosso. Individuiremo un pixel facente parte di tale riga colorata della DrawingArea, e ne mostreremo il valore in rappresentazione esadecimale:

Library "libX11:6.3.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$ As String) 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, xI As Integer, yI As Integer, wid As Integer, hei As Integer, plane_mask As Long, formatI As Integer) As Pointer

' unsigned long XGetPixel(XImage *ximage, int x, int y)
' Returns the specified pixel from the named image.
Private Extern XGetPixel(ximage As Pointer, xI As Integer, yI As Integer) As Long

' 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(displayP As Pointer)


Public Sub Form_Open()
  
 DrawingArea1.Background = Color.White

End


Public Sub DrawingArea1_Draw()
  
 Dim c As Integer[] = [Color.Blue, Color.Green, Color.Yellow, Color.Red]
 Dim p As Float[] = [0, 0.34, 0.67, 1]

' Disegnamo all'interno della "DrawingArea":
  With Paint
    .Brush = .LinearGradient(10, 40, 300, 40, c, p)
    .Rectangle(10, 40, 300, 40)
    .Fill
    .End
  End With

End


Public Sub Button1_Click()

 Dim dsp, XImage As Pointer
 
  dsp = XOpenDisplay(Null)
  If IsNull(dsp) 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(), XYPixmap)
  If IsNull(XImage) Then Error.Raise("Impossibile ottenere un 'Puntatore' ai dati dell'immagine della DrawingArea !")

' Mostriamo il valore in esadecimale di un pixel posto alle coordinate stabilite nel 2° e 3° parametro della seguente funzione:
  Print Hex(XGetPixel(XImage, 290, 52), 8)

' Va in chiusura:
  XCloseDisplay(dsp)

End



Riferimenti