Differenze tra le versioni di "Catturare l'immagine della finestra di un programma mediante le risorse della Classe DesktopWindow e le funzioni esterne del API di X11"

Da Gambas-it.org - Wikipedia.
 
Riga 55: Riga 55:
 
   
 
   
 
   
 
   
  '''Public''' Sub Button1_Click()
+
  Public Sub Button1_Click()
 
    
 
    
   dim dw As DesktopWindow
+
   Dim i As Integer
 +
  Dim dw As DesktopWindow
 
   Dim dsp As Pointer
 
   Dim dsp As Pointer
 
   Dim xi As XImage
 
   Dim xi As XImage
 
   Dim im As Image
 
   Dim im As Image
 
   Dim st As Stream
 
   Dim st As Stream
  Dim i As Integer
+
 
 
 
  <FONT Color=gray>' ''Individua il numero identificativo della finestra del programma VLC:''</font>
 
  <FONT Color=gray>' ''Individua il numero identificativo della finestra del programma VLC:''</font>
 
   i = Desktop.FindWindow("*VLC*", Null, Null)[0]
 
   i = Desktop.FindWindow("*VLC*", Null, Null)[0]
Riga 96: Riga 96:
 
   XCloseDisplay(dsp)
 
   XCloseDisplay(dsp)
 
    
 
    
  '''End'''
+
  End
  
  

Versione attuale delle 16:40, 10 giu 2024

Per catturare l'immagine della finestra di un qualsiasi programma (ma più in generale qualsiasi fienstra) e salvare tale cattura in un file immagine, si potranno utilizzare le risorse della Classe DesktopWindow e alcune funzioni esterne del API di X11. [nota 1]

E' necessario richiamare in Gambas la libreria dinamica condivisa: "libX11.so.6.4.0 ".


Mostriamo un esempio pratico (bisognerà attivare i Componenti gb.desktop e gb.desktop.x11), nel quale sarà catturata un'immagine del programma audio VLC:

Library "libX11:6.4.0"

Public Struct funcs
  create_image As Pointer
  destroy_image As Pointer
  get_pixel As Pointer
  put_pixel As Pointer
  sub_image As Pointer
  add_pixel As Pointer
End Struct

Public Struct XImage
  width As Integer
  height As Integer
  xoffset As Integer
  gformat As Integer
  data As Pointer
  byte_order As Integer
  bitmap_unit As Integer
  bitmap_bit_order As Integer
  bitmap_pad As Integer
  depth As Integer
  bytes_per_line As Integer
  bits_per_pixel As Integer
  red_mask As Long
  green_mask As Long
  blue_mask As Long
  obdata As Pointer
  func As Struct Funcs
End Struct

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, xformat As Integer) As XImage

' 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 Button1_Click()
 
 Dim i As Integer
 Dim dw As DesktopWindow
 Dim dsp As Pointer
 Dim xi As XImage
 Dim im As Image
 Dim st As Stream

' Individua il numero identificativo della finestra del programma VLC:
 i = Desktop.FindWindow("*VLC*", Null, Null)[0]
  
' Si passa il numero identificatore della finestra alla Classe "DesktopWindows" per generare una variabile che punti a quella finestra:
 dw = New DesktopWindow(i)
  
 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":
 xi = XGetImage(dsp, i, 0, 0, dw.W, dw.H, XAllPlanes(), ZPixmap)
 If IsNull(xi) Then Error.Raise("Impossibile ottenere un 'Puntatore' ai dati dell'immagine della DrawingArea !")
    
' Creiamo un semplice oggetto di tipo "Image":
 im = New Image(dw.W, dw.H)
 If IsNull(im) Then Error.Raise("Impossibile creare un oggetto 'Image' !")
  
' Utilizziamo ovviamente 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 * Len(im.Format)
   Write #st, Byte@(xi.data + i) As Byte
 Next
  
 st.Close
  
' Genera in fine il file immagine finale:
 im.Save("/tmp/test.png", 100)
 
' Va in chiusura:
 XCloseDisplay(dsp)
  
End


Note

[1] Vedi anche le seguenti pagine: