Acceso a la Cámara Web desde Aplicación en Silverlight 4
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..
Para 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.![]()
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();
}
}
}
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.
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
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:
Esto luego de presiona tabulador agrega un nuevo evento en la clase actual:
Igualmente se hará con el evento CaptureFailed para detectar cualquier error en la captura de la foto quedando el código del siguiente modo.
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.
Una vez que presionar si Silverlight muestra el video en vivo en pantalla:
Pueden Parar la captura y dejara de visualizar el video en vivo de la cámara Web o Tomar una fotografía.
Espero les guste el Articulo y es todo por hoy y Puedes descargar el código acá se llama DemoMedia:
Muchas gracias y espero sea de su agrado







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.
Que bueno que te gusto miguel animate con silverlight puedes hacer muchas cosas
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
Me gusta lo voy a implementar Thank a lot…
Ok Alfredo espero te sirva de aprendizaje y nos compartas lo que puedas descubrir..