AForge处理视频和拍照(暂时没有音频)
AForge处理视频和拍照
下载AForge相关的dll: AForge, AForge.Controls ,AForge.Video ,AForge.Video.DirectShow, AForge.Video.FFMPEG
包括如下:
using AForge;
using AForge.Controls;
using AForge.Video;
using AForge.Video.DirectShow;
using AForge.Video.FFMPEG;
相关dll类库下载地址:http://www.aforgenet.com/framework/downloads.htm
通过下载地址下载,显示如下,提示下载错误,食了很多次都是如此,因此我是用了nuget package下载,就是上图 右小角标记的 NuGet packages 通过指令安装(注:本人在NuGet 包管理器界面中输入搜索AForge.Video.FFMPEG,却无法搜索到对应的包,但在程序包管理器控制台中却可以安装)
在下载界面http://www.aforgenet.com/framework/downloads.html,右下角 点击NuGet packages,或者直接使用网址(AForge.Video.FFMPEG下载地址:https://www.nuget.org/packages?q=AForge.NET)也可以,打开以后下划找到ffmpeg,点击即可。
安装以后界面
注意:使用前,需要将Externals文件夹下的所有文件拷贝到项目输出路径下。如:bin\x86\Debug。
下面只要在项目中添加引用即可使用对应的dll进行音视频的开发了,
项目运行报错,如下:
是因为虽然将Externals文件夹下的所有文件拷贝到项目输出路径下,本人是吧需要的库放到Library中了,然后设置了覅知道输出目录:始终复制,并没有放到bin\Debug下
如下就可以了
添加视频播放控件,操作如下:
添加组件以后如下:
代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using AForge;
using AForge.Controls;
using AForge.Video;
using AForge.Video.DirectShow;
using AForge.Video.FFMPEG;namespace WindowsFormsTestVideo
{/// <summary>/// 测试视频和拍照/// </summary>public partial class Frmmain : Form{/// <summary>/// 构造函数/// </summary>public Frmmain(){InitializeComponent();}#region Fields and Propertities 字段和属性/// <summary>/// 摄像头实时显示控件对象,窗体上没有控件,只是用了该对象来截图/// </summary>private VideoSourcePlayer VideoSourcePlayerTest = null;/// <summary>/// 摄像头捕获对象/// </summary>private VideoCaptureDevice videoCaptureDevice = null;/// <summary>/// 摄像头图片写入文件对象,其实视频写入只不过是是写入的一张张图片而已/// </summary>private VideoFileWriter videoFileWriter = null;/// <summary>/// 摄像头设备集合/// </summary>FilterInfoCollection filterInfoCollection = null;/// <summary>/// 是否开始录像,开始录像标记/// </summary>bool isStartRecordVideo = false;/// <summary>/// 图像分辨率/// </summary>VideoCapabilities[] videoCapabilities = null;#endregion#region Methods 方法/// <summary>/// 记录日志/// </summary>/// <param name="message">日志信息</param>private static void Log(string message, MessageType messageType = MessageType.info){try{switch (messageType){default:case MessageType.info://WindowsFormsTestVideo.exe Information: 0 : 启动日志记录Trace.TraceInformation($"{DateTime.Now}:{message}");break;case MessageType.error://WindowsFormsTestVideo.exe Error: 启动日志记录Trace.TraceError($"{DateTime.Now}:{message}");break;case MessageType.fail://失败: 启动日志记录 Trace.Fail($"{DateTime.Now}:{message}");break;}}catch (Exception ex){Log(ex.Message, MessageType.error);}}#endregion#region Events 事件private void Frmmain_Load(object sender, EventArgs e){#region log日志System.Diagnostics.Trace.Listeners.Clear();System.Diagnostics.Trace.AutoFlush = true;System.Diagnostics.Trace.Listeners.Add(new System.Diagnostics.TextWriterTraceListener("log日志.log"));Log($"{DateTime.Now}:启动日志记录");#endregion//初始化//摄像头捕获器videoCaptureDevice = new VideoCaptureDevice();//视频录像器videoFileWriter = new VideoFileWriter();#region 添加摄像头,添加添加分辨率,添加视频格式try{//清空摄像头,视频格式,分辨率集合cbxSelectVideoCapture.Items.Clear();cbxSelectVideoSaveFormat.Items.Clear();cbxSelectResolution.Items.Clear();//分辨率集合videoCapabilities = null;//添加摄像头filterInfoCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);foreach (FilterInfo item in filterInfoCollection){cbxSelectVideoCapture.Items.Add(item.Name);}//默认选择第一个摄像头设备cbxSelectVideoCapture.SelectedIndex = 0;//添加视频格式foreach (var item in Enum.GetNames(typeof(VideoCodec))){cbxSelectVideoSaveFormat.Items.Add(item);}cbxSelectVideoSaveFormat.SelectedIndex = 0;}catch (Exception ex){Log(ex.Message, MessageType.error);}#endregion}/// <summary>/// 选择不同的摄像头/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void cbxSelectVideoCapture_SelectedIndexChanged(object sender, EventArgs e){try{//添加添加分辨率videoCaptureDevice = new VideoCaptureDevice(filterInfoCollection[cbxSelectVideoCapture.SelectedIndex].MonikerString);videoCaptureDevice.NewFrame += VideoCaptureDevice_NewFrame;//分辨率集合videoCapabilities = videoCaptureDevice.VideoCapabilities;//清空,不同的摄像头有不同的分辨率cbxSelectResolution.Items.Clear();foreach (var item in videoCapabilities){cbxSelectResolution.Items.Add(item.FrameSize);}//默认当前摄像头的第一个分辨率cbxSelectResolution.SelectedIndex = 0;//videoCaptureDevice.VideoResolution = videoCaptureDevice.VideoCapabilities[1];//videoCaptureDevice.Start();视频显示//vspPlayer.VideoSource = videoCaptureDevice;//vspPlayer.Start();}catch (Exception ex){Log(ex.Message, MessageType.error);}}/// <summary>/// 选择不同的分辨率/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void cbxSelectResolution_SelectedIndexChanged(object sender, EventArgs e){try{if (videoCaptureDevice.IsRunning || vspPlayer.IsRunning){videoCaptureDevice.SignalToStop();videoCaptureDevice.WaitForStop();vspPlayer.SignalToStop();vspPlayer.WaitForStop();VideoSourcePlayerTest.SignalToStop();VideoSourcePlayerTest.WaitForStop();}videoCaptureDevice.VideoResolution = videoCaptureDevice.VideoCapabilities[cbxSelectResolution.SelectedIndex];videoCaptureDevice.Start();//视频显示vspPlayer.VideoSource = videoCaptureDevice;vspPlayer.Start();VideoSourcePlayerTest = new AForge.Controls.VideoSourcePlayer();VideoSourcePlayerTest.VideoSource = videoCaptureDevice;VideoSourcePlayerTest.Start();}catch (Exception ex){Log(ex.Message, MessageType.error);}}/// <summary>/// 获取摄像头的当前帧,可以属实现实时动态的效果/// </summary>/// <param name="sender"></param>/// <param name="eventArgs"></param>private void VideoCaptureDevice_NewFrame(object sender, NewFrameEventArgs eventArgs){try{//eventArgs.Frame; 获取摄像头的每一帧图像//pbxPicture.Image = eventArgs.Frame;//直接复制报错//1、克隆//this.Invoke(new MethodInvoker(delegate ()//{// Bitmap image = (Bitmap)eventArgs.Frame.Clone();// pbxPicture.Image = image;// pbxPicture.Refresh();//}));//2、根据句柄创建Bitmap bitmap = eventArgs.Frame;//pbxPicture.Image = Bitmap.FromHbitmap(bitmap.GetHbitmap());if (isStartRecordVideo){//视频录像---向文件中写入摄像头的每一帧videoFileWriter.WriteVideoFrame(bitmap);}}catch (Exception ex){Log(ex.Message, MessageType.error);}#region 测试Bitmap和Marshal.Copy测试Bitmap和Marshal.Copy//Bitmap bitmap1 = new Bitmap("./123456.jpg");//Rectangle rectangle = new Rectangle(0, 0, bitmap1.Width, bitmap1.Height);锁定bitmap到系统内存//System.Drawing.Imaging.BitmapData bitmapData = bitmap1.LockBits(rectangle, System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap1.PixelFormat);BitmapData 指定 Bitmap 的特性,如大小、像素格式、像素数据在内存中的起始地址以及每个扫描行的长度(步幅)。//var pixel = bitmapData.PixelFormat; //Bitmap 的特性 宽度//var Width = bitmapData.Width;//Bitmap 的特性 宽度//var Height = bitmapData.Height; //Bitmap 的特性 高度//var firstStartAddress = bitmapData.Scan0;//像素数据在内存中的起始地址//var Stride = bitmapData.Stride;//像素数据在内存中的每个扫描行的长度(步幅)//var leength = Math.Abs(bitmapData.Stride) * bitmapData.Height;//byte[] bts = new byte[leength];将数据从非托管内存指针复制到托管 8 位无符号整数数组//System.Runtime.InteropServices.Marshal.Copy(firstStartAddress, bts, 0, bts.Length);使rgb图片变红色//for (int i = 2; i < bts.Length; i += 3)//{// bts[i] = 255;//}将数据从一维托管 8 位无符号整数数组复制到非托管内存指针。//System.Runtime.InteropServices.Marshal.Copy(bts, 0, firstStartAddress, bts.Length);//bitmap1.UnlockBits(bitmapData);//bitmap1.Save("./123456new.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);//bitmap1.Dispose();测试托管内存到非托管内存//string a = "123456";//IntPtr dd = System.Runtime.InteropServices.Marshal.AllocHGlobal(10);//char[] chars = a.ToCharArray();将数据从一维托管字符数组复制到非托管内存指针。//System.Runtime.InteropServices.Marshal.Copy(chars, 0, dd, chars.Length);修改//char[] chars1 = new char[chars.Length];将数据从非托管内存指针复制到托管字符数组。//System.Runtime.InteropServices.Marshal.Copy(dd, chars1, 0, chars.Length);//System.Runtime.InteropServices.Marshal.FreeHGlobal(dd); #endregion}/// <summary>/// 选择不同的视频格式/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void cbxSelectVideoSaveFormat_SelectedIndexChanged(object sender, EventArgs e){//try//{// //cbxSelectVideoSaveFormat.SelectedIndex = 0;//}//catch (Exception ex)//{// Log(ex.Message, MessageType.error);//}}/// <summary>/// 开始录像/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnStartVideo_Click(object sender, EventArgs e){try{if (cbxSelectVideoSaveFormat.SelectedIndex < 0 || !Enum.TryParse(cbxSelectVideoSaveFormat.SelectedItem.ToString(), out VideoCodec videoCodec)){MessageBox.Show("请选择视频格式", "提示:");cbxSelectVideoSaveFormat.Focus();return;}//创建具有指定名称和属性的视频文件。//文件名:要创建的视频文件名称。//宽度:视频文件的帧宽。//高:视频文件的帧高。//帧速率:视频文件的帧率。//编码:视频编解码器用于压缩VideoCapabilities capabilities = videoCapabilities[cbxSelectResolution.SelectedIndex];int height = capabilities.FrameSize.Height;// 720;//高:视频文件的帧高。int width = capabilities.FrameSize.Width;// 1280;//宽度:视频文件的帧宽。//int frameRate = capabilities.FrameRate;// 30;//帧速率:视频文件的帧率。int frameRate = capabilities.AverageFrameRate;// 30;//帧速率:视频文件的帧率。switch (cbxSelectVideoSaveFormat.SelectedIndex){case 0://MPEG-4 part 2.case 3:// MSMPEG4v2 = 3,MPEG-4 part 2 Microsoft variant version 2.case 4:// MSMPEG4v3 = 4,MPEG - 4 part 2 Microsoft variant version 3.case 7://MPEG2 = 7,MPEG-2 part 2.//创建具有指定名称和属性的视频文件,文件名:要创建的视频文件名称,宽度:视频文件的帧宽,高:视频文件的帧高,帧速率:视频文件的帧率,编码:视频编解码器用于压缩videoFileWriter.Open("video.mp4", width, height, frameRate, videoCodec);break;case 1:// WMV1 = 1 Windows Media Video 7case 2:// WMV2 = 2,Windows Media Video 8.videoFileWriter.Open("video.wmv", width, height, frameRate, videoCodec);break;case 5://H263P = 5, H.263+ / H.263-1998 / H.263 version 2.videoFileWriter.Open("video.mp4", width, height, frameRate, videoCodec);break;case 6://FLV1 = 6, Flash Video (FLV) / Sorenson Spark / Sorenson H.263.videoFileWriter.Open("video.flv", width, height, frameRate, videoCodec);break;case 8://Raw = 8,Raw (uncompressed) video.videoFileWriter.Open("video.mp4", width, height, frameRate, videoCodec);break;case -1://摘要: Default = -1 Default video codec, which FFmpeg library selects for the specified file format.default:videoFileWriter.Open("video.mkv", width, height, frameRate, videoCodec);break;}isStartRecordVideo = true;//开始录像标记lblRecord.ForeColor = Color.Red;lblRecord.Text = "录像中......";}catch (Exception ex){Log(ex.Message, MessageType.error);}}/// <summary>/// 停止录像/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnStopVideo_Click(object sender, EventArgs e){try{//关闭录像isStartRecordVideo = false;videoFileWriter.Close();lblRecord.ForeColor = DefaultForeColor;lblRecord.Text = "";}catch (Exception ex){Log(ex.Message, MessageType.error);}}/// <summary>/// 拍照/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnTakePhoto_Click(object sender, EventArgs e){try{if (vspPlayer.IsRunning && videoCaptureDevice.IsRunning){//拍照成功,照片保存路径var path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "takephoto.jpg");//使用实时显示摄像头控件//Bitmap image = vspPlayer.GetCurrentVideoFrame();//AForge.Controls.VideoSourcePlayerBitmap image = VideoSourcePlayerTest.GetCurrentVideoFrame();image.Save(path, System.Drawing.Imaging.ImageFormat.Jpeg);lblTakephotoSavePath.Text = $"拍照成功,照片保存路径:{path}";pbxPicture.SizeMode = PictureBoxSizeMode.Zoom;pbxPicture.Image = Bitmap.FromHbitmap(image.GetHbitmap());image.Dispose();}}catch (Exception ex){Log(ex.Message, MessageType.error);}}private void Frmmain_FormClosed(object sender, FormClosedEventArgs e){try{videoCaptureDevice.SignalToStop();videoCaptureDevice.WaitForStop();vspPlayer.SignalToStop();vspPlayer.WaitForStop();VideoSourcePlayerTest.SignalToStop();VideoSourcePlayerTest.WaitForStop();//videoCaptureDevice.Stop();//vspPlayer.Stop();//VideoSourcePlayerTest.Stop();}catch (Exception ex){Log(ex.Message, MessageType.error);}}#endregion}/// <summary>/// 信息的类型/// </summary>public enum MessageType{/// <summary>///正常记录信息/// </summary>info = 0,/// <summary>/// 错误信息/// </summary>error,/// <summary>/// 失败信息/// </summary>fail,}
}
运行效果如下:
AForge.2.2.5.zip库连接地址:https://download.csdn.net/download/LongtengGensSupreme/21057551
AForge处理视频和拍照(暂时没有音频)相关推荐
- ffplay分析 (音视频同步:主时钟为音频)
<ffplay的数据结构分析> <ffplay分析(从启动到读取线程的操作)> <ffplay分析(视频解码线程的操作)> <ffplay分析(音频解码线程的 ...
- Android音视频学习系列(五) — 掌握音频基础知识并使用AudioTrack、OpenSL ES渲染PCM数据
系列文章 Android音视频学习系列(一) - JNI从入门到精通 Android音视频学习系列(二) - 交叉编译动态库.静态库的入门 Android音视频学习系列(三) - Shell脚本入门 ...
- NDK开发——FFmpeg实现视频转YUV、视频转RGB显示、音频转PCM、音频播放、音视频同步
项目演示 前提准备 编译FFmpeg+CMake并能运行,详细可见我博客 下载libyuv库并编译成libyuv.so库,用于实现转换RGB格式功能 FFmpeg库简介 avcodec:编解码,包含 ...
- 使用sws_scale转换视频、使用swr_convert转换音频
使用Sws转换视频.使用swr_convert转换音频 环境 ➜ ~ ffmpeg -version ffmpeg version N-105035-g617452ce2c Copyright (c) ...
- 如何把视频的声音转换成音频?
如何把视频的声音转换成音频?小编是一名从事网络运营推广的上班族,随着视频营销的兴起,小编也开始制作视频然后发布到各大平台,想要做好视频营销,那么平时肯定需要收集各种素材,例如视频.音频.图片等素材,好 ...
- mp4视频文件如何转为MP3音频文件
mp4视频文件如何转为MP3音频文件 工具介绍 我们可以使用到一个网页版的转换器,这款转换器在未登录的情况下,最大支持100M的大文件上传并转换,如果通过注册,可以支持无限大小的支持,但是这个注册需要 ...
- Atititjs h5调用摄像头视频聊天 拍照功能 相机功能 录像attilax总结
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! Atit ...
- 视频怎么转成mp3音频
你是否会对视频中某段背景音乐所打动或是对视频中原音留下深刻印象.但是很多视频中的音频是无法找到源头,无法下载到音频.那么视频怎么转成mp3音频?这样的话就能直接获得视频里面的原音. 虽然现在大家使用的 ...
- 安卓音视频整理(一)——音频模块
这是关于安卓音视频的一个系列文章,大家可以从这里随意跳跃: 0.安卓音视频整理 1.安卓音视频整理(一)-- 音频模块 2.安卓音视频整理(二)-- 音视频编解码 3.安卓音视频整理(三)-- 图像模 ...
- 视频录像拍照加水印 在线文档编辑
主题:最近又学到的知识吧,虽然以前也有做过这次记录一下 一 .场景1:视频录像拍照加水印 知识点: 1.用标签<video>, navigator.mediaDevices.getUse ...
最新文章
- uwsgi: invalid option -- 'x'
- 泼点冷水,P2P借款限额是不是想的太美好?
- python四十三:静态属性,类方法
- 信息检索报告_读者信息素养状况问卷调查分析报告来啦
- 零件分组pascal程序
- java中使用switch case报错case expressions must be constant expressions
- tensorflow中协调器 tf.train.Coordinator 和入队线程启动器 tf.train.start_queue_runners
- Embedding技术在商业搜索与推荐场景的实践
- win7共享文件夹设置无密码
- 分布式锁实践(一)-Redis编程实现总结
- iOS本地化货币符号显示不正确(显示为XXX)的解决
- Linux第7章Gdk及Cairo基础,Linux第7章Gdk及Cairo基础.ppt
- img、link、html使用样式
- 猫耳FM日期窗口实现
- 机械自动化与计算机视觉关系,计算机视觉与机器视觉的区别?
- 20200120 数据结构和算法之 数组循环队列的实现
- ASCII码与字符对照表(附转换代码)
- Word 域嵌套太深弹窗,更新域卡顿,解决办法
- 【Pycharm教程】了解 PyCharm Python 控制台
- 阿里NLP架构与应用