BaslerCamera.cs 8.1 KB
using Basler.Pylon;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CodeLibrary
{

    public class BaslerCamera
    {
        public static BaslerCamera Instance= new BaslerCamera();
        /// <summary>
        /// 当前相机
        /// </summary>
        private Camera cameraCur = null;
        /// <summary>
        /// 所有相机列表
        /// </summary>
        private List<ICameraInfo> cameraAll;
        /// <summary>
        /// 所有相机的名称
        /// </summary>
        private List<string> cameraName;
        /// <summary>
        /// 获取连续图像
        /// </summary>
        public delegate void GrabImageEvent();
        /// <summary>
        /// 获取连续图像事件,需要跨线程操作
        /// </summary>
        public event GrabImageEvent GrabImage;

        private BaslerCamera()
        {
            Load();
        }

        /// <summary>
        /// 错误信息
        /// </summary>
        public string ErrInfo { set; get; }

        /// <summary>
        /// 相机总数
        /// </summary>
        public int Count
        {
            get { return cameraAll == null ? 0 : cameraAll.Count; }
        }

        /// <summary>
        /// 相机名称,ModelName,SerialNumber
        /// </summary>
        public string[] CameraName
        {
            get {
                if (cameraName == null)
                {
                    cameraName = new List<string>();
                }
                return cameraName.ToArray(); }
        }

        /// <summary>
        /// 当前相机是否打开
        /// </summary>
        public bool IsOpen
        {
            get
            {
                if (cameraCur == null)
                    return false;
                else
                    return cameraCur.IsOpen;
            }
        }

        /// <summary>
        /// 相机图像宽度
        /// </summary>
        public int Width { set; get; }

        /// <summary>
        /// 相机图像高度
        /// </summary>
        public int Height { set; get; }

        /// <summary>
        /// 相机32位缓存
        /// </summary>
        public byte[] Buffer { get; private set; }

        /// <summary>
        /// 相机32位图像
        /// </summary>
        public Bitmap Image { get; private set; }

        /// <summary>
        /// 加载相机
        /// </summary>
        public void Load()
        {
            try
            {
                cameraAll = CameraFinder.Enumerate();
                cameraName = new List<string>();
                foreach (ICameraInfo info in cameraAll)
                    cameraName.Add(info[CameraInfoKey.ModelName].ToString() + " (" + info[CameraInfoKey.SerialNumber].ToString() + ")");
            }
            catch (Exception ex)
            {
                HDLogUtil.error("Basler Load Error:" + ex.StackTrace);
            }
        }

        /// <summary>
        /// 打开指定相机
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public bool Open(string name)
        {
            int n = cameraName.FindIndex(s => s == name);
            if (n == -1)
                return false;
            else
                return Open(n);
        }

        /// <summary>
        /// 打开指定相机
        /// </summary>
        /// <param name="idx">索引</param>
        /// <returns></returns>
        public bool Open(int idx)
        {
            if (idx < 0 || idx >= cameraAll.Count) return false;
            if (cameraCur != null) Close();

            try
            {
                cameraCur = new Camera(cameraAll[idx]);
                //cameraCur.ConnectionLost += OnConnectionLost;
                //cameraCur.CameraOpened += OnCameraOpened;
                //cameraCur.CameraClosed += OnCameraClosed;
                //cameraCur.StreamGrabber.GrabStarted += OnGrabStarted;
                cameraCur.StreamGrabber.ImageGrabbed += OnImageGrabbed;
                //cameraCur.StreamGrabber.GrabStopped += OnGrabStopped;
                cameraCur.Open();
                Width = Convert.ToInt32(cameraCur.Parameters[PLCamera.Width].GetValue());
                Height = Convert.ToInt32(cameraCur.Parameters[PLCamera.Height].GetValue());
                cameraCur.Parameters[PLCamera.UserSetSelector].SetValue(PLCamera.UserSetSelector.UserSet1);  //加载用户设置1
                bool bln = cameraCur.Parameters[PLCamera.UserSetLoad].TryExecute();  //执行设置
                return true;
            }
            catch (Exception ex)
            {
                ErrInfo = ex.Message;
                return false;
            }
        }

        /// <summary>
        /// 关闭当前相机
        /// </summary>
        public void Close()
        {
            if (cameraCur != null)
            {
                cameraCur.Close();
                cameraCur.Dispose();
                cameraCur = null;
            }
        }

        /// <summary>
        /// 停止抓取数据
        /// </summary>
        public void Stop()
        {
            if (cameraCur != null)
                cameraCur.StreamGrabber.Stop();
        }

        /// <summary>
        /// 抓取一张图像
        /// </summary>
        public void GrabOne()
        {
            cameraCur.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.SingleFrame);

            //cameraCur.StreamGrabber.Start();
            //IGrabResult grabResult = cameraCur.StreamGrabber.RetrieveResult(5000, TimeoutHandling.ThrowException);
            IGrabResult grabResult = cameraCur.StreamGrabber.GrabOne(5000);

            if (!grabResult.IsValid) return;

            Image = new Bitmap(grabResult.Width, grabResult.Height, PixelFormat.Format32bppRgb);
            BitmapData bmpData = Image.LockBits(new Rectangle(0, 0, grabResult.Width, grabResult.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
            IntPtr ptrBmp = bmpData.Scan0;
            int picSize = bmpData.Stride * grabResult.Height;

            PixelDataConverter conv = new PixelDataConverter();
            conv.OutputPixelFormat = PixelType.BGRA8packed;
            conv.Convert(ptrBmp, picSize, grabResult);
            Buffer = new byte[picSize];
            System.Runtime.InteropServices.Marshal.Copy(ptrBmp, Buffer, 0, picSize);
            Image.UnlockBits(bmpData);

            //cameraCur.StreamGrabber.Stop();
        }

        /// <summary>
        /// 抓取连续图像,触发GrabImage事件
        /// </summary>
        public void GrabContinuous()
        {
            cameraCur.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.Continuous);
            cameraCur.StreamGrabber.Start(GrabStrategy.OneByOne, GrabLoop.ProvidedByStreamGrabber);
        }

        private void OnImageGrabbed(object sender, ImageGrabbedEventArgs e)
        {
            try
            {
                IGrabResult grabResult = e.GrabResult;
                if (!grabResult.IsValid) return;

                Image = new Bitmap(grabResult.Width, grabResult.Height, PixelFormat.Format32bppRgb);
                BitmapData bmpData = Image.LockBits(new Rectangle(0, 0, grabResult.Width, grabResult.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
                IntPtr ptrBmp = bmpData.Scan0;
                int picSize = bmpData.Stride * grabResult.Height;

                PixelDataConverter conv = new PixelDataConverter();
                conv.OutputPixelFormat = PixelType.BGRA8packed;
                conv.Convert(ptrBmp, picSize, grabResult);
                Buffer = new byte[picSize];
                System.Runtime.InteropServices.Marshal.Copy(ptrBmp, Buffer, 0, picSize);
                Image.UnlockBits(bmpData);

                GrabImage?.Invoke();
            }
            catch (Exception ex)
            {
                ErrInfo = ex.Message;
            }
            finally
            {
                e.DisposeGrabResultIfClone();
            }
        }


    }

}