C#调用笔记本摄像头当镜子用
发布日期:2021-05-09 04:22:21 浏览次数:18 分类:博客文章

本文共 4306 字,大约阅读时间需要 14 分钟。

前段时间看见别人写的一篇 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#真不愧是快餐语言,够快,够方便的 :)

上一篇:给Asp.net MVC Forms 验证设置角色访问控制
下一篇:C#实现简单的JSON序列化

发表评论

最新留言

不错!
[***.144.177.141]2025年04月14日 17时36分59秒