实例介绍
【实例简介】摄像头示例程序
【实例截图】
【核心代码】
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 System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Runtime.Serialization;
using System.Reflection;
namespace GD.VideoCapture2
{
public delegate void CameraPictureGetEventHandler(Image mainImage, Image subImage, string memo, Size cutSize);
public partial class FormVideoAforge : Form
{
public FormVideoAforge(bool enableEvent = true, bool enableSubVideo = false, bool maxForm = false, int mainDatumWdith = 1600, int submainDatumWdith = 640, bool showCutLine = true)
{
InitializeComponent();
if (maxForm)
this.WindowState = FormWindowState.Maximized;
this.MainDatumWdith = mainDatumWdith;
this.SubmainDatumWdith = submainDatumWdith;
this.EnableEvent = enableEvent;
this.groupBox1.Enabled = enableSubVideo;
this.checkBox1.Checked = showCutLine;
try
{
allDevice = new FilterInfoCollection(FilterCategory.VideoInputDevice);
if (allDevice == null || allDevice.Count == 0)
{
this.btnGetImage.Enabled = false;
}
else
{
cboMainDevices.Items.Clear();
cboSubDevices.Items.Clear();
foreach (FilterInfo item in allDevice)
{
cboMainDevices.Items.Add(item.Name);
cboSubDevices.Items.Add(item.Name);
}
cboSubDevices.SelectedIndex = -1;
cboMainDevices.SelectedIndex = 0;
MainSelectedIndex = 0;
}
}
catch { }
dotLine = new Pen(Color.LightGray, 1);
dotLine.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
dotLine.DashPattern = new float[] { 4f, 4f };
sline = new Pen(Color.LightGray, 2);
VideoCenterCutPercentage = 30f;
}
public static System.Windows.Forms.PictureBox ReturnPictureBox=null;
private FilterInfoCollection allDevice = null;
private VideoCaptureDevice mainDevice = null;
private VideoCaptureDevice subDevice = null;
#region public
/// <summary>
/// 视频拍照照片
/// </summary>
public Image VideoMainImage { get; set; }
/// <summary>
/// 副视频拍照照片
/// </summary>
public Image VideoSubImage { get; set; }
/// <summary>
/// 采集项目键值示例 名称|键值,若事件通知则也携带该值
/// </summary>
public string VideoMemo { get; set; }
/// <summary>
/// 需要绑定的字典,键值=Value ,名称=Name
/// </summary>
public DataTable VideoItemsSource { get; set; }
/// <summary>
/// 从图像中心算起,截取图片的大小.
/// </summary>
public Size VideoCenterCutSize { get; set; }
/// <summary>
/// 当前控件显示区域辅助线中心区域占总宽度和高度的百分比,做截图用
/// </summary>
public float VideoCenterCutPercentage { get; set; }
public event CameraPictureGetEventHandler VideoImageGet_Event = null;
public void OnCameraPictureGet(Image mainImage, Image subImage, string memo, Size cutSize)
{
if (VideoImageGet_Event != null)
{
VideoImageGet_Event.Invoke(mainImage, subImage, memo, cutSize);
}
}
#endregion
#region private
/// <summary>
/// 表示是否启用事件获取图片
/// </summary>
private bool EnableEvent { get; set; }
/// <summary>
/// 主摄像参考基准宽度
/// </summary>
private int MainDatumWdith = 1600;
/// <summary>
/// 副摄像头参考基准宽度
/// </summary>
private int SubmainDatumWdith = 640;
private int MainSelectedIndex = -1;
private int SubMainSelectedIndex = -1;
private Pen dotLine = null;
private Pen sline = null;
private Size cropSize = Size.Empty;//辅助线中间区域大小
private object syncLock = new object();
/// <summary>
/// 根据基准参考数值设置分辨率
/// </summary>
private void SetCapabilitiesByDatumWdith(int para, VideoCaptureDevice device)
{
if (device.VideoCapabilities.Length == 0)
{
return;
}
var bestCapList = device.VideoCapabilities.Where(w => w.FrameSize.Width.Equals(para));
if (bestCapList != null && bestCapList.Count() > 0)//选择最优
{
var cap = bestCapList.OrderByDescending(o => o.FrameSize.Height).FirstOrDefault();
device.VideoResolution = cap;
return;
}
var capabilities = device.VideoCapabilities.OrderByDescending(o => o.FrameSize.Width).ToArray();
if (capabilities[0].FrameSize.Width < para)
{
device.VideoResolution = capabilities[0];
return;
}
int index = -1;
for (int i = 0; i < capabilities.Length; i )
{
if (capabilities[i].FrameSize.Width < para)
{
index = i;
break;
}
}
if (index == -1 || index == 0)
{
device.VideoResolution = capabilities[capabilities.Length - 1];
return;
}
if (capabilities[index - 1].FrameSize.Width - para <= para - capabilities[index].FrameSize.Width)
{
device.VideoResolution = capabilities[index - 1];
}
else
{
device.VideoResolution = capabilities[index];
}
}
private void loadCode()
{
if (this.VideoItemsSource == null)
{
return;
}
cboMainClass.DisplayMember = "Name";
cboMainClass.ValueMember = "Value";
cboMainClass.DataSource = VideoItemsSource;
cboMainClass.SelectedIndex = -1;
}
private static object Clone(object obj)
{
if (obj == null)
{
return null;
}
BinaryFormatter Formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));
MemoryStream stream = new MemoryStream();
Formatter.Serialize(stream, obj);
stream.Position = 0;
object clonedObj = Formatter.Deserialize(stream);
stream.Close();
return clonedObj;
}
#endregion
private void cboMainDevices_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (cboMainDevices.SelectedIndex == -1)
{
return;
}
int selectedIndex = cboMainDevices.SelectedIndex;
if (MainSelectedIndex == selectedIndex)
{
return;
}
if (SubMainSelectedIndex == selectedIndex)
{
cboMainDevices.SelectedIndex = MainSelectedIndex;
MessageBox.Show("所选设备已被使用,请选择其他设备!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
if (mainDevice != null)
{
mainDevice.SignalToStop();
mainDevice.WaitForStop();
picMainImage.Image = null;
}
var device = new VideoCaptureDevice(allDevice[selectedIndex].MonikerString);
device.NewFrame = new NewFrameEventHandler(device_NewFrame);
this.SetCapabilitiesByDatumWdith(MainDatumWdith, device);
device.Start();
MainSelectedIndex = cboMainDevices.SelectedIndex;
this.mainDevice = device;
}
catch { }
}
//mainDevice
void device_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
try
{
lock (syncLock)
{
Bitmap bmp = eventArgs.Frame.Clone() as Bitmap;
var tmp = picMainImage.Image;
this.picMainImage.Image = bmp;
if (tmp != null)
{
tmp.Dispose();
}
}
}
catch { }
}
private void cboSubDevices_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (cboSubDevices.SelectedIndex == -1)
{
return;
}
int selectedIndex = cboSubDevices.SelectedIndex;
if (SubMainSelectedIndex == selectedIndex)
{
return;
}
if (MainSelectedIndex == selectedIndex)
{
cboSubDevices.SelectedIndex = SubMainSelectedIndex;
MessageBox.Show("所选设备已被使用,请选择其他设备!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
if (subDevice != null)
{
subDevice.SignalToStop();
subDevice.WaitForStop();
picSubImage.Image = null;
}
var deviceSubVideo = new VideoCaptureDevice(allDevice[selectedIndex].MonikerString);
deviceSubVideo.NewFrame = new NewFrameEventHandler(deviceSubVideo_NewFrame);
this.SetCapabilitiesByDatumWdith(SubmainDatumWdith, deviceSubVideo);
deviceSubVideo.Start();
this.subDevice = deviceSubVideo;
this.SubMainSelectedIndex = selectedIndex;
}
catch { }
}
//subdevice
void deviceSubVideo_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
try
{
lock (syncLock)
{
Bitmap bmp = eventArgs.Frame.Clone() as Bitmap;
var tmp = picSubImage.Image;
this.picSubImage.Image = bmp;
if (tmp != null)
{
tmp.Dispose();
}
}
}
catch { }
}
private void btnGetImage_Click(object sender, EventArgs e)
{
try
{
if (picMainImage.Image == null && picSubImage.Image == null)
{
MessageBox.Show("摄像头初始化失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
lock (syncLock)
{
if (picMainImage.Image != null)
{
VideoMainImage = new Bitmap(picMainImage.Image);
}
if (picSubImage.Image != null)
{
VideoSubImage = new Bitmap(picSubImage.Image);
}
}
VideoMemo = "";
if (!string.IsNullOrWhiteSpace(cboMainClass.Text))
{
VideoMemo = string.Format("{0}|{1}", this.cboMainClass.Text, this.cboMainClass.SelectedValue);
}
VideoCenterCutSize = Size.Empty;
if (!cropSize.IsEmpty)
{
var cutDisplaySize = cropSize;//当前截图大小
var ppiImageRect = picMainImage.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic);
var rc = (Rectangle)ppiImageRect.GetValue(picMainImage, null);
var displaySize = rc.Size;
if (cutDisplaySize.Height > displaySize.Height)
{
cutDisplaySize.Height = displaySize.Height;
}
if (cutDisplaySize.Width > displaySize.Width)
{
cutDisplaySize.Width = displaySize.Width;
}
if (picMainImage.SizeMode == PictureBoxSizeMode.Zoom)
{
VideoCenterCutSize = new Size(cutDisplaySize.Width * picMainImage.Image.Width / displaySize.Width, cutDisplaySize.Height * picMainImage.Image.Height / displaySize.Height);
}
else
{
VideoCenterCutSize = cutDisplaySize;
}
}
FormVideoAforge.ReturnPictureBox = picMainImage;
MessageBox.Show("采集图像成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
if (this.EnableEvent)
{
this.OnCameraPictureGet(this.VideoMainImage, this.VideoSubImage, VideoMemo, VideoCenterCutSize);
}
else
{
this.DialogResult = DialogResult.OK;
}
this.Close();
}
catch (Exception ex)
{
MessageBox.Show("采集图像异常," ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
private void btnCloseForm_Click(object sender, EventArgs e)
{
FormVideoAforge.ReturnPictureBox = null;
this.DialogResult = DialogResult.Cancel;
}
private void FormVideoAforge_Load(object sender, EventArgs e)
{
loadCode();
FormVideoAforge.ReturnPictureBox = null;
}
private void FormVideoAforge_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
if (dotLine != null)
{
dotLine.Dispose();
dotLine = null;
}
if (sline != null)
{
sline.Dispose(); sline = null;
}
if (mainDevice != null)
{
mainDevice.SignalToStop();
mainDevice.WaitForStop();
}
if (subDevice != null)
{
subDevice.SignalToStop();
subDevice.WaitForStop();
}
}
catch { }
}
private void picMainImage_Paint(object sender, PaintEventArgs e)
{
cropSize = Size.Empty;
if (dotLine == null || picMainImage.Image == null)
{
return;
}
if (!this.checkBox1.Checked)
{
return;
}
var g = e.Graphics;
var rect = e.ClipRectangle;
var woffset = rect.Width * VideoCenterCutPercentage / 100f;
var hoffset = rect.Height * VideoCenterCutPercentage / 100f;
var hlineOffset = woffset / 5f;// 5分之1宽
var sxHeight = hoffset / 4f;//4分之一高
if (woffset > 20 && hoffset > 20)
{
#region 画框
var initX = rect.Width / 2f;
var initY = rect.Height / 2f;
g.TranslateTransform(initX, initY);//系统坐标原点移动
var p1 = new PointF(woffset / 2f, sxHeight);//正向的三个点
var p2 = new PointF(woffset / 2f, hoffset / 2f);
var p3 = new PointF(woffset / 2f - hlineOffset, hoffset / 2f);
var points = new PointF[] { p1, p2, p3 };
g.DrawLines(sline, points);
points = new PointF[] { new PointF(-p1.X, p1.Y), new PointF(-p2.X, p2.Y), new PointF(-p3.X, p3.Y) };
g.DrawLines(sline, points);
points = new PointF[] { new PointF(-p1.X, -p1.Y), new PointF(-p2.X, -p2.Y), new PointF(-p3.X, -p3.Y) };
g.DrawLines(sline, points);
points = new PointF[] { new PointF(p1.X, -p1.Y), new PointF(p2.X, -p2.Y), new PointF(p3.X, -p3.Y) };
g.DrawLines(sline, points);
var halfWidth = woffset / 2f;
var halfHeight = hoffset / 2f;
var halfLen = 8f;
g.DrawLine(sline, halfWidth, halfLen, halfWidth, -halfLen);//右左
g.DrawLine(dotLine, halfWidth, 0, rect.Width - initX, 0);
g.DrawLine(sline, -halfWidth, halfLen, -halfWidth, -halfLen);
g.DrawLine(dotLine, -halfWidth, 0, -initX, 0);
g.DrawLine(sline, halfLen, halfHeight, -halfLen, halfHeight);//下上
g.DrawLine(dotLine, 0, halfHeight, 0, rect.Height - initY);
g.DrawLine(sline, halfLen, -halfHeight, -halfLen, -halfHeight);
g.DrawLine(dotLine, 0, -halfHeight, 0, -initY);
#endregion
cropSize = new Size((int)woffset, (int)hoffset);
}
}
private void picMainImage_SizeChanged(object sender, EventArgs e)
{
if (picMainImage.Image == null)
{
picMainImage.SizeMode = PictureBoxSizeMode.Zoom;
}
else
{
if (picMainImage.Width > picMainImage.Image.Width && picMainImage.Height > picMainImage.Image.Height)
{
picMainImage.SizeMode = PictureBoxSizeMode.CenterImage;
}
else
{
picMainImage.SizeMode = PictureBoxSizeMode.Zoom;
}
}
}
}
}
标签: 摄像头
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论