Differenze tra le versioni di "Ottenere un'immagine del Form"
Riga 167: | Riga 167: | ||
st.Close | st.Close | ||
+ | <FONT Color=gray>' ''Genera in fine il file immagine:''</font> | ||
+ | im.Save("<FONT Color=gray>''/percorso/del/file/immagine.xxx''</font>", 100) | ||
+ | |||
+ | <FONT Color=gray>' ''Va in chiusura:''</font> | ||
+ | XCloseDisplay(dsp) | ||
+ | |||
+ | '''End''' | ||
+ | oppure anche così: | ||
+ | Library "libX11:6.3.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 | ||
+ | |||
+ | <FONT Color=gray>' ''Display *XOpenDisplay(char *display_name)'' | ||
+ | ' ''Opens a connection to the X server that controls a display.''</font> | ||
+ | Private Extern XOpenDisplay(display_name As Pointer) As Pointer | ||
+ | |||
+ | <FONT Color=gray>' ''unsigned long XAllPlanes()'' | ||
+ | ' ''Returns a value with all bits set to 1 suitable for use in a plane argument to a procedure.''</font> | ||
+ | Private Extern XAllPlanes() As Long | ||
+ | |||
+ | <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> | ||
+ | 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 | ||
+ | |||
+ | <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> | ||
+ | Private Extern XCloseDisplay(display As Pointer) | ||
+ | |||
+ | |||
+ | '''Public''' Sub Form_Open() | ||
+ | |||
+ | TextBox1.Text = "Gambas" | ||
+ | PictureBox1.Picture = Picture.Load("<FONT Color=gray>' ''/percorso/del/file/immagine.png''</font>") | ||
+ | Button1.Foreground = Color.Red | ||
+ | Button1.Text = "Gambas" | ||
+ | |||
+ | '''End''' | ||
+ | |||
+ | '''Public''' Sub Form_Activate() | ||
+ | |||
+ | Dim dsp, p As Pointer | ||
+ | Dim xi As XImage | ||
+ | Dim bb As Byte[] | ||
+ | Dim i As Integer | ||
+ | Dim st As Stream | ||
+ | Dim im As Image | ||
+ | |||
+ | <FONT Color=gray>' ''Resta in attesa un po' per consentire che il Form si apra completamente mostrando anche gli Oggetti "figli" da esso contenuti:''</font> | ||
+ | Sleep 0.5 | ||
+ | |||
+ | dsp = XOpenDisplay(0) | ||
+ | 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 nel "Form":''</font> | ||
+ | xi = XGetImage(dsp, Me.Handle, 0, 0, Me.W, DrawingArea1.H, XAllPlanes(), ZPixmap) | ||
+ | If IsNull(Image) Then Error.Raise("Impossibile ottenere un 'Puntatore' ai dati dell'immagine del Form !") | ||
+ | |||
+ | bb = New Byte[] | ||
+ | |||
+ | For i = 0 To (DrawingArea1.W * DrawingArea1.H * 4) - 1 | ||
+ | bb.Push(Byte@(xi.data + i)) | ||
+ | Next | ||
+ | |||
+ | <FONT Color=gray>' ''Creiamo un semplice oggetto di tipo "Image":''</font> | ||
+ | im = New Image(Me.W, Me.H) | ||
+ | If IsNull(im) Then Error.Raise("Impossibile creare un oggetto 'Image' !") | ||
+ | |||
+ | p = Pointer@(Object.Address(im) + (SizeOf(gb.Pointer) * 2)) | ||
+ | |||
+ | <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> | ||
+ | st = Memory p For Write | ||
+ | bb.Write(st, 0, bb.Count) | ||
+ | st.Close | ||
+ | |||
<FONT Color=gray>' ''Genera in fine il file immagine:''</font> | <FONT Color=gray>' ''Genera in fine il file immagine:''</font> | ||
im.Save("<FONT Color=gray>''/percorso/del/file/immagine.xxx''</font>", 100) | im.Save("<FONT Color=gray>''/percorso/del/file/immagine.xxx''</font>", 100) |
Versione delle 15:26, 7 mar 2018
Per ottenere un'immagine del Form, comprensivo di ogni Oggetto grafico figlio in esso contenuto, è possibile adottare almeno tre modalità.
Uso del Metodo .Screeshot( ) della Classe Desktop
La prima modalità prevede l'uso del Metodo .Screeshot( ) della Classe Desktop. Pertanto è necessario attivare anche i Componenti "gb.desktop" e "gb.desktop.x11" di Gambas.
Con il Metodo .Screeshot( ) si otterrà una Picture dell'Oggetto (il Form in tal caso) posto a una distanza x, y del medesimo dall'angolo alto sinistro dello schermo.
Nell'esempio pratico che segue, porremo sul Form un TextBox, una PictureBox, per far mostrare un qualsiasi file immagine, e un Button. Si provvederà a effettuare la schermata del Form, pochissimo tempo dopo che questo si sarà attivato.
Public Sub Form_Open() TextBox1.Text = "Gambas" PictureBox1.Picture = Picture.Load("' /percorso/del/file/immagine.png") Button1.Foreground = Color.Red Button1.Text = "Gambas" End Public Sub Form_Activate() Dim pc As Picture ' Resta in attesa un po' per consentire che il Form si apra completamente mostrando anche gli Oggetti "figli" da esso contenuti: Sleep 0.5 ' Effettua la schermata del Form, generando un Oggetto di tipo "Picture": pc = Desktop.Screenshot(Me.ScreenX, Me.ScreenY, Me.W, Me.H) ' Salva la schermata in un file immagine di tipo "png": pc.Save("/tmp/test.png", 100) End
Uso del Metodo .GetScreeshot( ) della Classe DesktopWindow
La seconda malità prevede l'uso del Metodo .GetScreeshot( ) della Classe DesktopWindow. Pertanto è necessario attivare anche i Componenti "gb.desktop" e "gb.desktop.x11" di Gambas.
Con il Metodo .GetScreeshot( ) si otterrà una Picture dell'Oggetto (il Form in tal caso) posto a una distanza x, y del medesimo dall'angolo alto sinistro dello schermo.
Nell'esempio pratico che segue, porremo sul Form un TextBox, una PictureBox, per far mostrare un qualsiasi file immagine, e un Button. Anche in questo caso si provvederà a effettuare la schermata del Form, pochissimo tempo dopo che questo si sarà attivato.
Public Sub Form_Open() TextBox1.Text = "Gambas" PictureBox1.Picture = Picture.Load("' /percorso/del/file/immagine.png") Button1.Foreground = Color.Red Button1.Text = "Gambas" End Public Sub Form_Activate() Dim dw As DesktopWindow Dim pc As Picture ' Resta in attesa un po' per consentire che il Form si apra completamente mostrando anche gli Oggetti "figli" da esso contenuti: Sleep 0.5 ' Genera una variabile di tipo "DesktopWindow" che punta al Form, avendo individuato il numero identificativo della finestra del Form medesimo: With dw = New DesktopWindow(Me.Id) ' Effettua la schermata del Form, generando un Oggetto di tipo "Picture": pc = .GetScreenshot(True) End With ' Salva la schermata in un file immagine di tipo "png": pc.Save("/tmp/test.png", 100) End
Uso delle funzioni esterne del API di X11
Questa modalità prevede l'uso di alcune funzioni esterne appartenenti al API del sistema grafico X11. E' pertanto richiesta la dichiarazione in Gambas della libreria dinamica condivisa: "libX11.so.6.3.0"
L'assegnazione dei dati dei pixel della DrawingArea, contenuti nell'area di memoria puntata dal Puntatore restituito dalla funzione esterna XGetImage( ) della libreria di X11, direttamente all'area di memoria puntata dalla proprietà .Data di un oggetto Image preliminarmente creato.
Nell'esempio pratico che segue, porremo sul Form un TextBox, una PictureBox, per far mostrare un qualsiasi file immagine, e un Button. Anche in questo caso si provvederà a effettuare la schermata del Form, pochissimo tempo dopo che questo si sarà attivato.
Library "libX11:6.3.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 Form_Open() TextBox1.Text = "Gambas" PictureBox1.Picture = Picture.Load("' /percorso/del/file/immagine.png") Button1.Foreground = Color.Red Button1.Text = "Gambas" End Public Sub Form_Activate() Dim dsp As Pointer Dim xi As XImage Dim im As Image Dim st As Stream Dim i As Integer ' Resta in attesa un po' per consentire che il Form si apra completamente mostrando anche gli Oggetti "figli" da esso contenuti: Sleep 0.5 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 nel "Form": xi = XGetImage(dsp, Me.Handle, 0, 0, Me.W, DrawingArea1.H, XAllPlanes(), ZPixmap) If IsNull(Image) Then Error.Raise("Impossibile ottenere un 'Puntatore' ai dati dell'immagine del Form !") ' Creiamo un semplice oggetto di tipo "Image": im = New Image(Me.W, Me.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: im.Save("/percorso/del/file/immagine.xxx", 100) ' Va in chiusura: XCloseDisplay(dsp) End
oppure anche così:
Library "libX11:6.3.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 Form_Open() TextBox1.Text = "Gambas" PictureBox1.Picture = Picture.Load("' /percorso/del/file/immagine.png") Button1.Foreground = Color.Red Button1.Text = "Gambas" End Public Sub Form_Activate() Dim dsp, p As Pointer Dim xi As XImage Dim bb As Byte[] Dim i As Integer Dim st As Stream Dim im As Image ' Resta in attesa un po' per consentire che il Form si apra completamente mostrando anche gli Oggetti "figli" da esso contenuti: Sleep 0.5 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 nel "Form": xi = XGetImage(dsp, Me.Handle, 0, 0, Me.W, DrawingArea1.H, XAllPlanes(), ZPixmap) If IsNull(Image) Then Error.Raise("Impossibile ottenere un 'Puntatore' ai dati dell'immagine del Form !") bb = New Byte[] For i = 0 To (DrawingArea1.W * DrawingArea1.H * 4) - 1 bb.Push(Byte@(xi.data + i)) Next ' Creiamo un semplice oggetto di tipo "Image": im = New Image(Me.W, Me.H) If IsNull(im) Then Error.Raise("Impossibile creare un oggetto 'Image' !") p = Pointer@(Object.Address(im) + (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 p For Write bb.Write(st, 0, bb.Count) st.Close ' Genera in fine il file immagine: im.Save("/percorso/del/file/immagine.xxx", 100) ' Va in chiusura: XCloseDisplay(dsp) End