Newer
Older
TIASShot / TIASshot / Lucam.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Lumenera.USB;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using System.Drawing;
using System.Windows.Interop;

namespace TIASshot {

    /// <summary>
    /// Lumeneraカメラクラス
    /// </summary>
    internal class Lucam {

        public string DeviceName { get; private set; } = "Unknown";
        public string SerialNumber { get; private set; }

        private IntPtr _hCam = IntPtr.Zero;
        private PictureBox _picPreview, _picDisplay;
        private bool _isPreview = false;
        private dll.LucamRgbPreviewCallback _callbackHandler;
        private int _callbackId;
        private int _count = 0;
        private Bitmap[] _bmps = new Bitmap[2];
        private int _bmpIndex = 0;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="preview"></param>
        /// <param name="display"></param>
        public Lucam(PictureBox preview, PictureBox display) {
            _picPreview = preview;
            _picDisplay = display;
        }

        /// <summary>
        /// カメラ接続
        /// </summary>
        /// <returns></returns>
        public bool Connect() {
            var numCam = dll.LucamNumCameras();
            if ( numCam < 1 ) {
                return false;
            }

            var lumVersion = new dll.LucamVersion[numCam];
            lumVersion = api.EnumCameras();
            var id = 0;
            if (lumVersion[id].CameraId == 0x49f) DeviceName = "Lw110";
            SerialNumber = lumVersion[id].SerialNumber.ToString();

            _hCam = api.CameraOpen(1);
            if (_hCam == IntPtr.Zero) {
                return false;
            }

            _callbackHandler = new dll.LucamRgbPreviewCallback(PreviewCallback);
            _callbackId = dll.LucamAddRgbPreviewCallback(_hCam, _callbackHandler, IntPtr.Zero, dll.LucamPixelFormat.PF_24);
            if (_callbackId == -1) {
                MessageBox.Show("Cannot add rgb preview callback, fail to start preview");
                return false;
            }

            return true;
        }

        /// <summary>
        /// プレビュー開始・停止
        /// </summary>
        /// <returns></returns>
        public bool StartStopPreview() {
            if (_isPreview) {
                var ret = dll.LucamStreamVideoControl(_hCam, dll.LucamStreamMode.STOP_STREAMING, _picPreview.Handle.ToInt32());
                if (!ret) {
                    return false;
                }
                _isPreview = false;
                return true;
            } else {
                var ret = dll.LucamStreamVideoControl(_hCam, dll.LucamStreamMode.START_DISPLAY, _picPreview.Handle.ToInt32());
                if (!ret) {
                    return false;
                }
                _isPreview = true;
                return true;
            }
        }

        /// <summary>
        /// 画像表示(スレッドセーフ)
        /// </summary>
        void SafeDisplay() {
            if (_picDisplay.InvokeRequired) {
                _picDisplay.Invoke((MethodInvoker)delegate { SafeDisplay(); });
                return;
            }
            _picDisplay.Image = _bmps[_bmpIndex];
        }

        /// <summary>
        /// プレビューコールバック
        /// </summary>
        /// <param name="pContext"></param>
        /// <param name="pData">データポインタ</param>
        /// <param name="n">データサイズ</param>
        /// <param name="unused"></param>
        void PreviewCallback(IntPtr pContext, IntPtr pData, int n, uint unused) {
            //Debug.WriteLine(n);
            using (Mat img = Mat.FromPixelData(1024, 1280, MatType.CV_8UC3, pData)) {
                using (Mat imgt = img.T()) {
                    _bmps[_bmpIndex] = imgt.ToBitmap();
                }
            }
            SafeDisplay();
            //_picDisplay.Image = _bmps[_bmpIndex];
            _bmpIndex = (_bmpIndex + 1) % 2;
            if (_bmps[_bmpIndex] != null) _bmps[_bmpIndex].Dispose();
        }

        /// <summary>
        /// カメラ切断
        /// </summary>
        public void Disconnect() {
            if (_isPreview) {
                StartStopPreview();
            }
            Debug.WriteLine("カメラ切断");
            api.CameraClose(_hCam);
            _hCam = IntPtr.Zero;
        }
    }
}