C# camera camera and frame preview

I am a rookie in C#. I don’t understand many things, and there are not many online materials. I am afraid that I will forget or find the information. I will make a record here for future use, and it can also help other partners in need.

C# generally uses AForge to call the camera to take pictures. AForge is relatively perfect. After many people’s inspection and improvement, it can meet our basic needs in terms of function and stability. We also use this class library here, mainly using its camera initialization, preview and camera functions. If you are interested, you can dig out more of its functions and share them. The following is the rendering. , open the whole

First of all, you need to import AForge dependencies, you need to download and put them in the bin directory, you can download them by yourself, but the information on the Internet is not very complete, I packaged and uploaded the library, you can also download the library through this link

https://download.csdn.net/download/baoolong/85580501

Next, we need to write down the layout file first. In the layout file, VideoPlayer is used to display the information of the camera. The 3 Buttons are used to turn on the camera, turn off the camera and take pictures. The layout file is relatively simple, and you can change the layout according to your needs.

<Window x:Class="CameraCapture.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:wfi ="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
        xmlns:aforge ="clr-namespace:AForge.Controls;assembly=AForge.Controls"
        xmlns:local="clr-namespace:CameraCapture"
        mc:Ignorable="d"
        Title="MainWindow" Height="610" Width="640">
    <StackPanel>
        <wfi:WindowsFormsHost Grid.Row="0" Grid.Column="0">
            <aforge:VideoSourcePlayer x:Name="player" Height="90" Width="106"/>
        </wfi:WindowsFormsHost>
        <Button Name="btnCapture" Click="btnCapture_Click" Height="30">拍照</Button>
        <Button Name="btnOpenCamera" Click="btnOpenCamera_Click" Height="30">打开</Button>
        <Button Name="btnCloseCamera" Click="btnCloseCamera_Click" Height="30">关闭</Button>
    </StackPanel>
</Window>

After we finish writing the layout file, we also need to write a camera control class CameraHelper.cs

There are all methods for querying the number of cameras, setting the camera for VideoPlayer, taking pictures, and turning off the camera. You only need to call the corresponding method. I tried it myself and it can run stably. You can copy it with confidence.

class CameraHelper
    {
        private static FilterInfoCollection _cameraDevices;
        private  VideoCaptureDevice div = null;
        private  VideoSourcePlayer sourcePlayer = new VideoSourcePlayer();
        private  bool _isDisplay = false;
        //指示_isDisplay设置为true后,是否设置了其他的sourcePlayer,若未设置则_isDisplay重设为false
        private  bool isSet = false;

        /// <summary>
        /// 获取或设置摄像头设备,无设备为null
        /// </summary>
        public static FilterInfoCollection CameraDevices
        {
            get
            {
                return _cameraDevices;
            }
            set
            {
                _cameraDevices = value;
            }
        }
        /// <summary>
        /// 指示是否显示摄像头视频画面
        /// 默认false
        /// </summary>
        public  bool IsDisplay
        {
            get { return _isDisplay; }
            set { _isDisplay = value; }
        }
        /// <summary>
        /// 获取或设置VideoSourcePlayer控件,
        /// 只有当IsDisplay设置为true时,该属性才可以设置成功
        /// </summary>
        public  VideoSourcePlayer SourcePlayer
        {
            get { return sourcePlayer; }
            set
            {
                if (_isDisplay)
                {
                    sourcePlayer = value;
                    isSet = true;
                }
            }
        }
        /// <summary>
        /// 更新摄像头设备信息
        /// </summary>
        public static void UpdateCameraDevices()
        {
            _cameraDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
        }
        /// <summary>
        /// 设置使用的摄像头设备
        /// </summary>
        /// <param name="index">设备在CameraDevices中的索引</param>
        /// <returns><see cref="bool"/></returns>
        public  bool SetCameraDevice(int index)
        {
            if (!isSet) _isDisplay = false;
            //无设备,返回false
            if (_cameraDevices.Count <= 0 || index < 0) return false;
            if (index > _cameraDevices.Count - 1) return false;
            // 设定初始视频设备
            div = new VideoCaptureDevice(_cameraDevices[index].MonikerString);
            sourcePlayer.VideoSource = div;
            div.Start();
            sourcePlayer.Start();
            return true;
        }
        /// <summary>
        /// 截取一帧图像并保存
        /// </summary>
        /// <param name="filePath">图像保存路径</param>
        /// <param name="fileName">保存的图像文件名</param>
        /// <returns>如果保存成功,则返回完整路径,否则为 null</returns>
        public  string CaptureImage(string filePath, string fileName = null)
        {
            if (sourcePlayer.VideoSource == null) return null;
            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }
            try
            {
                Image bitmap = sourcePlayer.GetCurrentVideoFrame();
                if (fileName == null) fileName = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
                string fullPath = Path.Combine(filePath, fileName + "-cap.jpg");
                bitmap.Save(fullPath, ImageFormat.Jpeg);
                bitmap.Dispose();
                return fullPath;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message.ToString());
                return null;
            }
        }
        /// <summary>
        /// 关闭摄像头设备
        /// </summary>
        public  void CloseDevice()
        {
            if (div != null && div.IsRunning)
            {
                sourcePlayer.Stop();
                div.SignalToStop();
                div = null;
                _cameraDevices = null;
            }
        }
    }

Next, let's see how the main interface works. First, initialize the camera Helper class and set the displayed Player, and then update the camera. Three click events, one for opening the camera, one for closing the camera, and taking pictures, are all performed by calling the Helper class. I also set up a method videoSourcePlayer1_NewFrame called by the preview frame. Whenever there is a new frame, you can process the image. The method is very simple. If you need to develop multiple cameras, you only need to modify the layout and this class. I'm inside now with a single camera

    public partial class MainWindow : Window
    {
        private CameraHelper cameraHelper = new CameraHelper();
        public MainWindow()
        {
            InitializeComponent();
            cameraHelper.IsDisplay = true;
            cameraHelper.SourcePlayer = player;
            cameraHelper.UpdateCameraDevices();
        }

        private void btnCapture_Click(object sender, RoutedEventArgs e)
        {
            string fullPath = cameraHelper.CaptureImage(AppDomain.CurrentDomain.BaseDirectory + @"\Capture");

            BitmapImage bit = new BitmapImage();
            bit.BeginInit();
            bit.UriSource = new Uri(fullPath);
            bit.EndInit();

            String result  = parseBarCode(bit);
            Console.WriteLine("------"+ result);
        }

        private void btnOpenCamera_Click(object sender, RoutedEventArgs e)
        {
            if (cameraHelper.CameraDevices.Count > 0)
            {
                cameraHelper.SetCameraDevice(0);
                player.NewFrame += videoSourcePlayer1_NewFrame;
            }
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            cameraHelper.CloseDevice();
        }

        private Result[] parseBarCode(Bitmap bit)
        {
            BarcodeReader reader = new BarcodeReader();
            reader.Options.CharacterSet = "UTF-8";
            Result[] results = null;
            try
            {
                results = reader.DecodeMultiple(bit);
            }
            catch (Exception e)
            {
                String msg = e.Message;
                Console.WriteLine(msg);
            }
            return results;
        }

        private String parseBarCode(BitmapImage bit)
        {
            BarcodeReader reader = new BarcodeReader();
            reader.Options.CharacterSet = "UTF-8";
            Result result = null;
            try
            {
                result = reader.Decode(bit);
            }
            catch (Exception e)
            {
                String msg = e.Message;
                Console.WriteLine(msg);
            }
            return result == null ? "" : result.Text;
        }
       private  void videoSourcePlayer1_NewFrame(object sender, ref Bitmap image)
        {
            if (image == null) return;
            Bitmap bitmap = (Bitmap)image.Clone();
            new Thread(()=> {
                Result[] res = parseBarCode(bitmap);
                if (res == null) return;
                foreach (Result result in res)
                {
                    String resStr = result == null ? "" : result.Text;
                    Console.WriteLine("------" + resStr);
                }
            }).Start();
        }

        private void btnCloseCamera_Click(object sender, RoutedEventArgs e)
        {
            player.NewFrame -= videoSourcePlayer1_NewFrame;
            player.SignalToStop();
            player.WaitForStop();
        }
    }

Now you can happily take pictures with the camera. If you find this article useful, please like it

Guess you like

Origin blog.csdn.net/baoolong/article/details/125170520