Advertisement
Hadlock

Powershell Webcam GUI script

May 11th, 2014
841
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function Get-WebCamImage {
  2.  
  3. #requires -version 2.0
  4.  
  5. <#
  6. .Synopsis
  7.    Use PowerShell to preview video from your webcam and also take snapshots
  8. .Description
  9.    This PowerShell script previews video from your webcam and takes snapshots to JPEG
  10.    Script uses WebCamLib which is a C# wrapper around a couple of API's in avicap32.dll
  11.    The script can run interactively or from the command line.  
  12.    You can use some other program like the old vidcap32.exe from MSFT to change the  
  13.    resolution of the captured image, i.e increase it to 640x480  
  14.    Video Preview must be partially visible or the photos will be frozen on last scene.
  15.    Start the shell using a single-threaded apartment, Use -sta switch as per example
  16.    Code uses clipboard to transfer photo which only works when powershell is in sta mode
  17. .Parameter AppActivate
  18.    Application is forced on top to ensure picture is taken
  19. .Parameter CamIndex
  20.    The camera is selected, use index 0 for the first camera
  21. .Parameter Interval
  22.    When this parameter is used, a snapshot is taken every x second(s)    
  23. .Parameter PathBase
  24.    The base path that images are created.  
  25.    Defaults to "c:\cap\image" (ensure base 'folder' exists)
  26.    Images are created - "c:\cap\image0.jpg","c:\cap\image1.jpg","c:\cap\image2.jpg"
  27. .Parameter UseCam
  28.    start using camera straight away when this switch is selected
  29.  
  30. .example
  31.    Get-WebCamImage
  32.    
  33.    Description
  34.    -----------
  35.    The camera application is displayed
  36. .example
  37.    Get-WebCamImage -CamIndex 0 -UseCam
  38.    
  39.    Description
  40.    -----------
  41.    The camera application is displayed, first camera in drop downlist is selected  
  42.    and started.  
  43. .example
  44.    Get-WebCamImage -CamIndex 0 -UseCam -interval 3
  45.    
  46.    Description
  47.    -----------
  48.    The camera application is displayed, first camera in drop downlist is selected  
  49.    and started. A image is captured and saved in default path every 3 seconds
  50. .example
  51.    %windir%\system32\WindowsPowerShell\v1.0\powershell.exe -sta -WindowStyle Hidden -file C:\scripts\get-WebCam.ps1
  52.    or
  53.    powershell.exe C:\scripts\get-WebCam.ps1 -sta  
  54.    
  55.    Description
  56.    -----------
  57.    If you want to launch the application from a shortcut use this command or similar
  58.    Note the -sta parameter is required.        
  59. .Link
  60.    http://social.technet.microsoft.com/Profile/en-US/?user=Matthew Painter
  61. .link
  62.    http://weblogs.asp.net/nleghari/pages/webcam.aspx
  63. .Notes
  64.    NAME:      Get-WebCamImage
  65.    VERSION:   1.0
  66.    AUTHOR:    Matthew Painter
  67.    LASTEDIT:  26/09/2010
  68.  
  69. #>
  70.    [CmdletBinding()]    
  71.    
  72.       Param (
  73.       [Parameter(
  74.       ValueFromPipeline=$False,
  75.       Mandatory=$False,
  76.       HelpMessage="Application is forced on top to ensure picture is taken")]
  77.       [Switch]$AppActivate,
  78.        
  79.       [Parameter(
  80.       ValueFromPipeline=$False,
  81.       Mandatory=$false,
  82.       HelpMessage="The dropdown list index specifying the camera to be selected")]
  83.       [int]$CamIndex=0,
  84.  
  85.       [Parameter(
  86.       ValueFromPipeline=$False,
  87.       Mandatory=$False,
  88.       HelpMessage="Interval in seconds between each snapshot image taken")]
  89.       [int]$Interval,
  90.        
  91.       [Parameter(
  92.       ValueFromPipeline=$False,
  93.       Mandatory=$False,
  94.       HelpMessage="The base path that images are created")]
  95.       [String]$PathBase="c:\cap\image",
  96.        
  97.       [Parameter(
  98.       ValueFromPipeline=$False,
  99.       Mandatory=$false,
  100.       HelpMessage="This parameter is a switch - start using camera straight away")]
  101.       [switch]$UseCam
  102.       )
  103.    
  104.    $source=@"
  105. using System;
  106. using System.Collections.Generic;
  107. using System.Text;
  108. using System.Collections;
  109. using System.Runtime.InteropServices;
  110. using System.ComponentModel;
  111. using System.Data;
  112. using System.Drawing;
  113. using System.Windows.Forms;
  114.  
  115. namespace WebCamLib
  116. {
  117.    public class Device
  118.    {
  119.        private const short WM_CAP = 0x400;
  120.        private const int WM_CAP_DRIVER_CONNECT = 0x40a;
  121.        private const int WM_CAP_DRIVER_DISCONNECT = 0x40b;
  122.        private const int WM_CAP_EDIT_COPY = 0x41e;
  123.        private const int WM_CAP_SET_PREVIEW = 0x432;
  124.        private const int WM_CAP_SET_OVERLAY = 0x433;
  125.        private const int WM_CAP_SET_PREVIEWRATE = 0x434;
  126.        private const int WM_CAP_SET_SCALE = 0x435;
  127.        private const int WS_CHILD = 0x40000000;
  128.        private const int WS_VISIBLE = 0x10000000;
  129.  
  130.        [DllImport("avicap32.dll")]
  131.        protected static extern int capCreateCaptureWindowA([MarshalAs(UnmanagedType.VBByRefStr)] ref string lpszWindowName,
  132.            int dwStyle, int x, int y, int nWidth, int nHeight, int hWndParent, int nID);
  133.  
  134.        [DllImport("user32", EntryPoint = "SendMessageA")]
  135.        protected static extern int SendMessage(int hwnd, int wMsg, int wParam, [MarshalAs(UnmanagedType.AsAny)] object lParam);
  136.  
  137.        [DllImport("user32")]
  138.        protected static extern int SetWindowPos(int hwnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);
  139.  
  140.        [DllImport("user32")]
  141.        protected static extern bool DestroyWindow(int hwnd);
  142.                
  143.        int index;
  144.        int deviceHandle;
  145.  
  146.        public Device(int index)
  147.        {
  148.            this.index = index;
  149.        }
  150.  
  151.        private string _name;
  152.  
  153.        public string Name
  154.        {
  155.            get { return _name; }
  156.            set { _name = value; }
  157.        }
  158.  
  159.        private string _version;
  160.  
  161.        public string Version
  162.        {
  163.            get { return _version; }
  164.            set { _version = value; }
  165.        }
  166.  
  167.        public override string ToString()
  168.        {
  169.            return this.Name;
  170.        }
  171.  
  172.        public void Init(int windowHeight, int windowWidth, int handle)
  173.        {
  174.            string deviceIndex = Convert.ToString(this.index);
  175.            deviceHandle = capCreateCaptureWindowA(ref deviceIndex, WS_VISIBLE | WS_CHILD, 0, 0, windowWidth, windowHeight, handle, 0);
  176.  
  177.            if (SendMessage(deviceHandle, WM_CAP_DRIVER_CONNECT, this.index, 0) > 0)
  178.            {
  179.                SendMessage(deviceHandle, WM_CAP_SET_SCALE, -1, 0);
  180.                SendMessage(deviceHandle, WM_CAP_SET_PREVIEWRATE, 0x42, 0);
  181.                SendMessage(deviceHandle, WM_CAP_SET_PREVIEW, -1, 0);
  182.                SetWindowPos(deviceHandle, 1, 0, 0, windowWidth, windowHeight, 6);
  183.            }
  184.        }
  185.  
  186.        public void ShowWindow(global::System.Windows.Forms.Control windowsControl)
  187.        {
  188.            Init(windowsControl.Height, windowsControl.Width, windowsControl.Handle.ToInt32());                        
  189.        }
  190.        
  191.        public void CopyC()
  192.        {
  193.           SendMessage(this.deviceHandle, WM_CAP_EDIT_COPY, 0, 0);          
  194.        }
  195.  
  196.        public void Stop()
  197.        {
  198.            SendMessage(deviceHandle, WM_CAP_DRIVER_DISCONNECT, this.index, 0);
  199.            DestroyWindow(deviceHandle);
  200.        }
  201.    }
  202.    
  203.    public class DeviceManager
  204.    {
  205.        [DllImport("avicap32.dll")]
  206.        protected static extern bool capGetDriverDescriptionA(short wDriverIndex,
  207.            [MarshalAs(UnmanagedType.VBByRefStr)]ref String lpszName,
  208.           int cbName, [MarshalAs(UnmanagedType.VBByRefStr)] ref String lpszVer, int cbVer);
  209.  
  210.        static ArrayList devices = new ArrayList();
  211.  
  212.        public static Device[] GetAllDevices()
  213.        {
  214.            String dName = "".PadRight(100);
  215.            String dVersion = "".PadRight(100);
  216.  
  217.            for (short i = 0; i < 10; i++)
  218.            {
  219.                if (capGetDriverDescriptionA(i, ref dName, 100, ref dVersion, 100))
  220.                {
  221.                    Device d = new Device(i);
  222.                    d.Name = dName.Trim();
  223.                    d.Version = dVersion.Trim();
  224.                    devices.Add(d);                    
  225.                }
  226.            }
  227.  
  228.            return (Device[])devices.ToArray(typeof(Device));
  229.        }
  230.  
  231.        public static Device GetDevice(int deviceIndex)
  232.        {
  233.            return (Device)devices[deviceIndex];
  234.        }
  235.    }
  236. }
  237. "@
  238.        
  239.    Add-Type -AssemblyName System.Drawing  
  240.    $jpegCodec = [Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() |  
  241.    Where-Object { $_.FormatDescription -eq "JPEG" }  
  242.    
  243.    Add-Type -TypeDefinition $source -ReferencedAssemblies System.Windows.Forms, System.Data, System.Drawing
  244.  
  245.  
  246.  
  247. #region Import the Assemblies
  248. [reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
  249. [reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null
  250. #endregion
  251.  
  252. #region Generated Form Objects
  253. $MainForm = New-Object System.Windows.Forms.Form
  254. $btnQuitApp = New-Object System.Windows.Forms.Button
  255. $btnCopyImage = New-Object System.Windows.Forms.Button
  256. $btnStopCam = New-Object System.Windows.Forms.Button
  257. $btnSelectDevice = New-Object System.Windows.Forms.Button
  258. $cmbDevices = New-Object System.Windows.Forms.ComboBox
  259. $picCapture = New-Object System.Windows.Forms.PictureBox
  260. $InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
  261. #endregion Generated Form Objects
  262.  
  263. #Build drop down list
  264. $devices = [WebCamLib.DeviceManager]::GetAllDevices()
  265. foreach ($d in $devices)
  266. {
  267.    $cmbDevices.Items.Add($d) | Out-Null
  268. }
  269.  
  270. if ($devices.Length -gt 0)
  271. {
  272.    $cmbDevices.SelectedIndex = 0
  273. }
  274.  
  275. #Select Button code
  276. $handler_btnSelectDevice_Click=  
  277. {
  278.    $d = [WebCamLib.DeviceManager]::GetDevice($cmbDevices.SelectedIndex)
  279.    $d.ShowWindow($picCapture)
  280. }
  281.  
  282. #Copy Button Code
  283. $handler_btnCopyImage_Click=  
  284. {
  285.     [windows.forms.clipboard]::clear()
  286.     $d.CopyC()      
  287.     $bitmap = [Windows.Forms.Clipboard]::GetImage()  
  288.      
  289.     if ($bitmap -ne $null)
  290.     {            
  291.        $ep = New-Object Drawing.Imaging.EncoderParameters    
  292.        $ep.Param[0] = New-Object Drawing.Imaging.EncoderParameter ([System.Drawing.Imaging.Encoder]::Quality, [long]100)    
  293.        $c = 0  
  294.        while (Test-Path "${PathBase}${c}.jpg")  
  295.        {  
  296.           $c++  
  297.        }  
  298.        $bitmap.Save("$PathBase$c.jpg", $jpegCodec, $ep)
  299.        Write-host "Snap taken "$PathBase$c.jpg""
  300.        $bitmap.dispose()
  301.        $ep.dispose()
  302.        [windows.forms.clipboard]::clear()
  303.     }
  304.     else
  305.     {
  306.        write-host "no image on clipboard"
  307.     }
  308.  
  309.      
  310. }
  311.  
  312. #Stop Button Code
  313. $handler_btnStopCam_Click=  
  314. {
  315.    $d = [WebCamLib.DeviceManager]::GetDevice($cmbDevices.SelectedIndex)
  316.    $d.Stop()
  317.    if ($timer -ne $null){$timer.Stop()}
  318. }
  319.  
  320. #Quit Button Code
  321. $handler_btnQuitApp_Click=  
  322. {
  323.    $MainForm.close()
  324. }
  325.  
  326.  
  327. $OnLoadForm_StateCorrection=
  328. {#Correct the initial state of the form to prevent the .Net maximized form issue
  329.    $MainForm.WindowState = $InitialFormWindowState
  330.      
  331.    if($UseCam)
  332.    {        
  333.       write-host "Using camera $CamIndex"
  334.       $d = [WebCamLib.DeviceManager]::GetDevice($cmbDevices.$CamIndex)
  335.       $d.ShowWindow($picCapture)
  336.    }
  337. }
  338.  
  339. if ($interval -gt 0)
  340. {
  341.    # Make Timer  
  342.    [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")  
  343.    $timer = New-Object System.Windows.Forms.Timer  
  344.    if ($interval -gt 30 ) {$timer.Interval = 5000} Else {$timer.Interval = 1000}
  345.    $SecsToInterval = $interval
  346.  
  347.    $timer.add_Tick({
  348.  
  349.    $SecsToInterval -= ($timer.Interval / 1000)
  350.  
  351.    if ( $SecsToInterval -eq 0 )  
  352.    {
  353.       $SecsToInterval = $interval
  354.        
  355.       if ($Appactivate)
  356.       {
  357.          [void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
  358.          [Microsoft.VisualBasic.Interaction]::AppActivate("PowerShell WebCam")
  359.       }
  360.        
  361.       & $handler_btnCopyImage_Click
  362.    }
  363.  
  364.    write-host " [ Next Snap in : $(new-Timespan -sec $SecsToInterval) ]"
  365.  
  366.    })
  367.  
  368.    $timer.Enabled = $true
  369.    $timer.Start()
  370. }
  371.  
  372.  
  373. #----------------------------------------------
  374. #region Generated Form Code
  375. $MainForm.Text = "PowerShell WebCam"
  376. $MainForm.Name = "MainForm"
  377. $MainForm.DataBindings.DefaultDataSourceUpdateMode = 0
  378. $System_Drawing_Size = New-Object System.Drawing.Size
  379. $System_Drawing_Size.Width = 271
  380. $System_Drawing_Size.Height = 172
  381. $MainForm.ClientSize = $System_Drawing_Size
  382.  
  383. $btnQuitApp.TabIndex = 5
  384. $btnQuitApp.Name = "btnQuitApp"
  385. $System_Drawing_Size = New-Object System.Drawing.Size
  386. $System_Drawing_Size.Width = 75
  387. $System_Drawing_Size.Height = 23
  388. $btnQuitApp.Size = $System_Drawing_Size
  389. $btnQuitApp.UseVisualStyleBackColor = $True
  390.  
  391. $btnQuitApp.Text = "Quit"
  392.  
  393. $System_Drawing_Point = New-Object System.Drawing.Point
  394. $System_Drawing_Point.X = 12
  395. $System_Drawing_Point.Y = 137
  396. $btnQuitApp.Location = $System_Drawing_Point
  397. $btnQuitApp.DataBindings.DefaultDataSourceUpdateMode = 0
  398. $btnQuitApp.add_Click($handler_btnQuitApp_Click)
  399.  
  400. $MainForm.Controls.Add($btnQuitApp)
  401.  
  402. $btnCopyImage.TabIndex = 4
  403. $btnCopyImage.Name = "btnCopyImage"
  404. $System_Drawing_Size = New-Object System.Drawing.Size
  405. $System_Drawing_Size.Width = 75
  406. $System_Drawing_Size.Height = 23
  407. $btnCopyImage.Size = $System_Drawing_Size
  408. $btnCopyImage.UseVisualStyleBackColor = $True
  409.  
  410. $btnCopyImage.Text = "Copy"
  411.  
  412. $System_Drawing_Point = New-Object System.Drawing.Point
  413. $System_Drawing_Point.X = 12
  414. $System_Drawing_Point.Y = 71
  415. $btnCopyImage.Location = $System_Drawing_Point
  416. $btnCopyImage.DataBindings.DefaultDataSourceUpdateMode = 0
  417. $btnCopyImage.add_Click($handler_btnCopyImage_Click)
  418.  
  419. $MainForm.Controls.Add($btnCopyImage)
  420.  
  421. $btnStopCam.TabIndex = 3
  422. $btnStopCam.Name = "btnStopCam"
  423. $System_Drawing_Size = New-Object System.Drawing.Size
  424. $System_Drawing_Size.Width = 75
  425. $System_Drawing_Size.Height = 23
  426. $btnStopCam.Size = $System_Drawing_Size
  427. $btnStopCam.UseVisualStyleBackColor = $True
  428.  
  429. $btnStopCam.Text = "Stop"
  430.  
  431. $System_Drawing_Point = New-Object System.Drawing.Point
  432. $System_Drawing_Point.X = 13
  433. $System_Drawing_Point.Y = 108
  434. $btnStopCam.Location = $System_Drawing_Point
  435. $btnStopCam.DataBindings.DefaultDataSourceUpdateMode = 0
  436. $btnStopCam.add_Click($handler_btnStopCam_Click)
  437.  
  438. $MainForm.Controls.Add($btnStopCam)
  439.  
  440. $btnSelectDevice.TabIndex = 2
  441. $btnSelectDevice.Name = "btnSelectDevice"
  442. $System_Drawing_Size = New-Object System.Drawing.Size
  443. $System_Drawing_Size.Width = 75
  444. $System_Drawing_Size.Height = 23
  445. $btnSelectDevice.Size = $System_Drawing_Size
  446. $btnSelectDevice.UseVisualStyleBackColor = $True
  447.  
  448. $btnSelectDevice.Text = "Select Device"
  449.  
  450. $System_Drawing_Point = New-Object System.Drawing.Point
  451. $System_Drawing_Point.X = 12
  452. $System_Drawing_Point.Y = 42
  453. $btnSelectDevice.Location = $System_Drawing_Point
  454. $btnSelectDevice.DataBindings.DefaultDataSourceUpdateMode = 0
  455. $btnSelectDevice.add_Click($handler_btnSelectDevice_Click)
  456.  
  457. $MainForm.Controls.Add($btnSelectDevice)
  458.  
  459. $cmbDevices.FormattingEnabled = $True
  460. $System_Drawing_Size = New-Object System.Drawing.Size
  461. $System_Drawing_Size.Width = 242
  462. $System_Drawing_Size.Height = 21
  463. $cmbDevices.Size = $System_Drawing_Size
  464. $cmbDevices.DataBindings.DefaultDataSourceUpdateMode = 0
  465. $cmbDevices.Name = "cmbDevices"
  466. $System_Drawing_Point = New-Object System.Drawing.Point
  467. $System_Drawing_Point.X = 12
  468. $System_Drawing_Point.Y = 11
  469. $cmbDevices.Location = $System_Drawing_Point
  470. $cmbDevices.TabIndex = 1
  471.  
  472. $MainForm.Controls.Add($cmbDevices)
  473.  
  474. $picCapture.BackColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
  475. $picCapture.TabIndex = 0
  476. $System_Drawing_Size = New-Object System.Drawing.Size
  477. $System_Drawing_Size.Width = 160
  478. $System_Drawing_Size.Height = 120
  479. $picCapture.Size = $System_Drawing_Size
  480. $picCapture.BorderStyle = 2
  481.  
  482.  
  483. $System_Drawing_Point = New-Object System.Drawing.Point
  484. $System_Drawing_Point.X = 94
  485. $System_Drawing_Point.Y = 42
  486. $picCapture.Location = $System_Drawing_Point
  487.  
  488.  
  489. $picCapture.TabStop = $False
  490. $picCapture.Name = "picCapture"
  491. $picCapture.DataBindings.DefaultDataSourceUpdateMode = 0
  492.  
  493. $MainForm.Controls.Add($picCapture)
  494.  
  495. #endregion Generated Form Code
  496.  
  497. #Save the initial state of the form
  498. $InitialFormWindowState = $MainForm.WindowState
  499. #Init the OnLoad event to correct the initial state of the form
  500. $MainForm.add_Load($OnLoadForm_StateCorrection)
  501. #Show the Form
  502. $MainForm.ShowDialog()| Out-Null
  503.  
  504. } #End Function
  505.  
  506.  
  507.  
  508. Get-WebCamImage
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement