Vanguarsoft Developers blog

Ing. Javier Leal -Desarrollador CPANAX C.A / Microsoft Student Partners – VENEZUELA

Acceso a la Cámara Web desde Aplicación en Silverlight 4

13 comentarios

Hola amigos ahora les traigo un tema técnico bien interesante, en las aplicaciones de Silverlight puedes fácilmente tener acceso a dispositivos de audio y video del equipo mediante un permiso que el mismo emite al usuario al momento de acceder..

imagePara Iniciar creamos un nuevo proyecto de Silverlight en mi caso lo hago desde Blend, además de tomar en cuenta que lo haremos usando C Shard como lenguaje de programación.

Luego de Crear el proyecto crea tu interfaz personalizada a tu gusto en mi caso le coloque un titulo y un TextBox por los momentos, este combo llevara por nombre: Cbox_Dispositivos.image

Ya que se trata de una entidad a la cual vamos a acceder puedes colocar el nombre exacto del dispositivo editando el Template del ComboBox este seria el código XAML:

<ComboBox x:Name="Cbox_Dispositivos">

<ComboBox.ItemTemplate>

<DataTemplate>

<TextBlock Text="{Binding FriendlyName}" />

</DataTemplate>

</ComboBox.ItemTemplate>

</ComboBox>

Luego de esto nos vamos a visual Studio para llenar esa lista de los dispositivos. y como estamos trabajando con la cámara web debemos llenar el ItemSourse de el combo Box con el método GetAvailableVideoCaptureDevices de la clase CaptureDeviceConfiguration ;

using System;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Ink;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

 

namespace DemoMedia

{

    public partial class MainPage : UserControl

    {

        public MainPage()

        {

            // Necesario para inicializar variables

            InitializeComponent();

            //Llenar el Combo de los dispositivos necesarios

            Cbox_Dispositivos.ItemsSource = CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices();

        }

    }

}

image

De nuevo en Expression Blend y para terminar la parte de diseño agregaras a la pantalla dos Objetos Rectangule uno para mostrar el video y otro para captura de una foto desde la cámara el primero se llamara camVideo y el segundo camCaptura, además de ello agregaras tres botones Iniciar Captura, Parar Captura y Capturar Foto.

image

Código XAML del diseño:

<UserControl

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    x:Class="DemoMedia.MainPage">

    <Grid x:Name="LayoutRoot" Height="768" Width="1024">

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="350"/>

            <ColumnDefinition Width="150"/>

            <ColumnDefinition Width="*"/>

        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>

            <RowDefinition Height="90"/>

            <RowDefinition Height="30"/>

            <RowDefinition Height="30"/>

            <RowDefinition Height="450"/>

            <RowDefinition Height="*"/>

        </Grid.RowDefinitions>

        <Grid.Background>

            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">

                <GradientStop Color="Black" Offset="0"/>

                <GradientStop Color="White" Offset="1"/>

                <GradientStop Color="#FF1527BC" Offset="0.48"/>

                <GradientStop Color="#FF0B1241" Offset="0.83"/>

            </LinearGradientBrush>

        </Grid.Background>

        <TextBlock   Foreground="White" FontSize="22" FontWeight="Bold" TextAlignment="Center" FontFamily="Jing Jing" Grid.ColumnSpan="3"><Run Text="CAMARA WEB EN SILVERLIGHT"/><LineBreak/><Run Text="Por. Ing. Javier Leal"/></TextBlock>

        <ComboBox x:Name="Cbox_Dispositivos"  Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2">

            <ComboBox.ItemTemplate>             <DataTemplate>                 <TextBlock Text="{Binding FriendlyName}" />             </DataTemplate>        </ComboBox.ItemTemplate>  </ComboBox>

        <TextBlock  Grid.Row="2" Text="Lista de Dispositivos:" Foreground="White" FontSize="21.333" />         <Rectangle x:Name="camVideo"   Grid.Row="3" Grid.ColumnSpan="2"  Height="408"  Stroke="Black"  Width="480" Fill="Black" RadiusY="25" RadiusX="25" />         <Rectangle x:Name="camCaptura" Stroke="Black"  Width="487" Height="400" Grid.Column="2" Grid.Row="3" Fill="Blue" RadiusY="25" RadiusX="25" />         <Button Click="cmdIniCaptura_Click"  Height="50" Content="Iniciar Captura" x:Name="cmdIniCaptura"  Grid.Row="4" FontWeight="Bold" FontSize="20" Margin="18,59,90,59" />         <Button Click="cmdStopCaptura_Click" Height="50" Content="Parar Captura" x:Name="cmdStopCaptura" Grid.Row="4" Grid.Column="1" FontWeight="Bold" FontSize="20" Margin="-62,59,18,59" />         <Button Click="cmdFotoCaptura_Click" Height="50" Content="Captura Foto" x:Name="cmdFotoCaptura"  Grid.Row="4" Grid.Column="2" FontWeight="Bold" FontSize="20" Margin="20,59,19,59" />     </Grid>

</UserControl>

Ahora A agregarle funcionalidad a los botones desde visual Studio antes de darle funcionalidad a cada botón de debe indicar que el objeto rectangule es quien recibirá la captura de la cámara web y cabe destacar que puede ser otro objeto como un botón que tenga su método Fill.

Y se crea una variable global del objeto CaptureSourse para ser usado en toda la clase y la clase Image Brush que usaremos mas adelante:

CaptureSource capture = new CaptureSource(); 

//clase captura Sourse a nivel global para ser usada en toda la clase         

ImageBrush capturedFoto = new ImageBrush(); 

 // Se crea una ImageBrush para  capturar la imagen.

Justo debajo del código que llega el Combo de dispositivos se agrega el código que que captura el dispositivo por defecto del equipo con la clase VideoCaptureDevice, y se le asigna al CaptureSourse, luego se instancia la clase VideoBrush que se le agrega como sourse el CaptureSourse que ya tiene asignado el dispositivo, con este el pintara el video que para mostrarlo en pantalla se le agrega ese VideoBrush al metodo Fill del rectángulo, para capturar la foto se instancia la clase ImageBrush que ya se hizo arriba de manera Globaly luego se le agrega el método fill del rectángulo que va a mostrar la foto capturada.

public MainPage()

{

    InitializeComponent();             

    Cbox_Dispositivos.ItemsSource = CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices(); 

    //Llenar el Combo de los dispositivos necesarios             

    VideoCaptureDevice VideoDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice(); 

    //Se captura el dispositivo de video por defecto del equipo             

    capture.VideoCaptureDevice = VideoDevice; // Se indica a la clase capture Souse el dispositivo que usara             

    VideoBrush BrochaVideo = new VideoBrush();  // Clase Brocha que pintara el video en un objeto             

    BrochaVideo.SetSource(capture); //  VideoBrush tiene como sourse la clase Capture Sourse que ya tiene asignado un dispositivo             

    camVideo.Fill = BrochaVideo;  // la brocha pinta en el video en el metodo Fill del rectangulo camVideo                          

    camCaptura.Fill = capturedFoto; // Pinta en el rectangulo la imagen capturada.

}

El código se vería de la siguiente manera en visual Studio

image

Si compilan la aplicación verán que no aun no funciona nada solo el combo de dispositivos esta lleno. por lo que esto significa que se debe agregar la funciones a los botones para poder iniciar una captura.

BOTON INICIAR CAPTURA

El botón de captura usara la variable global CaptureSourse para llamar al metodo Star no sin antes verificar que el dispositivo elegido es valido y se inicia sin ningún problema el código del método click es el siguiente

private void cmdIniCaptura_Click(object sender, RoutedEventArgs e)         

{

    // verificar si se puede acceder al dispositivo y el VideoCaptureDevice es nulo.             

    if (CaptureDeviceConfiguration.RequestDeviceAccess() && capture.VideoCaptureDevice != null)             

    {                 

        try                 

        {                     

            //Comenzar Captura                     

            capture.Start();                 

        }                 

        catch (InvalidOperationException ex)                 

        {                     

            // Notificar que hay un arror.                     

            MessageBox.Show("No se ha Iniciado la Captura");                 

        }                 

    }         

}

Como pueden observar se utiliza un Try Catch para verificar si la operación es correcta.

BOTON PARAR CAPTURA

private void cmdStopCaptura_Click(object sender, RoutedEventArgs e)         

{             

    // Verificar si el  VideoCaptureDevice es nulo.             

    if (capture.VideoCaptureDevice != null)                 

    {                 

        capture.Stop();             

    }         

}

Ambos códigos de los primeros dos botones como pueden ver son sencillos ya lo pueden Compilar y funcionara perfecto pero aun falta la captura de la imagen.

BOTON CAPTURAR FOTO

private void cmdFotoCaptura_Click(object sender, RoutedEventArgs e)         

{             

    // Verifica si VideoCaptureDevice es nullo y si el dispositivo se ha iniciado.             

    if (capture.VideoCaptureDevice != null && capture.State == CaptureState.Started)             

    {                 

        capture.CaptureImageAsync();             

    }         

}

Como pueden observar este también verifica si el VIdeoCaptureDevice es diferente de nulo y el estado actual de la cámara que debería ser Iniciado,, otra cosa es que pueden ver que se utiliza el método CaptureImagenAync(), se trata se una método asíncrono que requiere de un Complete para recibir los resultados de la captura de manera asíncrona así la aplicación no tendrá ningún retardo.

Se llamara al evento CaptureImageCompleted de la clase CaptureSourse pero como podemos capturar un evento de este modo estamos acostumbrados a que visual Studio cree los eventos al darle doble click pero podemos usar expresiones lambda muy utilizado hoy en día para capturar eventos y delegados de las clases,

Para hacerlo Utilizamos la clase CaptureSouse en mi caso declare una variable llamada Capture y le instancie el CaptureSourse de tal manera que seria Capture.CaptureImageComplete += Se coloca luego del evento el símbolo + y luego el = y el Itellisense te ayudara a crear el evento correspondiente presionado tabulador varias veces como ven acá este código se colocara al final del método  MainPage:

image

Esto luego de presiona tabulador agrega un nuevo evento en la clase actual:

image

Igualmente se hará con el evento CaptureFailed  para detectar cualquier error en la captura de la foto quedando el código del siguiente modo.

image

A cada método se agrego lo siguiente:

throw new NotImplementedException();


Donde en el caso de el Complete aquí es donde utilizaremos el ImageBruch para que se muestre como foto en el otro rectángulo así quedaron los códigos que los dos nuevo eventos llamados por expression Labda:

void capture_CaptureFailed(object sender, ExceptionRoutedEventArgs e)         

{             

    // Mensaje de error por si falla la captura             

    MessageBox.Show("Falla en la Captura");         

}         

void capture_CaptureImageCompleted(object sender, CaptureImageCompletedEventArgs e)         

{             

    // asina el resultado al ImageBrush declarado Globalmente             

    capturedFoto.ImageSource = e.Result;         

}

Ahora si pueden compitar y funcionara todo Perfecto:

Al compilar te darás cuenta que al presionar Capturar Silverlight le pide permiso al usuario para acceder al equipo y trabajar con el dispositivo de Video.

image

Una vez que presionar si Silverlight muestra el video en vivo en pantalla:

image

Pueden Parar la captura y dejara de visualizar el video en vivo de la cámara Web o Tomar una fotografía.

image

Espero les guste el Articulo y es todo por hoy y Puedes descargar el código acá se llama DemoMedia:

https://skydrive.live.com/?cid=32f66a031183fd4b#!/?cid=32f66a031183fd4b&sc=documents&id=32F66A031183FD4B%21153

Muchas gracias y espero sea de su agrado

Autor: Ing. Javier J. Leal H.

Desarrollador en CPANAX C.A, Microsoft Student Partners de Venezuela Amantes de nuevas Tecnologías Desarrollador es Silverlight 5, Windows 8, Windows Phone, Influenciador y Orador en Actividades Tecnológicas Microsoft

13 pensamientos en “Acceso a la Cámara Web desde Aplicación en Silverlight 4

  1. muy interesante la aplicacion.. se ve chevere luego de que profundice VB mas a fondo comenzare a meterle un poco a C# muy buen post.

  2. Muy interesante. seria bueno hacer la codificacion en VB… Lo unico que falta es como grabar la imagen(Foto) en el servidor.

    • Hola Ruperto sin ningun problema lo podemos hacer en visual basic.. con respecto a montarla en el servidor en sencillo pronto hare un articulo del lo que me pides hay por una posibilidad es montar la foto en un ftp y carturar la url para cuando se necesite de nuevo gracias por el comentario y tu interen en el articulo y mi blog

  3. Me gusta lo voy a implementar Thank a lot…

  4. genial me funciono de maravilla gracias

  5. Y como puedo hacer que desde un windows form pueda programar silverlight para la toma de fotos

    • Amigo Silverlight es Silverlight y Windows Form es Windows Form, tu caso seria como acceder a la web desde windows Form o en su defecto lo mas parecido a lo que te muestro aca seria WPF

    • Son 2 tecnologías diferentes Silverlight en una tecnología que puede ser web o de escritorio depende como lo quieres usar pero en la web trabaja del lado del cliente aprovechando el potencia de tu maquina, windows form en en su totalidad una aplicación de escritorio habitual de windows.

  6. No funciona lo del combobox, dado el codigo:

    VideoCaptureDevice VideoDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();

    y si quiero seleccionar otro dispositivo que no sea por defecto?

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s