Differenze tra le versioni di "Estrarre e salvare singole immagini da una ripresa video mediante WebCam effettuata con il Componente gb.media"

Da Gambas-it.org - Wikipedia.
(Creata pagina con "A volte può essere necessario estrarre e salvare in appositi file singole immagini di una ripresa video effettuata mediante una WebCam con il Componente ''gb.media'' . Per fa...")
 
 
(27 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
A volte può essere necessario estrarre e salvare in appositi file singole immagini di una ripresa video effettuata mediante una WebCam con il Componente ''gb.media'' . Per fare ciò, si raccoglierà mediante il metodo "''.GetScreenshot( )''" della Classe ''DesktopWindow'' quanto appare sulla superficie video utilizzata. Per individuare utilmente tale superficie video, è necessario individuare il suo ''handle''.
+
A volte può essere necessario estrarre e salvare in appositi file singole immagini di una ripresa video effettuata mediante una WebCam con il Componente ''gb.media''. <SUP>&#091;[[#Note|nota 1]]&#093;</sup>
<BR>E' necessario attivare nell'applicazione Gambas i Componenti "''gb.desktop''" e "''gb.desktop.x11''". <SUP>&#091;[[#Note|Nota 1]]&#093;</sup>
+
<BR>Per fare ciò, sono disponibili alcune modalità.
  
Mostriamo di seguito un esempio pratico, nel quale si salverà in un vettore di tipo ''Picture[ ]'' ogni 300 millesimi di secondo un'immagine del video, mostrato all'interno di una ''DrawingArea''. Al termine della ripresa video si provvederà a salvare ciascuna immagine, salvata nel predetto vettore, in un file immagine di tipo ''png''.
+
E' il caso di sottolineare che <SPAN Style="text-decoration:underline">bisognerà creare progetti '''''QT''' Application''</span>, altrimenti usando i Componenti GTK detti codici non funzioneranno a dovere.
 +
 
 +
 
 +
===Usare la Classe ''MediaPlayer'' con una ''PictureBox''===
 +
Innanzitutto è possibile usare la Classe ''MediaPlayer''. In particolare, per catturare le singole immagini, si utilizzerà in tal caso la sotto-Proprietà ".Image" della Proprietà "Video" della Classe ''MediaPlayer''.
 +
 
 +
Mostriamo un esempio in ambiente grafico, nel quale si utilizzerà una ''PictureBox'' per mostrare il video e un'altra per mostrare l'immagine catturata:
 +
Private mp As MediaPlayer
 +
 +
 +
Public Sub Form_Open()
 +
 
 +
  With mp = new MediaPlayer
 +
    .URL = "v4l2:///dev/video0"
 +
    .SetWindow(PictureBox1)    ' <SUP>&#091;[[#Note|nota 2]]&#093;</sup>
 +
    .Play()
 +
  End With
 +
 
 +
End
 +
 
 +
 +
Public Sub Button1_Click() <FONT Color=gray>' ''Cliccando sul tasto, si catturerà un'immagine dal video''</font>
 +
 
 +
  Dim im As Image
 +
 
 +
  im = mp.Video.Image
 +
 
 +
  im.Save("/tmp" &/ Format(Now, "dd:mm:yyyy_hh:nn:ss.uu") & ".png")
 +
 
 +
  PictureBox2.Image = im.Stretch(PictureBox2.W, PictureBox2.H)
 +
 
 +
End
 +
 
 +
 
 +
===Usare le Classi ''MediaPlayer'', ''MediaControl'' con una ''DrawingArea''===
 +
E' possibile usare le Classi ''MediaPlayer'' e ''MediaControl''.
 +
 
 +
Mostriamo di seguito un semplice esempio, nel quale la ripresa sarà mostrata all'interno di una ''DrawingArea'', e sarà salvata ogni secondo - grazie all'uso dell'Oggetto ''Timer'' - un'immagine della ripresa all'interno di un file immagine di formato PNG.
 +
Private mp As MediaPlayer
 +
Private im As MediaControl
 +
Private drar As DrawingArea
 +
Private tb As ToggleButton
 +
Private tempus As Timer
 +
Private i As Integer
 +
 +
 +
Public Sub Form_Open()
 +
 +
  Dim flt As MediaFilter
 +
 +
  With Me
 +
    .W = Screen.AvailableWidth * 0.75
 +
    .H = Screen.AvailableHeight * 0.75
 +
  End With
 +
  With drar = New DrawingArea(Me)
 +
    .X = Me.W * 0.05
 +
    .Y = Me.H * 0.05
 +
    .W = Me.W * 0.9
 +
    .H = Me.H * 0.8
 +
    .Border = Border.Plain
 +
  End With
 +
  With tb = New ToggleButton(Me) As "Tasto"
 +
    .W = Me.W * 0.1
 +
    .H = Me.H * 0.05
 +
    .X = (Me.W / 2) - (.W / 2)
 +
    .Y = 0
 +
    .Text = "Avvia"
 +
  End With
 +
 +
  If Not Exist("/tmp/immagini") Then Mkdir "/tmp/immagini"
 +
 +
  mp = New MediaPlayer As "MediaPlayer"
 +
  flt = New MediaFilter(mp, "video/x-raw,width=640,height=480,framerate=30/1")
 +
  im = New MediaControl(mp, "xvimagesink")
 +
 +
End
 +
 +
 +
Public Sub Tasto_Click()
 +
 +
  mp.Video.Output = im
 +
  mp.URL = "v4l2:///dev/video0"
 +
 
 +
  im.SetWindow(drar)
 +
 
 +
  If tb.Value Then
 +
    mp.Play
 +
    With tempus = New Timer As "Tempus"
 +
      .Delay = 1000
 +
      .Start()
 +
    End With
 +
    tb.Text = "Stop"
 +
  Else
 +
    mp.Stop
 +
    mp.Close
 +
    tempus.Stop
 +
    tb.Text = "Avvia"
 +
  Endif
 +
 
 +
End
 +
 +
 +
Public Sub Tempus_Timer()
 +
 +
  Dim img As Image
 +
 +
  img = mp.Video.Image
 +
  Inc i
 +
 +
  img.Save("/tmp/immagini/foto_" & CStr(i) & ".png", 100)
 +
 +
  Write #File.out, "\rImmagini catturate: " & CStr(i)
 +
 +
End
 +
 
 +
 
 +
 +
===Usare il Metodo ".GetLastImage()" della Classe ''MediaControl'' per catturare singole immagini dal video, e utilizzare una ''DrawingArea'' per mostrare la ripresa video===
 +
Quest'altra modalità prevede che:
 +
* sia utilizzata una ''DrawingArea'', come superficie ove mostrare la ripresa video;
 +
* sia utilizzato il Metodo ".GetLastImage()" della Classe ''MediaControl'' per catturare singole immagini dal video.
 +
 
 +
Mostriamo di seguito un esempio pratico, nel quale la cattura delle immagini dalla ripresa video avviene ogni 500 millisecondi:
 +
Private pl As MediaPipeline
 +
Private snk As MediaControl
 +
 +
 +
Public Sub Form_Open()
 +
 
 +
  Dim src, cnv As MediaControl
 +
  Dim ftr As MediaFilter
 +
  Dim dr As DrawingArea
 +
 
 +
  With dr = New DrawingArea(Me)
 +
    .X = 10
 +
    .Y = 10
 +
    .W = 640
 +
    .H = 480
 +
  End With
 +
 
 +
  pl = New MediaPipeline
 +
 
 +
  src = New MediaControl(pl, "v4l2src")
 +
  src["device"] = "/dev/video0"
 +
 
 +
  ftr = New MediaFilter(pl)
 +
  ftr.Filter = "video/x-raw,width=640,height=480,framerate=30/1"
 +
  cnv = New MediaControl(pl, "videoconvert")
 +
  snk = New MediaControl(pl, "xvimagesink")
 +
   
 +
  src.LinkTo(ftr)
 +
  ftr.LinkTo(cnv)
 +
  cnv.LinkTo(snk)
 +
 
 +
<FONT Color=gray>' ''Imposta la DrawingArea come superficie ove mostrare la ripresa video:''</font>
 +
  snk.SetWindow(dr)
 +
 
 +
End
 +
 +
 +
Public Sub Button1_Click()
 +
 
 +
  Dim i As Integer
 +
  Dim drc, s As String
 +
 
 +
  drc = "/tmp/immagini"
 +
 
 +
  If Not Exist(drc) Then
 +
    Mkdir drc
 +
  Else
 +
    For Each s In Dir(drc, "immagine_*", gb.file)
 +
      Kill drc &/ s
 +
    Next
 +
  Endif
 +
 
 +
  pl.Play()
 +
 
 +
  While pl.State = Media.Playing
 +
    snk.GetLastImage().Save(drc &/ "immagine_" & CStr(I) & ".png")
 +
    Print "Schermata video salvata nella cartella " & drc
 +
<FONT Color=gray>' ''Attende mezzo secondo per catturare un'altra immagine dalla ripresa video:''</font>
 +
    Wait 0.5
 +
    Inc i
 +
  Wend
 +
 
 +
End
 +
 +
 +
Public Sub Button2_Click()
 +
 +
  pl.Stop()
 +
  pl.Close()
 +
 
 +
End
 +
 
 +
 
 +
 
 +
===Usare il Metodo ".GetScreenshot()" della Classe ''DesktopWindow'' per catturare singole immagini dal video, e utilizzare una ''DrawingArea'' per mostrare la ripresa video===
 +
Con questa modalità si raccoglierà mediante il Metodo ".GetScreenshot()" della Classe ''DesktopWindow''  <SUP>&#091;[[#Note|Nota 3]]&#093;</sup> quanto appare sulla superficie video utilizzata. Per individuare utilmente tale superficie video, è necessario individuare il suo ''handle''.
 +
<BR>E' necessario attivare nell'applicazione Gambas i Componenti ''gb.desktop'' e ''gb.desktop.x11''.
 +
 
 +
Mostriamo di seguito un esempio pratico, nel quale si salverà in un vettore di tipo "Picture[]" ogni 300 millesimi di secondo un'immagine del video, mostrato all'interno di una ''DrawingArea''. Al termine della ripresa video si provvederà a salvare ciascuna immagine, salvata nel predetto vettore, in un file immagine di tipo ''png''.
 
  Private dr As DrawingArea
 
  Private dr As DrawingArea
 
  Private pl As MediaPipeline
 
  Private pl As MediaPipeline
Riga 8: Riga 209:
 
   
 
   
 
   
 
   
  '''Public''' Sub Form_Open()
+
  Public Sub Form_Open()
 
    
 
    
Dim src, tim, snk As MediaControl
+
  Dim src, tim, cnv, snk As MediaControl
Dim ftr As MediaFilter
+
  Dim ftr As MediaFilter
 
    
 
    
 
   With dr = New DrawingArea(Me)
 
   With dr = New DrawingArea(Me)
Riga 18: Riga 219:
 
     .W = 640
 
     .W = 640
 
     .H = 480
 
     .H = 480
<FONT Color=gray>' ''Affinche la "DrawingArea" mostri il video, è assolutamente necessario attribuire un colore qualsiasi alla sua proprietà ".Background":''</font>
 
    .Background = Color.Black
 
 
   End With
 
   End With
 
    
 
    
Riga 25: Riga 224:
 
    
 
    
 
   src = New MediaControl(pl, "v4l2src")
 
   src = New MediaControl(pl, "v4l2src")
 +
  src["device"] = "/dev/video0"
 
   ftr = New MediaFilter(pl, "video/x-raw,width=640,height=480,framerate=30/1")
 
   ftr = New MediaFilter(pl, "video/x-raw,width=640,height=480,framerate=30/1")
 
  <FONT Color=gray>' ''Mostra nel video anche il tempo trascorso dall'avvio della ripresa:''</font>
 
  <FONT Color=gray>' ''Mostra nel video anche il tempo trascorso dall'avvio della ripresa:''</font>
 
   tim = New MediaControl(pl, "timeoverlay")
 
   tim = New MediaControl(pl, "timeoverlay")
 +
  cnv = New MediaControl(pl, "videoconvert")
 
   snk = New MediaControl(pl, "xvimagesink")
 
   snk = New MediaControl(pl, "xvimagesink")
 
    
 
    
 
  <FONT Color=gray>' ''Colleghiamo i quattro plug-in di "GStreamer":''</font>
 
  <FONT Color=gray>' ''Colleghiamo i quattro plug-in di "GStreamer":''</font>
   src.LinkTo(tim)
+
   src.LinkTo(ftr)
   tim.LinkTo(ftr)
+
  ftr.LinkTo(tim)
   ftr.LinkTo(snk)
+
   tim.LinkTo(cnv)
 +
   cnv.LinkTo(snk)
 
   snk.SetWindow(dr)
 
   snk.SetWindow(dr)
 
    
 
    
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Public''' Sub Button1_Click()
+
  Public Sub Button1_Click()
 
+
 
   Dim dw As DesktopWindow
 
   Dim dw As DesktopWindow
 
    
 
    
 
  <FONT Color=gray>' ''Avvia la ripresa video della WebCam:''</font>
 
  <FONT Color=gray>' ''Avvia la ripresa video della WebCam:''</font>
  pl.State = Media.Playing
+
  pl.State = Media.Playing
  pl.Play()
+
  pl.Play()
 
    
 
    
 
  <FONT Color=gray>' ''Resta in attesa che la WebCam avvi effettivamente la ripresa video:''</font>
 
  <FONT Color=gray>' ''Resta in attesa che la WebCam avvi effettivamente la ripresa video:''</font>
  Wait 2
+
  Wait 2
 +
 
 +
  dw = New DesktopWindow(dr.Handle)
 
    
 
    
  While pl.State = Media.Playing
+
  While pl.State = Media.Playing
    With dw = New DesktopWindow(dr.Handle)
 
 
  <FONT Color=gray>' ''Cattura una schermata del contenuto video mostrato in quel momento dalla "DrawingArea":''</font>
 
  <FONT Color=gray>' ''Cattura una schermata del contenuto video mostrato in quel momento dalla "DrawingArea":''</font>
      pc.Push(.GetScreenshot(True))
+
    pc.Push(dw.GetScreenshot(True))
    End With
 
 
  <FONT Color=gray>' ''La cattura della schermata avviene ogni 300 millisecondi:''</font>
 
  <FONT Color=gray>' ''La cattura della schermata avviene ogni 300 millisecondi:''</font>
    Wait 0.3
+
    Wait 0.3
  Wend
+
  Wend
 
        
 
        
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Public''' Sub Button2_Click()    <FONT Color=gray>' ''Questo evento arresta la ripresa video e salva ogni picture in un file .png''</font>
+
  Public Sub Button2_Click()    <FONT Color=gray>' ''Questo evento arresta la ripresa video e salva ogni picture in un file .png''</font>
 
+
 
   Dim i As Integer
 
   Dim i As Integer
 
   Dim drc, s As String
 
   Dim drc, s As String
 
    
 
    
  drc = "/tmp/imago"
+
  drc = "/tmp/immago"
 
    
 
    
  pl.Stop
+
  pl.Stop
 
    
 
    
  If Not Exist(drc) Then
+
  If Not Exist(drc) Then
    Mkdir drc
+
    Mkdir drc
  Else
+
  Else
    For Each s In Dir(drc, "picture_*", gb.file)
+
    For Each s In Dir(drc, "picture_*", gb.file)
      Kill drc &/ s
+
      Kill drc &/ s
    Next
+
    Next
  Endif
+
  Endif
 
    
 
    
  For i = 0 To pc.Max
+
  For i = 0 To pc.Max
    pc[i].Save(drc &/ "picture_" & CStr(i) & ".png", 100)
+
    pc[i].Save(drc &/ "picture_" & CStr(i) & ".png", 100)
  Next
+
  Next
 
    
 
    
  '''End'''
+
  End
 +
 
 +
 
 +
===Usare il Metodo ".GetLastImage()" della Classe ''MediaControl'' per catturare singole immagini dal video, ma senza utilizzare una ''DrawingArea''===
 +
Quest'altra modalità prevede che:
 +
* non sia utilizzata una ''DrawingArea'', come superficie ove mostrare la ripresa video, bensì una superficie generata automaticamente da ''GStreamer'';
 +
* sia utilizzato il Metodo ".GetLastImage()" della Classe ''MediaControl'' per catturare singole immagini dal video.
  
 +
Mostriamo di seguito un esempio pratico:
 +
Private pl As MediaPipeline
 +
Private snk As MediaControl
 +
 +
 +
Public Sub Form_Open()
 +
 
 +
  Dim src, cnv As MediaControl
 +
  Dim ftr As MediaFilter
 +
 
 +
  pl = New MediaPipeline
 +
 
 +
  src = New MediaControl(pl, "v4l2src")
 +
  src["device"] = "/dev/video0"
 +
  ftr = New MediaFilter(pl)
 +
  ftr.Filter = "video/x-raw,width=640,height=480,framerate=30/1"
 +
  cnv = New MediaControl(pl, "videoconvert")
 +
  snk = New MediaControl(pl, "xvimagesink")
 +
   
 +
  src.LinkTo(ftr)
 +
  ftr.LinkTo(cnv)
 +
  cnv.LinkTo(snk)
 +
 
 +
End
 +
 +
 +
Public Sub Button1_Click()
 +
 
 +
  Dim i As Integer
 +
  Dim drc, s As String
 +
 
 +
  drc = "/tmp/immagini"
 +
 
 +
  If Not Exist(drc) Then
 +
    Mkdir drc
 +
  Else
 +
    For Each s In Dir(drc, "immagine_*", gb.file)
 +
      Kill drc &/ s
 +
    Next
 +
  Endif
 +
 
 +
  pl.Play()
 +
 
 +
  While pl.State = Media.Playing
 +
    snk.GetLastImage().Save(drc &/ "immagine_" & CStr(I) & ".png")
 +
    Print "Schermata video salvata nella cartella " & drc
 +
    Wait 0.5
 +
    Inc i
 +
  Wend
 +
 
 +
End
 +
 +
 +
Public Sub Button2_Click()
 +
 +
  pl.Stop()
 +
  pl.Close()
 +
 +
End
  
  
  
 
=Note=
 
=Note=
[1] Vedi anche questa pagina della WIKI: [[Generare_un_file_immagine_da_una_DrawingArea#1a_modalit.C3.A0|Generare un file immagine da una DrawingArea]]
+
[1] Vedere anche questa pagina della WIKI: [[Catturare un'immagine con una webcam mediante il Componente gb.media]]
 +
 
 +
[2] Riguardo all'Oggetto grafico da usare con il Metodo ".SetWindow()" della Classe ''MediaPlayer'', B. Minisini ha chiarito che esso necessita di un controllo che abbia una vera finestra X11 (o Wayland), altrimenti si userà il primo controllo genitore con una finestra reale (che di solito è quella di primo livello).
 +
 
 +
[3] Vedi anche questa pagina della WIKI: [[Generare un file immagine da una DrawingArea]]

Versione attuale delle 16:04, 22 dic 2023

A volte può essere necessario estrarre e salvare in appositi file singole immagini di una ripresa video effettuata mediante una WebCam con il Componente gb.media. [nota 1]
Per fare ciò, sono disponibili alcune modalità.

E' il caso di sottolineare che bisognerà creare progetti QT Application, altrimenti usando i Componenti GTK detti codici non funzioneranno a dovere.


Usare la Classe MediaPlayer con una PictureBox

Innanzitutto è possibile usare la Classe MediaPlayer. In particolare, per catturare le singole immagini, si utilizzerà in tal caso la sotto-Proprietà ".Image" della Proprietà "Video" della Classe MediaPlayer.

Mostriamo un esempio in ambiente grafico, nel quale si utilizzerà una PictureBox per mostrare il video e un'altra per mostrare l'immagine catturata:

Private mp As MediaPlayer


Public Sub Form_Open()
 
 With mp = new MediaPlayer
   .URL = "v4l2:///dev/video0"
   .SetWindow(PictureBox1)     ' [nota 2]
   .Play()
 End With
 
End
 

Public Sub Button1_Click() ' Cliccando sul tasto, si catturerà un'immagine dal video
 
 Dim im As Image
 
 im = mp.Video.Image
 
 im.Save("/tmp" &/ Format(Now, "dd:mm:yyyy_hh:nn:ss.uu") & ".png")
 
 PictureBox2.Image = im.Stretch(PictureBox2.W, PictureBox2.H)
  
End


Usare le Classi MediaPlayer, MediaControl con una DrawingArea

E' possibile usare le Classi MediaPlayer e MediaControl.

Mostriamo di seguito un semplice esempio, nel quale la ripresa sarà mostrata all'interno di una DrawingArea, e sarà salvata ogni secondo - grazie all'uso dell'Oggetto Timer - un'immagine della ripresa all'interno di un file immagine di formato PNG.

Private mp As MediaPlayer
Private im As MediaControl
Private drar As DrawingArea
Private tb As ToggleButton
Private tempus As Timer
Private i As Integer


Public Sub Form_Open()

 Dim flt As MediaFilter

 With Me
   .W = Screen.AvailableWidth * 0.75
   .H = Screen.AvailableHeight * 0.75
 End With
 With drar = New DrawingArea(Me)
   .X = Me.W * 0.05
   .Y = Me.H * 0.05
   .W = Me.W * 0.9
   .H = Me.H * 0.8
   .Border = Border.Plain
 End With
 With tb = New ToggleButton(Me) As "Tasto"
   .W = Me.W * 0.1
   .H = Me.H * 0.05
   .X = (Me.W / 2) - (.W / 2)
   .Y = 0
   .Text = "Avvia"
 End With

 If Not Exist("/tmp/immagini") Then Mkdir "/tmp/immagini"

 mp = New MediaPlayer As "MediaPlayer"
 flt = New MediaFilter(mp, "video/x-raw,width=640,height=480,framerate=30/1")
 im = New MediaControl(mp, "xvimagesink")

End


Public Sub Tasto_Click()

 mp.Video.Output = im
 mp.URL = "v4l2:///dev/video0"
 
 im.SetWindow(drar)
 
 If tb.Value Then
   mp.Play
   With tempus = New Timer As "Tempus"
     .Delay = 1000
     .Start()
   End With
   tb.Text = "Stop"
 Else
   mp.Stop
   mp.Close
   tempus.Stop
   tb.Text = "Avvia"
 Endif
 
End


Public Sub Tempus_Timer()

 Dim img As Image

 img = mp.Video.Image
 Inc i

 img.Save("/tmp/immagini/foto_" & CStr(i) & ".png", 100)

 Write #File.out, "\rImmagini catturate: " & CStr(i)

End


Usare il Metodo ".GetLastImage()" della Classe MediaControl per catturare singole immagini dal video, e utilizzare una DrawingArea per mostrare la ripresa video

Quest'altra modalità prevede che:

  • sia utilizzata una DrawingArea, come superficie ove mostrare la ripresa video;
  • sia utilizzato il Metodo ".GetLastImage()" della Classe MediaControl per catturare singole immagini dal video.

Mostriamo di seguito un esempio pratico, nel quale la cattura delle immagini dalla ripresa video avviene ogni 500 millisecondi:

Private pl As MediaPipeline
Private snk As MediaControl


Public Sub Form_Open()
 
 Dim src, cnv As MediaControl
 Dim ftr As MediaFilter
 Dim dr As DrawingArea
 
 With dr = New DrawingArea(Me)
   .X = 10
   .Y = 10
   .W = 640
   .H = 480
 End With
  
 pl = New MediaPipeline
 
 src = New MediaControl(pl, "v4l2src")
 src["device"] = "/dev/video0"
  
 ftr = New MediaFilter(pl)
 ftr.Filter = "video/x-raw,width=640,height=480,framerate=30/1"
 cnv = New MediaControl(pl, "videoconvert")
 snk = New MediaControl(pl, "xvimagesink")
    
 src.LinkTo(ftr)
 ftr.LinkTo(cnv)
 cnv.LinkTo(snk)
  
' Imposta la DrawingArea come superficie ove mostrare la ripresa video:
 snk.SetWindow(dr)
  
End


Public Sub Button1_Click()
 
 Dim i As Integer
 Dim drc, s As String
  
 drc = "/tmp/immagini"
  
 If Not Exist(drc) Then
   Mkdir drc
 Else
   For Each s In Dir(drc, "immagine_*", gb.file)
     Kill drc &/ s
   Next
 Endif
  
 pl.Play()
  
 While pl.State = Media.Playing
   snk.GetLastImage().Save(drc &/ "immagine_" & CStr(I) & ".png")
   Print "Schermata video salvata nella cartella " & drc
' Attende mezzo secondo per catturare un'altra immagine dalla ripresa video:
   Wait 0.5
   Inc i
 Wend
  
End


Public Sub Button2_Click()

 pl.Stop()
 pl.Close()
 
End


Usare il Metodo ".GetScreenshot()" della Classe DesktopWindow per catturare singole immagini dal video, e utilizzare una DrawingArea per mostrare la ripresa video

Con questa modalità si raccoglierà mediante il Metodo ".GetScreenshot()" della Classe DesktopWindow [Nota 3] quanto appare sulla superficie video utilizzata. Per individuare utilmente tale superficie video, è necessario individuare il suo handle.
E' necessario attivare nell'applicazione Gambas i Componenti gb.desktop e gb.desktop.x11.

Mostriamo di seguito un esempio pratico, nel quale si salverà in un vettore di tipo "Picture[]" ogni 300 millesimi di secondo un'immagine del video, mostrato all'interno di una DrawingArea. Al termine della ripresa video si provvederà a salvare ciascuna immagine, salvata nel predetto vettore, in un file immagine di tipo png.

Private dr As DrawingArea
Private pl As MediaPipeline
Private pc As New Picture[]


Public Sub Form_Open()
 
 Dim src, tim, cnv, snk As MediaControl
 Dim ftr As MediaFilter
 
 With dr = New DrawingArea(Me)
   .X = 10
   .Y = 10
   .W = 640
   .H = 480
 End With
 
 pl = New MediaPipeline 
 
 src = New MediaControl(pl, "v4l2src")
 src["device"] = "/dev/video0"
 ftr = New MediaFilter(pl, "video/x-raw,width=640,height=480,framerate=30/1")
' Mostra nel video anche il tempo trascorso dall'avvio della ripresa:
 tim = New MediaControl(pl, "timeoverlay")
 cnv = New MediaControl(pl, "videoconvert")
 snk = New MediaControl(pl, "xvimagesink")
 
' Colleghiamo i quattro plug-in di "GStreamer":
 src.LinkTo(ftr)
 ftr.LinkTo(tim)
 tim.LinkTo(cnv)
 cnv.LinkTo(snk)
 snk.SetWindow(dr)
  
End


Public Sub Button1_Click()

 Dim dw As DesktopWindow
 
' Avvia la ripresa video della WebCam:
 pl.State = Media.Playing
 pl.Play()
 
' Resta in attesa che la WebCam avvi effettivamente la ripresa video:
 Wait 2
  
 dw = New DesktopWindow(dr.Handle)
 
 While pl.State = Media.Playing
' Cattura una schermata del contenuto video mostrato in quel momento dalla "DrawingArea":
   pc.Push(dw.GetScreenshot(True))
' La cattura della schermata avviene ogni 300 millisecondi:
   Wait 0.3
 Wend
     
End


Public Sub Button2_Click()    ' Questo evento arresta la ripresa video e salva ogni picture in un file .png

 Dim i As Integer
 Dim drc, s As String
  
 drc = "/tmp/immago"
  
 pl.Stop
 
 If Not Exist(drc) Then
   Mkdir drc
 Else
   For Each s In Dir(drc, "picture_*", gb.file)
     Kill drc &/ s
   Next
 Endif
 
 For i = 0 To pc.Max
   pc[i].Save(drc &/ "picture_" & CStr(i) & ".png", 100)
 Next
  
End


Usare il Metodo ".GetLastImage()" della Classe MediaControl per catturare singole immagini dal video, ma senza utilizzare una DrawingArea

Quest'altra modalità prevede che:

  • non sia utilizzata una DrawingArea, come superficie ove mostrare la ripresa video, bensì una superficie generata automaticamente da GStreamer;
  • sia utilizzato il Metodo ".GetLastImage()" della Classe MediaControl per catturare singole immagini dal video.

Mostriamo di seguito un esempio pratico:

Private pl As MediaPipeline
Private snk As MediaControl


Public Sub Form_Open()
 
 Dim src, cnv As MediaControl
 Dim ftr As MediaFilter
 
 pl = New MediaPipeline
 
 src = New MediaControl(pl, "v4l2src")
 src["device"] = "/dev/video0"
 ftr = New MediaFilter(pl)
 ftr.Filter = "video/x-raw,width=640,height=480,framerate=30/1"
 cnv = New MediaControl(pl, "videoconvert")
 snk = New MediaControl(pl, "xvimagesink")
    
 src.LinkTo(ftr)
 ftr.LinkTo(cnv)
 cnv.LinkTo(snk)
  
End


Public Sub Button1_Click()
 
 Dim i As Integer
 Dim drc, s As String
  
 drc = "/tmp/immagini"
  
 If Not Exist(drc) Then
   Mkdir drc
 Else
   For Each s In Dir(drc, "immagine_*", gb.file)
     Kill drc &/ s
   Next
 Endif
  
 pl.Play()
 
 While pl.State = Media.Playing
   snk.GetLastImage().Save(drc &/ "immagine_" & CStr(I) & ".png")
   Print "Schermata video salvata nella cartella " & drc
   Wait 0.5
   Inc i
 Wend
  
End


Public Sub Button2_Click()

 pl.Stop()
 pl.Close()

End


Note

[1] Vedere anche questa pagina della WIKI: Catturare un'immagine con una webcam mediante il Componente gb.media

[2] Riguardo all'Oggetto grafico da usare con il Metodo ".SetWindow()" della Classe MediaPlayer, B. Minisini ha chiarito che esso necessita di un controllo che abbia una vera finestra X11 (o Wayland), altrimenti si userà il primo controllo genitore con una finestra reale (che di solito è quella di primo livello).

[3] Vedi anche questa pagina della WIKI: Generare un file immagine da una DrawingArea