C#调用笔记本摄像头当镜子用

C#摄像头镜像应用
本文介绍了一款使用C#语言开发的应用程序,该程序能够将笔记本电脑上的摄像头变成一个实时显示的虚拟镜子,帮助用户整理仪容。通过调用Windows API函数,实现了摄像头视频流的捕获和显示。

作者:记忆的森林

转自:http://www.cnblogs.com/leonwang/archive/2011/08/12/2136657.html


前段时间看见别人写的一篇 c#调用网络摄像头的,正好搬到的新的地方,这地儿洗脸的地方木有镜子用,每天起床,头发总是很乱,也不想专门去超市买个镜子,又正好笔记本上有个摄像头,平时也木有MM跟偶视频聊天,纯粹的浪费了一个多好的功能,突发"奇想",视频不就是实时的吗,何不写个客户端程序,把摄像头当镜子用呢,想到此处,所以把别人的代码copy过来以定制偶整理头发的镜子,不过发现copy过来的代码偶尔不工作,重新修改了下,基本当个镜子木有问题了(当然木有镜子清晰!),只是有一个问题至今还木解决,视频源窗口偶尔会弹出来,不知道哪个筒子能解决,如下图(左),另外一张就是偶的镜子程序,刚下班回来,头发还不乱,稍加整理了下,截个了屏 #_#

 

 刚下班,所以人有点累,废话不多话,直接上代码,如下,希望对这个有兴趣的筒子也可以借鉴下,大家相互借鉴,相信总是可以做得更好 :)

 

复制代码
namespace  webcam
{
    
using  System;
    
using  System.Runtime.InteropServices;
    
using  System.Windows.Forms;

    
///   <summary>
    
///  Leon's webcam mirror
    
///   </summary>
     public   partial   class  WebCam : Form
    {
        
///   <summary>
        
///  Webcam handle. 
        
///   </summary>
         private   int  hHwnd;

        
public  WebCam()
        {
            InitializeComponent();
        }

        
public   struct  videohdr_tag
        {
            
public   byte [] lpData;
            
public   int  dwBufferLength;
            
public   int  dwBytesUsed;
            
public   int  dwTimeCaptured;
            
public   int  dwUser;
            
public   int  dwFlags;
            
public   int [] dwReserved;
        }

        
#region  P/Invoke

        [DllImport(
" avicap32.dll " , CharSet  =  CharSet.Ansi, SetLastError  =   true , ExactSpelling  =   true )]
        
public   static   extern   int  capCreateCaptureWindowA([MarshalAs(UnmanagedType.VBByRefStr)]    ref     string  lpszWindowName,  int  dwStyle,  int  x,  int  y,  int  nWidth,  short  nHeight,  int  hWndParent,  int  nID);
        [DllImport(
" avicap32.dll " , CharSet  =  CharSet.Ansi, SetLastError  =   true , ExactSpelling  =   true )]
        
public   static   extern   bool  capGetDriverDescriptionA( short  wDriver, [MarshalAs(UnmanagedType.VBByRefStr)]    ref     string  lpszName,  int  cbName, [MarshalAs(UnmanagedType.VBByRefStr)]    ref     string  lpszVer,  int  cbVer);
        [DllImport(
" user32 " , CharSet  =  CharSet.Ansi, SetLastError  =   true , ExactSpelling  =   true )]
        
public   static   extern   bool  DestroyWindow( int  hndw);
        [DllImport(
" user32 " , EntryPoint  =   " SendMessageA " , CharSet  =  CharSet.Ansi, SetLastError  =   true , ExactSpelling  =   true )]
        
public   static   extern   int  SendMessage( int  hwnd,  int  wMsg,  int  wParam, [MarshalAs(UnmanagedType.AsAny)]    object  lParam);
        [DllImport(
" user32 " , CharSet  =  CharSet.Ansi, SetLastError  =   true , ExactSpelling  =   true )]
        
public   static   extern   int  SetWindowPos( int  hwnd,  int  hWndInsertAfter,  int  x,  int  y,  int  cx,  int  cy,  int  wFlags);
        [DllImport(
" vfw32.dll " )]
        
public   static   extern   string  capVideoStreamCallback( int  hwnd, videohdr_tag videohdr_tag);
        [DllImport(
" vicap32.dll " , CharSet  =  CharSet.Ansi, SetLastError  =   true , ExactSpelling  =   true )]
        
public   static   extern   bool  capSetCallbackOnFrame( int  hwnd,  string  s);

        
#endregion

        
///   <summary>
        
///  Initialize webcam and display the video in a panel.
        
///   </summary>
        
///   <returns></returns>
         private   bool  InitializeWebcam()
        {
            
bool  ok  =   false ;

            
int  intWidth  =   this .panel1.Width;
            
int  intHeight  =   this .panel1.Height;
            
int  intDevice  =   0 ;
            
string  refDevice  =  intDevice.ToString();

            
// Create vedio and get the window handle.
            hHwnd  =  WebCam.capCreateCaptureWindowA( ref  refDevice,  1342177280 0 0 640 480 this .panel1.Handle.ToInt32(),  0 );
           
            
if  (WebCam.SendMessage(hHwnd,  0x40a , intDevice,  0 >   0 )
            {
                WebCam.SendMessage(
this .hHwnd,  0x435 - 1 0 );
                WebCam.SendMessage(
this .hHwnd,  0x434 0x42 0 );
                WebCam.SendMessage(
this .hHwnd,  0x432 - 1 0 );
                WebCam.SetWindowPos(
this .hHwnd,  1 0 0 , intWidth, intHeight,  6 );

                ok 
=   true ;
            }
            
else
            {
                WebCam.DestroyWindow(
this .hHwnd);
            }

            
return  ok;
        }
        
///   <summary>
        
///  App run, then invoke the webcam till successfully.
        
///   </summary>
        
///   <param name="sender"></param>
        
///   <param name="e"></param>
         private   void  WebCam_Load( object  sender, EventArgs e)
        {
            
bool  ok  =   false ;

            
while  ( ! ok)
            {
                ok 
=   this .InitializeWebcam();
                System.Threading.Thread.Sleep(
100 );
            }
        }
        
private   void  CloseWebcam()
        {
            
if  ( this .hHwnd  >   0 )
            {
                WebCam.SendMessage(
this .hHwnd,  0x40b 0 0 );
                WebCam.DestroyWindow(
this .hHwnd);
            }
        }
        
///   <summary>
        
///  when close window, destroy the webcam window.
        
///   </summary>
        
///   <param name="sender"></param>
        
///   <param name="e"></param>
         private   void  WebCam_FormClosed( object  sender, FormClosedEventArgs e)
        {
            CloseWebcam();
        }
        
///   <summary>
        
///  when window size changed, resize webcam pic.
        
///   </summary>
        
///   <param name="sender"></param>
        
///   <param name="e"></param>
         private   void  WebCam_SizeChanged( object  sender, EventArgs e)
        {
            WebCam.SetWindowPos(
this .hHwnd,  1 0 0 , this .Width, this .Height,  6 );
        }
    }
}
复制代码

 

排列控件的Designer代码就不贴了,就一个panel控件,相信大家一看就懂的:) , 实现这个“镜子”的代码,所花的时间还真的比去超市的买个镜子花的时间少哈,而且还变废为宝,c#真不愧是快餐语言,够快,够方便的 :)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值