So, how do we capture an image from a WebCam?

Once you download the source code that is attached to the article you should have the following three projects:

  • Demo – simple Windows Forms project that demonstrates how a WebCam is used. It references WebCamWrapper which in turn references WebCamLib.
  • WebCamLib – this is where the magic is happening – it is a C++ project with just two files (WebCamLib.h andWebCamLib.cpp) that queries a WebCam using DirectShow and returns results.
  • WebCamWrapper – a C# wrapper on top of the C++ project that enables easy integration into the .NET world.

For a starting point I recommend a code view of Demo\MainForm.cs. This form implements most of the operations you can think of when it comes to WebCam access. First is the iteration through the WebCams hooked up to the computer:

private void MainForm_Load(object sender, EventArgs e)
{if (!DesignMode){comboBoxCameras.Items.Clear();foreach (Camera cam in CameraService.AvailableCameras)comboBoxCameras.Items.Add(cam);if (comboBoxCameras.Items.Count > 0)comboBoxCameras.SelectedIndex = 0;}
}

The CameraService class you see in the code is contained in the WebCamWrapper project and is the main wrapper over the main class CameraMethods that is the only class implemented in the C++ WebCamLib project.CameraService exposes AvailableCameras as a list of Camera classes that contain the logic for a certain WebCam. Once the user makes a choice of camera, you’ll obviously want to start the capture:

private CameraFrameSource _frameSource;
private static Bitmap _latestFrame;private void btnStart_Click(object sender, EventArgs e)
{if (_frameSource != null && _frameSource.Camera == comboBoxCameras.SelectedItem)return;thrashOldCamera();startCapturing();
}

  

_frameSource is the variable in which we’ll save the currently selected Camera. Touchless developers decided not to tie their capture source exclusively to WebCam (good choice obviously) so they made a generic IFrameSourceinterface that CameraFrameSource implements… and that’s how this class ended up as a container instead of theCamera class directly. The rest of the code is pretty self-explanatory – if we select the same frame source, we’ll just exit; if not we will thrash the old camera and start a new one. Onto the startCapturing method:

private void startCapturing()
{try{Camera c = (Camera)comboBoxCameras.SelectedItem;setFrameSource(new CameraFrameSource(c));_frameSource.Camera.CaptureWidth = 320;_frameSource.Camera.CaptureHeight = 240;_frameSource.Camera.Fps = 20;_frameSource.NewFrame += OnImageCaptured;pictureBoxDisplay.Paint += new PaintEventHandler(drawLatestImage);_frameSource.StartFrameCapture();}catch (Exception ex){comboBoxCameras.Text = "Select A Camera";MessageBox.Show(ex.Message);}
}private void setFrameSource(CameraFrameSource cameraFrameSource)
{if (_frameSource == cameraFrameSource)return;_frameSource = cameraFrameSource;
}private void drawLatestImage(object sender, PaintEventArgs e)
{if (_latestFrame != null){e.Graphics.DrawImage(_latestFrame, 0, 0, _latestFrame.Width, _latestFrame.Height);}
}public void OnImageCaptured(Touchless.Vision.Contracts.IFrameSource frameSource, Touchless.Vision.Contracts.Frame frame, double fps)
{_latestFrame = frame.Image;pictureBoxDisplay.Invalidate();
}

  

We start off by fetching the selected Camera from the ComboBox which we then use to create and set theCameraFrameSource. Lines after that influence the capture parameters (be sure to remember these three lines as we will be getting back to them later) and after that we have a subscription to two events.

The first event, NewFrame, is raised whenever WebCamLib captures an image from the WebCam. As you can see, we save that image into a local variable _latestFrame and from there you can do any additional image processing you like. The second event is just a fancy (and more efficient) way of saying pictureBoxDisplay.Image = frame.Image. For some reason, setting the Image property on a PictureBox too often causes flicker and we obviously do not want that – instead we resort to invalidating the PictureBox and then handling its paint event to draw the current image from the WebCam.

Now that all that is implemented, we just StartFrameCapture and enjoy the view from our WebCam. Try it out – press F5 and then click the ‘Start’ button once the Form loads up.

Rent is too damn high

When you grow tired of watching yourself, simply close the form. Once you are back in Visual Studio, check out thethrashOldCamera method (that is utilized from the Form_Closing and btnStop_Click methods also):

private void thrashOldCamera()
{if (_frameSource != null){_frameSource.NewFrame -= OnImageCaptured;_frameSource.Camera.Dispose();setFrameSource(null);pictureBoxDisplay.Paint -= new PaintEventHandler(drawLatestImage);}
}

  

Well, nothing too fancy – we unsubscribe from the two mentioned events, set the _frameSource variable to null, and call Dispose on Camera so that the C++ WebCamLib can perform cleanup operations.

Believe it or not – that’s it. There is nothing more critical to explain or implement in order to use images from your WebCam in C#. The extra code that exists in MainForm.cs is just there for saving the current image:

private void btnSave_Click(object sender, EventArgs e)
{if (_frameSource == null)return;Bitmap current = (Bitmap)_latestFrame.Clone();using (SaveFileDialog sfd = new SaveFileDialog()){sfd.Filter = "*.bmp|*.bmp";if (sfd.ShowDialog() == DialogResult.OK){current.Save(sfd.FileName);}}current.Dispose();
}

  

And bringing up the configuration dialog:

private void btnConfig_Click(object sender, EventArgs e)
{// snap cameraif (_frameSource != null)_frameSource.Camera.ShowPropertiesDialog();
}

  

Configuration Dialog

Problem(s)

As you can see from the code – the implementation is pretty easy and clean (unlike some other approaches that use WIA, obscure DLLs, clipboard, or hard disk for saving images, etc.), meaning that there are not many problems. Actually, currently there is only one problem I can identify. You remember these three lines?

_frameSource.Camera.CaptureWidth = 320;
_frameSource.Camera.CaptureHeight = 240;
_frameSource.Camera.Fps = 20;

Well, it turns out that they are not working as advertised. First, let’s talk about FPS. If we dive into the Camera class (line 254) here is what we will see (the method that gets called after an image is captured from the webcam):

Even if you just glanced at the method, you probably saw that most of it is dedicated to calculating the time between frames and ditching the frame if it came too soon. Which is not too bad, I guess – controlling the frame rate on C# level rather than on hardware level will probably not kill you.

But what about finding out the other two lines, which influence the size of the captured image, also not working (line 235 in Camera.cs)?

As you can see, the image size is actually faked. Majority of cameras I’ve tested out will tend to return images in the 640x480 size. Which is fine in most cases – if you need a smaller image, b.GetThumbnailImage will allow you to easily resize it. However, if you wish a higher resolution image, you are stuck and that’s not a good thing.

So, anyone from the C++ world is more than welcome to help with this. The following links I’ve read gave me the impression that all that’s needed to be done is somehow invoke the Video Format window in C++, the same way we are now invoking the Video Source Configuration window (for setting Brightness, Contracts, etc):

  • Setting up Webcam properties with DirectShow forum post
  • EasyWebCam project – for most part it is bad, but it does have a Video Format window. I decompiledWebCam_Capture.dll from the project only to find out that everything is implemented using PInvoke - meaning that it’s useless for our approach. So, if somebody can bring up that same window using C++ and DirectShow – please help out by extending the existing CameraMethods class.

Video Format Dialog

源码下载地址: Source

C# 使用摄像头拍照 支持Win7 64位相关推荐

  1. C#屏幕取色(支持Win7 64位 32位 WinXP)

    测试过对Win7 64位 32位 WinXP都可用的: http://www.cnblogs.com/hihell/archive/2011/09/16/2178660.html 网上能找到的几种方法 ...

  2. HP QC IE11不支持( win7 64位 无法安装)解决方法

    QC IE11不支持( win7 64位 无法安装)解决方法 使用HP公司的QC做项目缺陷管理,发现IE浏览器只支持IE7,IE8.安装插件ALP_Platform_Loader提示64位无法安装,顿 ...

  3. 64位计算机 内存,Win7 64位/32位系统支持多大内存?64/32位系统有什么区别?

    Win7 64位/32位系统支持多大内存?计算机上不同的操作系统对内存的支持是有限度的,且因为主板.CPU的存在,这样的限制只会更小,但还在用户可以接受的范围内.想知道什么原因限制了内存极限吗?请看下 ...

  4. win7 php 5.3,win7 64位 WAMP环境下(PHP5.3) redis扩展无法生效

    将正确的redis.dll(for php5.3 + apache)放入到ext目录下 在php.ini里边添加redis扩展. 但是打印出phpinfo 还是没有redis 无论如何都尝试不成功 w ...

  5. 怎么安装Scrapy框架以及安装时出现的一系列错误(win7 64位 python3 pycharm)

    因为要学习爬虫,就打算安装Scrapy框架,以下是我安装该模块的步骤,适合于刚入门的小白: 一.打开pycharm,依次点击File---->setting---->Project---- ...

  6. android+ndk+r9+x64下载,Win7 64位中文旗舰版上Cocos2d-x 3.0的Android开发调试环境架设

    系统环境: Win7 64位中文旗舰版 各组件的版本: VS2012 Python2.7.6 x86 安装步骤: 1.默认安装VS2012 2.默认安装Python 2.7.6,修改环境变量Path ...

  7. win7 64位系统配置服务器,Tomcat服务器win764位配置方法

    Tomcat服务器win764位配置方法 腾讯视频/爱奇艺/优酷/外卖 充值4折起 打开底部的网盘链接,将压缩包解压,如图 打开文件夹,在目录下找到bin文件夹,找到里面的startup.bat.双击 ...

  8. html chm 64,Win7 64位下的CHM

    最近下了几个沪江资料,都是chm格式的,但是在win7 64位下,都显示不了里面的音频和视频flash之类的控件,虽然可以通过源文件的方式打开视频文件,但是很麻烦. 网上似乎碰到的人也不是很多,基本就 ...

  9. 服务器重装系统用友u6,64系统装U6我用win7 64位旗舰版的系统,安装用

    近日使用的用友畅捷通T+财务管理软件的T6中碰到一个问题: 64系统装U6 详细的问题情况是这样的: 我用win7 64位旗舰版的系统,安装用友U6 3.2plus1,单机版,装完后运行系统管理,连不 ...

最新文章

  1. 零起点学算法11——求梯形面积
  2. 没有安装python如何使用anaconda运行python命令行
  3. 练笔--字符串,向量和数组2
  4. boost::mp11::mp_and相关用法的测试程序
  5. c语言程序源代码_程序的编译、链接和执行
  6. php curl 发送post请求带参数
  7. 详解loadrunner的think time
  8. 数码相机专业术语解答
  9. [原创] Ubuntu 安装vim与中文帮助文档
  10. linux命令ps -aux|grep xxx详解
  11. FL Studio20.8中文完整版本覆盖升级更新说明介绍v20.8.3
  12. 连麦互动技术及其连麦调研
  13. android 仿qq it蓝豹,十大Android开源项目-IT蓝豹
  14. 魔百盒ZXV10 B863AV3.2-M/B863AV3.1-M2_S905L3A-B_线刷+卡刷精简固件
  15. 第三届上海大学生网络安全
  16. 上火了该如何是好 五招让你轻松消火
  17. 关于个人网贷查询系统网贷信用查询,公司开发图片整合技术
  18. 含有一般疑问句的歌_一般疑问句,特殊疑问句和否定句
  19. 关于asc、txt格式到pcd、ply格式数据转换
  20. Python_小林的爬取QQ空间相册图片链接程序

热门文章

  1. VS2017环境下动态链接库编写及调用
  2. 【体系结构】shared pool的个人理解
  3. 在线最大公因数计算器
  4. 关闭Windows Defender保护
  5. springboot + shiro之登录人数限制、登录判断重定向、session时间设置
  6. 《云云众声》第95期:业界大事接着看 HP成功收购Aruba;IBM战略变动 前景发展被看好...
  7. HTML中的IE条件注释
  8. Android中Webview自适应屏幕
  9. 利用sender的Parent获取GridView中的当前行
  10. 合工大计算机学院吴辽源,计算机学院智能计算系统系召开人才培养大讨论专题会议...