I'm a first timer with WPF and implementing a c# code for generating images captured from webcam in WPF. I have done it this far that currently it can get single image from the button click. But I want to take sequences of images captured (where each image has a slight difference from the previous one, depending on number of seconds/ms it is taken). The same functionality is achieved in javascript but I have come to know that javascript cannot be used in WPF applications.
Here is a code snippet so far that I have done
In XAML:
<Border Grid.Column="1" Grid.Row="1" BorderThickness="3" CornerRadius="3" Margin="0,0,0,1">
<Border.BorderBrush>
<RadialGradientBrush>
<GradientStop Color="Black" Offset="0.047"/>
<GradientStop Color="#FF00907A" Offset="1"/>
</RadialGradientBrush>
</Border.BorderBrush>
<Image x:Name="imgVideo" Stretch="Fill" />
</Border>
<Border Grid.Column="3" Grid.Row="1" BorderThickness="3" CornerRadius="3" Margin="0,0,0,1">
<Border.BorderBrush>
<RadialGradientBrush>
<GradientStop Color="Black" Offset="0.047"/>
<GradientStop Color="#FF00907A" Offset="1"/>
</RadialGradientBrush>
</Border.BorderBrush>
<Image x:Name="imgCapture" Stretch="None" Width="200" Height="150" />
</Border>
<StackPanel Grid.Column="3" Grid.Row="5" Orientation="Horizontal" HorizontalAlignment="Left" Width="162">
<Button x:Name="bntCapture" Content="Capture Image" Click="bntCapture_Click" />
</StackPanel>
In C# event handler
private void bntCapture_Click(object sender, RoutedEventArgs e)
{
for (int j = 1; j <=30;j++ )
{
string path = Directory.GetCurrentDirectory();
string em_cap_original_path=System.IO.Path.Combine(path, "Database");
imgCapture.Source = imgVideo.Source;
Helper.SaveImageCapture((BitmapSource)imgCapture.Source, em_cap_original_path, j);
}
MessageBox.Show("Images created");
}
This is Helper class
class Helper
{
//Block Memory Leak
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr handle);
public static BitmapSource bs;
public static IntPtr ip;
public static BitmapSource LoadBitmap(System.Drawing.Bitmap source)
{
ip = source.GetHbitmap();
bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ip, IntPtr.Zero, System.Windows.Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
DeleteObject(ip);
return bs;
}
public static void SaveImageCapture(BitmapSource bitmap, string em_cap_original_path, int counter)
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Interlace = PngInterlaceOption.On;
encoder.Frames.Add(BitmapFrame.Create(bitmap));
string img_path = em_cap_original_path + "/" + "frame" + counter + ".png";
FileStream fp;
fp = System.IO.File.Create(img_path);
encoder.Save(fp);
fp.Close();
}
}
This code can generate 10 images but they are shot of same image not from image sequence.
If anyone knows how I can do it. Any help will be appreciated.
If the loop in the even handler is how you take multiple pictures, you should wait a bit between taking the pictures, you could just do this:
private async void bntCapture_Click(object sender, RoutedEventArgs e)
{
for (int j = 1; j <= 30; j++)
{
string path = Directory.GetCurrentDirectory();
string em_cap_original_path = System.IO.Path.Combine(path, "Database");
imgCapture.Source = imgVideo.Source;
Helper.SaveImageCapture((BitmapSource)imgCapture.Source, em_cap_original_path, j);
await Task.Delay(20);//Delay in ms
}
MessageBox.Show("Images created");
}
notice the async
void and the await Task.Delay()