Why is webcam freezing after certain time - c#

I coded an application that has a webcam which can SCAN QR codes:
VideoCaptureDevice LocalWebCam;
public FilterInfoCollection LoaclWebCamsCollection;
void Cam_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
try
{
BitmapImage bi;
using (var bitmap = (Bitmap)eventArgs.Frame.Clone())
{
bi = new BitmapImage();
bi.BeginInit();
MemoryStream ms = new MemoryStream();
bitmap.Save(ms, ImageFormat.Bmp);
bi.StreamSource = ms;
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.EndInit();
}
bi.Freeze();
Dispatcher.BeginInvoke(new ThreadStart(delegate { frameHolder.Source = bi; }));
}
catch
{
//some error
}
and
void Window2_Loaded(object sender, RoutedEventArgs e)
{
LoaclWebCamsCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);
LocalWebCam = new VideoCaptureDevice(LoaclWebCamsCollection[0].MonikerString);
LocalWebCam.NewFrame += new NewFrameEventHandler(Cam_NewFrame);
LocalWebCam.Start();
timer.Start(); // QR CODE SCANNER
}
It works all fine but when I let the application run for some longer time the webam freezes. Does someone have an idea why?

Related

Must create DependencySource on same Thread as the DependencyObject even by using Dispatcher WPF

I am writing a C# WPF application, I am using the AForge library for video streaming.
I wanted to deploy the application, because everything worked on the first pc.
Than I deployed it and on the other pc I get the following Error:
"Must create DependencySource on same Thread as the DependencyObject even by using Dispatcher"
This is the source Code, I am calling it on every new Frame which I get from the WebCam
private void video_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
if (StreamRunning)
{
try
{
using (var bitmap = (Bitmap)eventArgs.Frame.Clone())
{
Image = ToBitmapImage(bitmap);
}
Image.Freeze();
}
catch (Exception e)
{
UIMessages = "Error: NewFrame " + e.Message;
}
}
}
ToBitmapImage Method:
private BitmapImage ToBitmapImage(Bitmap bitmap)
{
var start = 420;
var end = 1920 - 2* 420;
BitmapImage bi = new BitmapImage();
bi.BeginInit();
MemoryStream ms = new MemoryStream();
Bitmap source = bitmap;
Bitmap CroppedImage = source.Clone(new System.Drawing.Rectangle(start, 0, end, 1080), source.PixelFormat);
CroppedImage.Save(ms, ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);
bi.StreamSource = ms;
bi.EndInit();
return bi;
}
Further code:
private BitmapImage _image;
public BitmapImage Image {
get => _image;
set
{
_image = value;
OnPropertyChanged();
}
}
The start of the camera:
if (SelectedDevice != null)
{
_videoSource = new VideoCaptureDevice(SelectedDevice.MonikerString);
//var test = _videoSource.VideoCapabilities;
_videoSource.NewFrame += video_NewFrame;
_videoSource.Start();
}
UI:
<Image Height="400" Width="400" Source="{Binding Image, UpdateSourceTrigger=PropertyChanged}" Margin="0,0,0,0"/>
I also tried this out:
Dispatcher.CurrentDispatcher.Invoke(() => Image = ToBitmapImage(bitmap));
When loading a BitmapImage from a Stream, you would usually close the Stream as soon as possible and make sure the BitmapImage is loaded immediately, by setting BitmapCacheOption.OnLoad.
private static BitmapImage ToBitmapImage(Bitmap bitmap)
{
var start = 420;
var end = 1920 - 2 * 420;
var croppedBitmap = bitmap.Clone(
new System.Drawing.Rectangle(start, 0, end, 1080),
bitmap.PixelFormat);
var bi = new BitmapImage();
using (var ms = new MemoryStream())
{
croppedBitmap.Save(ms, ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);
bi.BeginInit();
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.StreamSource = ms;
bi.EndInit();
}
bi.Freeze();
return bi;
}

Fetching Web Image and showing in Image control after interval - not working

I have a custom UserControl with an Image control in it. I'm trying to fetch an image from web[network server] and show it in my control, refreshing the source using a dispatcher timer. Here is the code:
void StartSourceRefresh()
{
if (timeinterval < 1) timeinterval = 1;
tmrRefresh.Tick += new EventHandler(dispatcherTimer_Tick);
tmrRefresh.Interval = new TimeSpan(0, 0, timeinterval); //in hour-minute-second
tmrRefresh.Start();
}
public void ChangeImageSource(string newSource)
{
//newSource = "http://192.168.1.3/abc/imagetobeshown.png"
WebImg.Source = null;
if (newSource.Trim() == "")
WebImg.Source = new BitmapImage(new Uri(#imagePlaceholder, UriKind.Absolute));
else
{
BitmapImage image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri(#newSource, UriKind.Absolute);
image.EndInit();
WebImg.Source = image;
}
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
ChangeImageSource(txtImgSrc.Text.Trim());
}
the problem is the image wont change. Its showing the same one which was fetched at the first time. Timer is running fine. But the image just won't change. What am i doing wrong here?
Edit: Network Source gets refreshed after certain interval, so have to fetch the same source
You are apparently reloading from the same image URL, which is cached by default.
Disable caching by setting BitmapCreateOptions.IgnoreImageCache:
var image = new BitmapImage();
image.BeginInit();
image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
image.UriSource = new Uri(newSource);
image.EndInit();

Xaml C# replacing images from an array of images

Ik in windows forms I could add images in resources and then change the images as users click on an event handler not sure whats changed in Xaml but I cant figure it out.
private void guessClick(object sender, RoutedEventArgs e)
{
wrongGuesses++;
hangmanPicture.Image = hangmanImage[wrongGuesses];
}
if I just put hangmanPicture = hangmanImage[wrongGuesses];
I get can not convert. I don't understand why its trying to convert anything.
if your hangmanImage array is an array of ImageSource or BitmapImage, you can use it like this:
private void guessClick(object sender, RoutedEventArgs e)
{
wrongGuesses++;
hangmanPicture.Source = hangmanImage[wrongGuesses];
}
Otherwise, you have to convert anything in hangmanImage into ImageSource or BitmapImage.
If it's Bitmap you can use below converter before that code:
public static BitmapImage ConvertToBitmapImageFromBitmap(Bitmap bitmap)
{
using(var memory = new MemoryStream())
{
BitmapImage bitmapImage;
bitmap.Save(memory, ImageFormat.Png);
memory.Position = 0;
bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
return bitmapImage;
}
}
So, then it will be like this:
hangmanPicture.Source = ConvertToBitmapImageFromBitmap(hangmanImage[wrongGuesses]);

Desktop screen capture

I try to receive a desktop screen capture from my PC using WPF (Client and server side WPF)
here is my code
private void ViewReceivedImage(byte[] buffer)
{
try
{
using (MemoryStream memoryStream = new MemoryStream(buffer))
{
BitmapImage imageSource = new BitmapImage();
imageSource.BeginInit();
imageSource.StreamSource = memoryStream;
imageSource.EndInit();
// Assign the Source property of your image
MyImage.Source = imageSource;
}
//MemoryStream ms = new MemoryStream(buffer);
//BitmapImage bi = new BitmapImage();
//bi.SetSource = ms;
//MyImage.Source = bi;
//ms.Close();
}
catch (Exception) { }
finally
{
StartReceiving();
}
}
The commented line above are for Windows phone app, I have already tested it and it works with WP8(Client Side), I have the problem only on WPF Client Side.
WPF Server Side and WP8 Client Side works
WPF Client Side not working but connection is successful
this method sends the image
void StartSending()
{
while (!stop)
try
{
System.Drawing.Image oldimage = scr.Get_Resized_Image(wToCompare, hToCompare, scr.GetDesktopBitmapBytes());
//Thread.Sleep(1);
System.Drawing.Image newimage = scr.Get_Resized_Image(wToCompare, hToCompare, scr.GetDesktopBitmapBytes());
byte[] buffer = scr.GetDesktop_ResizedBytes(wToSend, hToSend);
//float difference = scr.difference(newimage, oldimage);
//if (difference >= 1)
//{
SenderSocket.Send(buffer);
//}
}
catch (Exception) { }
}
and this Get_Resized_Image
public Image Get_Resized_Image(int w, int h, byte[] image)
{
MemoryStream ms = new MemoryStream(image);
Image bt = Image.FromStream(ms);
try
{
Size sizing = new Size(w, h);
bt = new System.Drawing.Bitmap(bt, sizing);
}
catch (Exception) { }
return bt;
}
edited
this is the output

Choosing image from windows phone media library and set as page background

I am trying to retrieve an image from the phone library and set it as the page background using the following code
private void selectImageFromMediaLib()
{
selectphoto = new PhotoChooserTask();
selectphoto.Completed += new EventHandler<PhotoResult>(selectphoto_Completed);
selectphoto.Show();
}
private void selectphoto_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
backgroundUri = new Uri(e.OriginalFileName, UriKind.Absolute);
var bitmap = new BitmapImage(backgroundUri);
ImageBrush imageBrush = new ImageBrush();
imageBrush.ImageSource = bitmap;
this.LayoutRoot.Background = imageBrush;
}
}
However, the page background turns black so the photo was not retrieved/created correctly. What is the correct path for the URI to the device library? Isn't using UriKind.Absolute enough?
You can't use the PhotoResult.OriginalFileName property to read the file, instead use the
PhotoResult.ChosenPhoto stream and assign it to the bitmap.ImageSource property in your code.
try this. It works for me
PhotoChooserTask selectphoto;
private void selectImageFromMediaLib()
{
selectphoto = new PhotoChooserTask();
selectphoto.Completed += new EventHandler<PhotoResult>(selectphoto_Completed);
selectphoto.Show();
}
private void selectphoto_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
var imageBytes = new byte[e.ChosenPhoto.Length];
e.ChosenPhoto.Read(imageBytes, 0, imageBytes.Length);
BitmapImage bitmapImage = new BitmapImage();
MemoryStream ms = new MemoryStream(imageBytes);
bitmapImage.SetSource(ms);
ImageBrush imageBrush = new ImageBrush();
imageBrush.ImageSource = bitmapImage;
this.LayoutRoot.Background = imageBrush;
}
}

Categories

Resources