Capture images from webcam in c# [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I've been working on an application which generates and reads(decode) QR codes. In decoding part the user capture the picture of QR code and the program will start process of decoding.
My problem is I don't Know how I can take the photo.
P.S:
If you offer a library please give a link which contains the tutorial of using that lib.
Thank you.

I have been looking for web cam recording since a long time, you can use Aforge.NET .
Here is code for the same using WPF :
public partial class MainWindow : Window
{
private FilterInfoCollection VideoCaptureDevices;
private VideoCaptureDevice FinalVideo;
public VideoFileWriter writer= new VideoFileWriter();
public MainWindow()
{
InitializeComponent();
VideoCaptureDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach (FilterInfo VideoCaptureDevice in VideoCaptureDevices)
{
comboBox1.Items.Add(VideoCaptureDevice.Name);
}
comboBox1.SelectedIndex = 0;
}
private void button1_Click(object sender, EventArgs e)
{
writer.Open(#"d:\\newVid.avi", 640, 480, 25, VideoCodec.MPEG4);
FinalVideo = new VideoCaptureDevice(VideoCaptureDevices[comboBox1.SelectedIndex].MonikerString);
FinalVideo.NewFrame += new NewFrameEventHandler(FinalVideo_NewFrame);
FinalVideo.Start();
}
void FinalVideo_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
System.Drawing.Image imgforms = (Bitmap)eventArgs.Frame.Clone();
Bitmap bmp = (Bitmap)eventArgs.Frame.Clone();
BitmapImage bi = new BitmapImage();
bi.BeginInit();
MemoryStream ms = new MemoryStream();
imgforms.Save(ms, ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);
bi.StreamSource = ms;
bi.EndInit();
//Using the freeze function to avoid cross thread operations
bi.Freeze();
//Calling the UI thread using the Dispatcher to update the 'Image' WPF control
Dispatcher.BeginInvoke(new ThreadStart(delegate
{
pictureBox1.Source = bi; /*frameholder is the name of the 'Image' WPF control*/
}));
for (int i = 0; i < 2; i++)
{
writer.WriteVideoFrame(bmp);
}
}
private void Stop_Click(object sender, RoutedEventArgs e)
{
writer.Close();
FinalVideo.Stop();
this.Close();
}
}
include below namespaces:
using AForge.Video;
using AForge.Video.DirectShow;
using AForge.Video.FFMPEG;
using System.Drawing.Drawing2D;
using AForge.Video.VFW;
You can set change frame rate as per your convenience.

Related

Capture images using usb Camera using C# desktop app

I am developing an app in which i want to capture images from a usb camera, i have seen many examples on the internet in which you have to initialize video first and then capture images from in using a button configured to do so. the problem is i want to capture the images without initializing the video first so it has to done be anonymously and then save it in some folder and write its location in database
any idea how it can be done?
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using System.Windows.Forms;
// Important: include the opencvsharp library in your code
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace Sandbox
{
public partial class Form1 : Form
{
// Create class-level accesible variables
VideoCapture capture;
Mat frame;
Bitmap image;
private Thread camera;
bool isCameraRunning = false;
// Declare required methods
private void CaptureCamera()
{
camera = new Thread(new ThreadStart(CaptureCameraCallback));
camera.Start();
}
private void CaptureCameraCallback()
{
frame = new Mat();
capture = new VideoCapture(0);
capture.Open(0);
if (capture.IsOpened())
{
while (isCameraRunning)
{
capture.Read(frame);
image = BitmapConverter.ToBitmap(frame);
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
}
pictureBox1.Image = image;
}
}
}
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
// When the user clicks on the start/stop button, start or release the camera and setup flags
private void button1_Click(object sender, EventArgs e)
{
if (button1.Text.Equals("Start"))
{
CaptureCamera();
button1.Text = "Stop";
isCameraRunning = true;
}
else
{
capture.Release();
button1.Text = "Start";
isCameraRunning = false;
}
}
// When the user clicks on take snapshot, the image that is displayed in the pictureBox will be saved in your computer
private void button2_Click(object sender, EventArgs e)
{
if (isCameraRunning)
{
// Take snapshot of the current image generate by OpenCV in the Picture Box
Bitmap snapshot = new Bitmap(pictureBox1.Image);
// Save in some directory
// in this example, we'll generate a random filename e.g 47059681-95ed-4e95-9b50-320092a3d652.png
// snapshot.Save(#"C:\Users\sdkca\Desktop\mysnapshot.png", ImageFormat.Png);
snapshot.Save(string.Format(#"C:\Users\sdkca\Desktop\{0}.png", Guid.NewGuid()), ImageFormat.Png);
}
else
{
Console.WriteLine("Cannot take picture if the camera isn't capturing image!");
}
}
}
}

AForge Convertation and problems with HD

First of all, I can't play and record HD video(1920x1080), when I change my camera resolution to 1920x1080 program show and record black background, if camera resolution is 720x576 it works without problems. I'm sure that the problem is in my solution because, when I use DesktopVideo(Software which is included with Blackmagic Decklink Studio 2) it shows HD video from camera.
Second, How do I convert video with AForge? like changing resolution and framerate, I can change codecs and bitrate, but when I change Resolution and FrameRate in "FileWriter.Open"
command I get Error Resolution and FrameRate must be the same as Bitmap I'm capturing from camera.
If anybody knows how to solve these problems please share information, thanks!
Here is the code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AForge.Video;
using AForge.Video.DirectShow;
using AForge.Video.FFMPEG;
using AForge.Video.VFW;
namespace WindowsFormsApplication12
{
public partial class Form1 : Form
{
private FilterInfoCollection VideoCaptureDevices;
private VideoCaptureDevice FinalVideo = null;
private VideoCaptureDeviceForm captureDevice;
private Bitmap video;
//private AVIWriter AVIwriter = new AVIWriter();
private VideoFileWriter FileWriter = new VideoFileWriter();
private SaveFileDialog saveAvi;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
VideoCaptureDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
captureDevice = new VideoCaptureDeviceForm();
}
private void button1_Click(object sender, EventArgs e)
{
/////capture device list
if (captureDevice.ShowDialog(this) == DialogResult.OK)
{
VideoCaptureDevice videoSource = captureDevice.VideoDevice;
FinalVideo = captureDevice.VideoDevice;
FinalVideo.NewFrame += new NewFrameEventHandler(FinalVideo_NewFrame);
FinalVideo.Start();
}
}
void FinalVideo_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
if (butStop.Text == "Stop Record")
{
video = (Bitmap)eventArgs.Frame.Clone();
pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone();
//AVIwriter.Quality = 0;
FileWriter.WriteVideoFrame(video);
//AVIwriter.AddFrame(video);
}
else
{
video = (Bitmap)eventArgs.Frame.Clone();
pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone();
}
}
private void button2_Click(object sender, EventArgs e)
{
////record button
saveAvi = new SaveFileDialog();
saveAvi.Filter = "Avi Files (*.avi)|*.avi";
if (saveAvi.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
int h = captureDevice.VideoDevice.VideoResolution.FrameSize.Height;
int w = captureDevice.VideoDevice.VideoResolution.FrameSize.Width;
FileWriter.Open(saveAvi.FileName, w, h,25,VideoCodec.Default,5000000);
FileWriter.WriteVideoFrame(video);
//AVIwriter.Open(saveAvi.FileName, w, h);
butStop.Text = "Stop Record";
//FinalVideo = captureDevice.VideoDevice;
//FinalVideo.NewFrame += new NewFrameEventHandler(FinalVideo_NewFrame);
//FinalVideo.Start();
}
}
private void butStop_Click(object sender, EventArgs e)
{
if (butStop.Text == "Stop Record")
{
butStop.Text = "Stop";
if (FinalVideo == null)
{ return; }
if (FinalVideo.IsRunning)
{
//this.FinalVideo.Stop();
FileWriter.Close();
//this.AVIwriter.Close();
pictureBox1.Image = null;
}
}
else
{
this.FinalVideo.Stop();
FileWriter.Close();
//this.AVIwriter.Close();
pictureBox1.Image = null;
}
}
private void button3_Click(object sender, EventArgs e)
{
pictureBox1.Image.Save("IMG" + DateTime.Now.ToString("hhmmss") + ".jpg");
}
private void button4_Click(object sender, EventArgs e)
{
this.Close();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (FinalVideo == null)
{ return; }
if (FinalVideo.IsRunning)
{
this.FinalVideo.Stop();
FileWriter.Close();
//this.AVIwriter.Close();
}
}
}
}
The provided code simply captures and saves in the format currently active/selected for the capture device. In general, resolution change is an "expensive" operation is not available as a complimentary operation.
You want to change resolution right on capture device by switching it to more appropriate format, then capture in this resolution and have all further data manipulation in correct resolution. Available resolutions and options might be hardware specific there.
If/when no suitable capture resolution option is available, you typically resample the video to new resolution. Even though Windows API has suitable functionality, in your particular case you are interested to have this integrated with AForge library and you need to check its documentation to find out whether it provides a respective wrapper and whether it can be integrated into capture process overall (or, you need to write this code yourself to handle scaling).

Saving image in picture box to specific directory

I am trying to save webcam image in directory using AForge.NET.
Here is my Code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
FilterInfoCollection webcam;
VideoCaptureDevice cam;
Bitmap bitmap;
private void Form1_Load(object sender, EventArgs e)
{
webcam = new FilterInfoCollection(FilterCategory.VideoInputDevice);
cam = new VideoCaptureDevice(webcam[0].MonikerString);
cam.NewFrame += new NewFrameEventHandler(cam_NewFrame);
cam.Start();
}
void cam_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
bitmap = (Bitmap)eventArgs.Frame.Clone();
pictureBox1.Image = bitmap;
pictureBox1.Image.Save("c:\\image\\image1.jpg");
}
But i am getting this exception:
InvalidOperationException was unhandled
Object is currently in use elsewhere.
If you are using Graphic objects after the GetHdc method, call the RealseHdc method.
Thanks in advance.
Problem is this line:
pictureBox1.Image = bitmap;
pictureBox1.Image.Save("c:\\image\\image1.jpg");
You are trying to save image that is not yet properly loaded and also you are facing cross-threading.
The solution in this case is to not use multiple threads when drawing.
void cam_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
bitmap = (Bitmap)eventArgs.Frame.Clone();
pictureBox1.Image = bitmap;
try
{
this.Invoke((MethodInvoker)delegate
{
//saves image on its thread
pictureBox1.Image.Save("c:\\image\\image1.jpg");
});
}
catch (Exception ex)
{
MessageBox.Show(""+ex);
}
}

Refactor code - make class [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I want to make a class Photo where can I submit methods, because I will be use these methods many times in many pages.
So how can I send my image in parameter ?
Now I have :
PhotoChooserTask selectPhoto = null;
private void chooseLogoButton_Click(object sender, RoutedEventArgs e)
{
selectPhoto = new PhotoChooserTask();
selectPhoto.Completed += new EventHandler<PhotoResult>(selectPhoto_Completed);
selectPhoto.Show();
}
void selectPhoto_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
MessageBox.Show(e.ChosenPhoto.Length.ToString());
//Code to display the photo on the page in an image control named myImage.
System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
bmp.SetSource(e.ChosenPhoto);
logoQrCodeImage.Source = bmp;
}
}
And I made a class Photo:
public class Photo
{
PhotoChooserTask selectPhoto = null;
public void chooseLogo()
{
selectPhoto = new PhotoChooserTask();
selectPhoto.Completed += new EventHandler<PhotoResult>(selectPhoto_Completed);
selectPhoto.Show();
}
void selectPhoto_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
MessageBox.Show(e.ChosenPhoto.Length.ToString());
//Code to display the photo on the page in an image control named myImage.
System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
bmp.SetSource(e.ChosenPhoto);
logoQrCodeImage.Source = bmp; //ERROR
}
}
}
You could build your class to support Tasks and then use an async/await event handler. So your class would look like this:
public class PhotoChooser
{
public Task<BitmapImage> ChoosePhoto()
{
var taskSource = new TaskCompletionSource<BitmapImage>();
var chooser = new PhotoChooserTask();
chooser.Completed += (s, e) =>
{
if (e.ChosenPhoto == null)
{
taskSource.SetResult(null);
}
else
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(e.ChosenPhoto);
taskSource.SetResult(bmp);
}
};
chooser.Show();
return taskSource.Task;
}
}
The your event handler would look like this:
private async void ChoosePhoto_OnClick(object sender, RoutedEventArgs e)
{
var chooser = new PhotoChooser();
logoQrCodeImage.Source = await chooser.ChoosePhoto();
}
Update:
If you are using Windows Phone 7 you can still use async and await by adding the Async for Silverlight, .NET 4, Windows Phone NuGet Package. Just add a nuget reference and search for Async. It should be the first one.
You can supply a callback on what to do when the photo finishes selecting.
For example, you can add event to Photo class (you'd need to define class PhotoEventHandler too)
public class PhotoEventArgs
{
public Bitmap Bmp;
}
public event EventHandler<PhotoEventArgs> photoSelectCompleted;
and in the method invoke the event
void selectPhoto_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
MessageBox.Show(e.ChosenPhoto.Length.ToString());
//Code to display the photo on the page in an image control named myImage.
System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
bmp.SetSource(e.ChosenPhoto);
if (photoSelectCompleted != null)
photoSelectCompleted(this, new PhotoEventArgs(){ Bmp = bmp;});
}
}
and in the original page subscribe to the event and in the eventhandler do this:
void photoSelectCompleted(object sender, PhotoEventArgs e)
{
logoQrCodeImage.Source = e.Bmp;
}

How to resize multiple images [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
My task is to resize multiple images. I tried this code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Boyutlandir
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string dosyaYolu = string.Empty;
Bitmap bmp = null;
OpenFileDialog openFileDialogDosyaAc = new OpenFileDialog();
private void button1_Click(object sender, EventArgs e)
{
openFileDialogDosyaAc.Multiselect = true;
if (openFileDialogDosyaAc.ShowDialog() == DialogResult.OK)
{
dosyaYolu = openFileDialogDosyaAc.FileName;
bmp = new Bitmap(openFileDialogDosyaAc.FileNames.ToString());
pictureBox1.Image = bmp;
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
}
}
private void button2_Click(object sender, EventArgs e)
{
Bitmap bmpKucuk = new Bitmap(pictureBox1.Image,Convert.ToInt32(textBox1.Text),Convert.ToInt32(textBox2.Text));
pictureBox1.Image = bmpKucuk;
pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;
}
private void button3_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "jpeg dosyası(*.jpg)|*.jpg|Bitmap(*.bmp)|*.bmp";
DialogResult sonuc = sfd.ShowDialog();
if (sonuc == DialogResult.OK)
{
pictureBox1.Image.Save(sfd.FileName);
}
}
}
}
Ok, so you are using winforms and want to open multiple files? or a directory? and want to resize them. but there is nothing resized? or do I need more coffee? use http://nuget.org/packages/ImageResizer/ and I don't see a loop to loop over the files you want to resize.
Read more about the imageresizer component here: http://imageresizing.net/docs/managed
in your button1 click event, do something like this:
private void button1_Click(object sender, EventArgs e)
{
DialogResult dr = this.openFileDialogDosyaAc.ShowDialog();
if (dr == System.Windows.Forms.DialogResult.OK)
{
// Read the files
foreach (String file in openFileDialogDosyaAc.FileNames)
{
//resize and save
}
}
}

Categories