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

前段时间看见别人写的一篇 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, 134217728000640480this.panel1.Handle.ToInt32(), 0);
           
            
if (WebCam.SendMessage(hHwnd, 0x40a, intDevice, 0> 0)
            {
                WebCam.SendMessage(
this.hHwnd, 0x435-10);
                WebCam.SendMessage(
this.hHwnd, 0x4340x420);
                WebCam.SendMessage(
this.hHwnd, 0x432-10);
                WebCam.SetWindowPos(
this.hHwnd, 100, 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, 0x40b00);
                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, 100,this.Width,this.Height, 6);
        }
    }
}

 

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

posted @ 2011-08-12 19:54  记忆的森林  阅读(8411)  评论(12编辑  收藏  举报