Allen's 데이터 맛집

C#과 Basler Pylon을 사용한 라이브 뷰 애플리케니션의 메인 윈도우 MainForm 본문

Programming/Pylon .Net API

C#과 Basler Pylon을 사용한 라이브 뷰 애플리케니션의 메인 윈도우 MainForm

Allen93 2024. 8. 28. 17:02
C#과 Basler Pylon .NET API를 사용하여 라이브 뷰 애플리케이션의 메인 윈도우 역할을 하는 MainForm 클래스에 대해 설명하겠습니다. 이 클래스는 카메라와의 연결을 관리하고, 이미지를 캡처하며, 다양한 카메라 설정을 조정할 수 있는 기능을 제공합니다.

 

 

클래스 개요

 

MainForm 클래스는 Basler Pylon 카메라의 다양한 기능을 제어할 수 있는 메인 윈도우를 구현합니다. 이 클래스는 카메라 연결, 이미지 캡처, 설정 조정, 그리고 사용자 인터페이스 업데이트 등의 주요 기능을 담당합니다.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using PylonLiveView;
using Basler.Pylon;

namespace PylonLiveView
{
    // The main window.
    public partial class MainForm : Form
    {
        private Camera camera = null;
        private PixelDataConverter converter = new PixelDataConverter();
        private Stopwatch stopWatch = new Stopwatch();

        // Set up the controls and events to be used and update the device list.
        public MainForm()
        {
            InitializeComponent();

            // Set the default names for the controls.
            testImageControl.DefaultName = "Test Image Selector";
            pixelFormatControl.DefaultName = "Pixel Format";
            widthSliderControl.DefaultName = "Width";
            heightSliderControl.DefaultName = "Height";
            gainSliderControl.DefaultName = "Gain";
            exposureTimeSliderControl.DefaultName = "Exposure Time";

            // Update the list of available camera devices in the upper left area.
            UpdateDeviceList();

            // Disable all buttons.
            EnableButtons(false, false);
        }

        // Occurs when the single frame acquisition button is clicked.
        private void toolStripButtonOneShot_Click(object sender, EventArgs e)
        {
            OneShot(); // Start the grabbing of one image.
        }

        // Occurs when the continuous frame acquisition button is clicked.
        private void toolStripButtonContinuousShot_Click(object sender, EventArgs e)
        {
            ContinuousShot(); // Start the grabbing of images until grabbing is stopped.
        }

        // Occurs when the stop frame acquisition button is clicked.
        private void toolStripButtonStop_Click(object sender, EventArgs e)
        {
            Stop(); // Stop the grabbing of images.
        }

        // Occurs when a device with an opened connection is removed.
        private void OnConnectionLost(Object sender, EventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new EventHandler<EventArgs>(OnConnectionLost), sender, e);
                return;
            }

            DestroyCamera();
            UpdateDeviceList();
        }

        // Occurs when the connection to a camera device is opened.
        private void OnCameraOpened(Object sender, EventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new EventHandler<EventArgs>(OnCameraOpened), sender, e);
                return;
            }

            EnableButtons(true, false);
        }

        // Occurs when the connection to a camera device is closed.
        private void OnCameraClosed(Object sender, EventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new EventHandler<EventArgs>(OnCameraClosed), sender, e);
                return;
            }

            EnableButtons(false, false);
        }

        // Occurs when a camera starts grabbing.
        private void OnGrabStarted(Object sender, EventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new EventHandler<EventArgs>(OnGrabStarted), sender, e);
                return;
            }

            stopWatch.Reset();
            updateDeviceListTimer.Stop();
            EnableButtons(false, true);
        }

        // Occurs when an image has been acquired and is ready to be processed.
        private void OnImageGrabbed(Object sender, ImageGrabbedEventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new EventHandler<ImageGrabbedEventArgs>(OnImageGrabbed), sender, e.Clone());
                return;
            }

            try
            {
                IGrabResult grabResult = e.GrabResult;

                if (grabResult.IsValid)
                {
                    if (!stopWatch.IsRunning || stopWatch.ElapsedMilliseconds > 33)
                    {
                        stopWatch.Restart();

                        Bitmap bitmap = new Bitmap(grabResult.Width, grabResult.Height, PixelFormat.Format32bppRgb);
                        BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
                        IntPtr ptrBmp = bmpData.Scan0;
                        converter.OutputPixelFormat = PixelType.BGRA8packed;
                        converter.Convert(ptrBmp, bmpData.Stride * bitmap.Height, grabResult);
                        bitmap.UnlockBits(bmpData);

                        Bitmap bitmapOld = pictureBox.Image as Bitmap;
                        pictureBox.Image = bitmap;
                        if (bitmapOld != null)
                        {
                            bitmapOld.Dispose();
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                ShowException(exception);
            }
            finally
            {
                e.DisposeGrabResultIfClone();
            }
        }

        // Occurs when a camera has stopped grabbing.
        private void OnGrabStopped(Object sender, GrabStopEventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new EventHandler<GrabStopEventArgs>(OnGrabStopped), sender, e);
                return;
            }

            stopWatch.Reset();
            updateDeviceListTimer.Start();
            EnableButtons(true, false);

            if(e.Reason != GrabStopReason.UserRequest)
            {
                MessageBox.Show("A grab error occured:\n" + e.ErrorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // Helps to set the states of all buttons.
        private void EnableButtons(bool canGrab, bool canStop)
        {
            toolStripButtonContinuousShot.Enabled = canGrab;
            toolStripButtonOneShot.Enabled = canGrab;
            toolStripButtonStop.Enabled = canStop;
        }

        // Stops the grabbing of images and handles exceptions.
        private void Stop()
        {
            try
            {
                camera.StreamGrabber.Stop();
            }
            catch (Exception exception)
            {
                ShowException(exception);
            }
        }

        // Closes the camera object and handles exceptions.
        private void DestroyCamera()
        {
            try
            {
                if (camera != null)
                {
                    testImageControl.Parameter = null;
                    pixelFormatControl.Parameter = null;
                    widthSliderControl.Parameter = null;
                    heightSliderControl.Parameter = null;
                    gainSliderControl.Parameter = null;
                    exposureTimeSliderControl.Parameter = null;
                }
            }
            catch (Exception exception)
            {
                ShowException(exception);
            }

            try
            {
                if (camera != null)
                {
                    camera.Close();
                    camera.Dispose();
                    camera = null;
                }
            }
            catch (Exception exception)
            {
                ShowException(exception);
            }
        }

        // Starts the grabbing of a single image and handles exceptions.
        private void OneShot()
        {
            try
            {
                camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.SingleFrame);
                camera.StreamGrabber.Start(1, GrabStrategy.OneByOne, GrabLoop.ProvidedByStreamGrabber);
            }
            catch (Exception exception)
            {
                ShowException(exception);
            }
        }

        // Starts the continuous grabbing of images and handles exceptions.
        private void ContinuousShot()
        {
            try
            {
                camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.Continuous);
                camera.StreamGrabber.Start(GrabStrategy.OneByOne, GrabLoop.ProvidedByStreamGrabber);
            }
            catch (Exception exception)
            {
                ShowException(exception);
            }
        }

        // Updates the list of available camera devices.
        private void UpdateDeviceList()
        {
            try
            {
                List<ICameraInfo> allCameras = CameraFinder.Enumerate();
                ListView.ListViewItemCollection items = deviceListView.Items;

                foreach (ICameraInfo cameraInfo in allCameras)
                {
                    bool newitem = true;
                    foreach (ListViewItem item in items)
                    {
                        ICameraInfo tag = item.Tag as ICameraInfo;

                        if ( tag[CameraInfoKey.FullName] == cameraInfo[CameraInfoKey.FullName])
                        {
                            tag = cameraInfo;
                            newitem = false;
                            break;
                        }
                    }

                    if (newitem)
                    {
                        ListViewItem item = new ListViewItem(cameraInfo[CameraInfoKey.FriendlyName]);

                        string toolTipText = "";
                        foreach( KeyValuePair<string, string> kvp in cameraInfo)
                        {
                            toolTipText += kvp.Key + ": " + kvp.Value + "\n";
                        }
                        item.ToolTipText = toolTipText;
                        item.Tag = cameraInfo;
                        deviceListView.Items.Add(item);
                    }
                }

                foreach (ListViewItem item in items)
                {
                    bool exists = false;

                    foreach (ICameraInfo cameraInfo in allCameras)
                    {
                        if (((ICameraInfo)item.Tag)[CameraInfoKey.FullName] == cameraInfo[CameraInfoKey.FullName])
                        {
                            exists = true;
                            break;
                        }
                    }

                    if (!exists)
                    {
                        deviceListView.Items.Remove(item);
                    }
                }
            }
            catch (Exception exception)
            {
                ShowException(exception);
            }
        }

        // Shows exceptions in a message box.
        private void ShowException(Exception exception)
        {
            MessageBox.Show("Exception caught:\n" + exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        // Closes the camera object when the window is closed.
        private void MainForm_FormClosing(object sender, FormClosingEventArgs ev)
        {
            DestroyCamera();
        }

        // Occurs when a new camera has been selected in the list. Destroys the object of the currently opened camera device and
        // creates a new object for the selected camera device. After that, the connection to the selected camera device is opened.
        private void deviceListView_SelectedIndexChanged(object sender, EventArgs ev)
        {
            if (camera != null)
            {
                DestroyCamera();
            }

            if (deviceListView.SelectedItems.Count > 0)
            {
                ListViewItem item = deviceListView.SelectedItems[0];
                ICameraInfo selectedCamera = item.Tag as ICameraInfo;
                try
                {
                    camera = new Camera (selectedCamera);

                    camera.CameraOpened += Configuration.AcquireContinuous;

                    camera.ConnectionLost += OnConnectionLost;
                    camera.CameraOpened += OnCameraOpened;
                    camera.CameraClosed += OnCameraClosed;
                    camera.StreamGrabber.GrabStarted += OnGrabStarted;
                    camera.StreamGrabber.ImageGrabbed += OnImageGrabbed;
                    camera.StreamGrabber.GrabStopped += OnGrabStopped;

                    camera.Open();

                    testImageControl.Parameter = camera.Parameters[PLCamera.TestImageSelector];
                    pixelFormatControl.Parameter = camera.Parameters[PLCamera.PixelFormat];
                    widthSliderControl.Parameter = camera.Parameters[PLCamera.Width];
                    heightSliderControl.Parameter = camera.Parameters[PLCamera.Height];
                    if (camera.Parameters.Contains(PLCamera.GainAbs))
                    {
                        gainSliderControl.Parameter = camera.Parameters[PLCamera.GainAbs];
                    }
                    else
                    {
                        gainSliderControl.Parameter = camera.Parameters[PLCamera.Gain];
                    }
                    if (camera.Parameters.Contains(PLCamera.ExposureTimeAbs))
                    {
                        exposureTimeSliderControl.Parameter = camera.Parameters[PLCamera.ExposureTimeAbs];
                    }
                    else
                    {
                        exposureTimeSliderControl.Parameter = camera.Parameters[PLCamera.ExposureTime];
                    }
                }
                catch (Exception exception)
                {
                    ShowException(exception);
                }
            }
        }

        // If the F5 key has been pressed, update the list of devices.
        private void deviceListView_KeyDown(object sender, KeyEventArgs ev)
        {
            if (ev.KeyCode == Keys.F5)
            {
                ev.Handled = true;
                UpdateDeviceList();
            }
        }

        // Timer callback used to periodically check whether displayed camera devices are still attached to the PC.
        private void updateDeviceListTimer_Tick(object sender, EventArgs e)
        {
            UpdateDeviceList();
        }
    }
}

 

 

2. 주요 구성 요소 및 기능

 

a. 초기화 및 설정

public MainForm()
{
    InitializeComponent();

    // Set the default names for the controls.
    testImageControl.DefaultName = "Test Image Selector";
    pixelFormatControl.DefaultName = "Pixel Format";
    widthSliderControl.DefaultName = "Width";
    heightSliderControl.DefaultName = "Height";
    gainSliderControl.DefaultName = "Gain";
    exposureTimeSliderControl.DefaultName = "Exposure Time";

    // Update the list of available camera devices in the upper left area.
    UpdateDeviceList();

    // Disable all buttons.
    EnableButtons(false, false);
}
  • 초기화: 생성자에서 컨트롤을 초기화하고 기본 이름을 설정합니다.
  • 디바이스 리스트 업데이트: 사용 가능한 카메라 디바이스 목록을 갱신합니다.
  • 버튼 비활성화: 모든 버튼을 비활성화합니다.

 

b. 이미지 캡처 버튼 처리

private void toolStripButtonOneShot_Click(object sender, EventArgs e)
{
    OneShot(); // Start the grabbing of one image.
}

private void toolStripButtonContinuousShot_Click(object sender, EventArgs e)
{
    ContinuousShot(); // Start the grabbing of images until grabbing is stopped.
}

private void toolStripButtonStop_Click(object sender, EventArgs e)
{
    Stop(); // Stop the grabbing of images.
}
  • 단일 이미지 캡처: 한 장의 이미지를 캡처합니다.
  • 연속 이미지 캡처: 이미지를 연속으로 캡처합니다.
  • 이미지 캡처 중지: 이미지 캡처를 중지합니다.

 

c. 연결 상태 처리

private void OnConnectionLost(Object sender, EventArgs e)
{
    if (InvokeRequired)
    {
        BeginInvoke(new EventHandler<EventArgs>(OnConnectionLost), sender, e);
        return;
    }

    DestroyCamera();
    UpdateDeviceList();
}

private void OnCameraOpened(Object sender, EventArgs e)
{
    if (InvokeRequired)
    {
        BeginInvoke(new EventHandler<EventArgs>(OnCameraOpened), sender, e);
        return;
    }

    EnableButtons(true, false);
}

private void OnCameraClosed(Object sender, EventArgs e)
{
    if (InvokeRequired)
    {
        BeginInvoke(new EventHandler<EventArgs>(OnCameraClosed), sender, e);
        return;
    }

    EnableButtons(false, false);
}
  • 연결 끊김 처리: 카메라 연결이 끊어졌을 때 카메라를 파괴하고 디바이스 리스트를 업데이트합니다.
  • 카메라 열림 처리: 카메라 연결이 열렸을 때 버튼을 활성화합니다.
  • 카메라 닫힘 처리: 카메라 연결이 닫혔을 때 버튼을 비활성화합니다.

 

d. 이미지 캡처 처리

private void OnGrabStarted(Object sender, EventArgs e)
{
    if (InvokeRequired)
    {
        BeginInvoke(new EventHandler<EventArgs>(OnGrabStarted), sender, e);
        return;
    }

    stopWatch.Reset();
    updateDeviceListTimer.Stop();
    EnableButtons(false, true);
}

private void OnImageGrabbed(Object sender, ImageGrabbedEventArgs e)
{
    if (InvokeRequired)
    {
        BeginInvoke(new EventHandler<ImageGrabbedEventArgs>(OnImageGrabbed), sender, e.Clone());
        return;
    }

    try
    {
        IGrabResult grabResult = e.GrabResult;

        if (grabResult.IsValid)
        {
            if (!stopWatch.IsRunning || stopWatch.ElapsedMilliseconds > 33)
            {
                stopWatch.Restart();

                Bitmap bitmap = new Bitmap(grabResult.Width, grabResult.Height, PixelFormat.Format32bppRgb);
                BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
                IntPtr ptrBmp = bmpData.Scan0;
                converter.OutputPixelFormat = PixelType.BGRA8packed;
                converter.Convert(ptrBmp, bmpData.Stride * bitmap.Height, grabResult);
                bitmap.UnlockBits(bmpData);

                Bitmap bitmapOld = pictureBox.Image as Bitmap;
                pictureBox.Image = bitmap;
                if (bitmapOld != null)
                {
                    bitmapOld.Dispose();
                }
            }
        }
    }
    catch (Exception exception)
    {
        ShowException(exception);
    }
    finally
    {
        e.DisposeGrabResultIfClone();
    }
}

private void OnGrabStopped(Object sender, GrabStopEventArgs e)
{
    if (InvokeRequired)
    {
        BeginInvoke(new EventHandler<GrabStopEventArgs>(OnGrabStopped), sender, e);
        return;
    }

    stopWatch.Reset();
    updateDeviceListTimer.Start();
    EnableButtons(true, false);

    if(e.Reason != GrabStopReason.UserRequest)
    {
        MessageBox.Show("A grab error occured:\n" + e.ErrorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}
  • 이미지 캡처 시작: 이미지 캡처가 시작될 때 타이머를 리셋하고 디바이스 리스트 업데이트를 중지합니다.
  • 이미지 캡처 완료: 이미지가 캡처되었을 때 이미지를 처리하고, 최신 이미지만 표시합니다.
  • 이미지 캡처 중지: 이미지 캡처가 중지될 때 타이머를 리셋하고 디바이스 리스트 업데이트를 다시 시작합니다.

 

e. 버튼 활성화/비활성화

private void EnableButtons(bool canGrab, bool canStop)
{
    toolStripButtonContinuousShot.Enabled = canGrab;
    toolStripButtonOneShot.Enabled = canGrab;
    toolStripButtonStop.Enabled = canStop;
}
  • 버튼 활성화/비활성화: 이미지 캡처 상태에 따라 버튼을 활성화하거나 비활성화합니다.

 

f. 카메라 파괴 및 예외 처리

private void DestroyCamera()
{
    try
    {
        if (camera != null)
        {
            testImageControl.Parameter = null;
            pixelFormatControl.Parameter = null;
            widthSliderControl.Parameter = null;
            heightSliderControl.Parameter = null;
            gainSliderControl.Parameter = null;
            exposureTimeSliderControl.Parameter = null;
        }
    }
    catch (Exception exception)
    {
        ShowException(exception);
    }

    try
    {
        if (camera != null)
        {
            camera.Close();
            camera.Dispose();
            camera = null;
        }
    }
    catch (Exception exception)
    {
        ShowException(exception);
    }
}
  • 카메라 파괴: 카메라 객체를 안전하게 파괴하고 예외를 처리합니다.

 

g. 단일 이미지 및 연속 이미지 캡처

private void OneShot()
{
    try
    {
        camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.SingleFrame);
        camera.StreamGrabber.Start(1, GrabStrategy.OneByOne, GrabLoop.ProvidedByStreamGrabber);
    }
    catch (Exception exception)
    {
        ShowException(exception);
    }
}

private void ContinuousShot()
{
    try
    {
        camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.Continuous);
        camera.StreamGrabber.Start(GrabStrategy.OneByOne, GrabLoop.ProvidedByStreamGrabber);
    }
    catch (Exception exception)
    {
        ShowException(exception);
    }
}
  • 단일 이미지 캡처: 한 장의 이미지를 캡처합니다.
  • 연속 이미지 캡처: 이미지를 연속으로 캡처합니다.

 

h. 디바이스 리스트 업데이트

private void UpdateDeviceList()
{
    try
    {
        List<ICameraInfo> allCameras = CameraFinder.Enumerate();
        ListView.ListViewItemCollection items = deviceListView.Items;

        foreach (ICameraInfo cameraInfo in allCameras)
        {
            bool newitem = true;
            foreach (ListViewItem item in items)
            {
                ICameraInfo tag = item.Tag as ICameraInfo;

                if ( tag[CameraInfoKey.FullName] == cameraInfo[CameraInfoKey.FullName])
                {
                    tag = cameraInfo;
                    newitem = false;
                    break;
                }
            }

            if (newitem)
            {
                ListViewItem item = new ListViewItem(cameraInfo[CameraInfoKey.FriendlyName]);

                string toolTipText = "";
                foreach( KeyValuePair<string, string> kvp in cameraInfo)
                {
                    toolTipText += kvp.Key + ": " + kvp.Value + "\n";
                }
                item.ToolTipText = toolTipText;
                item.Tag = cameraInfo;
                deviceListView.Items.Add(item);
            }
        }

        foreach (ListViewItem item in items)
        {
            bool exists = false;

            foreach (ICameraInfo cameraInfo in allCameras)
            {
                if (((ICameraInfo)item.Tag)[CameraInfoKey.FullName] == cameraInfo[CameraInfoKey.FullName])
                {
                    exists = true;
                    break;
                }
            }

            if (!exists)
            {
                deviceListView.Items.Remove(item);
            }
        }
    }
    catch (Exception exception)
    {
        ShowException(exception);
    }
}
  • 디바이스 리스트 업데이트: 사용 가능한 카메라 디바이스 목록을 갱신하고, 제거된 디바이스는 리스트에서 삭제합니다.

 

i. 예외 처리

private void ShowException(Exception exception)
{
    MessageBox.Show("Exception caught:\n" + exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
  • 예외 처리: 예외가 발생했을 때 메시지 박스를 통해 사용자에게 알립니다.

 

j. 폼 닫기 및 디바이스 선택 처리

private void MainForm_FormClosing(object sender, FormClosingEventArgs ev)
{
    DestroyCamera();
}

private void deviceListView_SelectedIndexChanged(object sender, EventArgs ev)
{
    if (camera != null)
    {
        DestroyCamera();
    }

    if (deviceListView.SelectedItems.Count > 0)
    {
        ListViewItem item = deviceListView.SelectedItems[0];
        ICameraInfo selectedCamera = item.Tag as ICameraInfo;
        try
        {
            camera = new Camera (selectedCamera);

            camera.CameraOpened += Configuration.AcquireContinuous;

            camera.ConnectionLost += OnConnectionLost;
            camera.CameraOpened += OnCameraOpened;
            camera.CameraClosed += OnCameraClosed;
            camera.StreamGrabber.GrabStarted += OnGrabStarted;
            camera.StreamGrabber.ImageGrabbed += OnImageGrabbed;
            camera.StreamGrabber.GrabStopped += OnGrabStopped;

            camera.Open();

            testImageControl.Parameter = camera.Parameters[PLCamera.TestImageSelector];
            pixelFormatControl.Parameter = camera.Parameters[PLCamera.PixelFormat];
            widthSliderControl.Parameter = camera.Parameters[PLCamera.Width];
            heightSliderControl.Parameter = camera.Parameters[PLCamera.Height];
            if (camera.Parameters.Contains(PLCamera.GainAbs))
            {
                gainSliderControl.Parameter = camera.Parameters[PLCamera.GainAbs];
            }
            else
            {
                gainSliderControl.Parameter = camera.Parameters[PLCamera.Gain];
            }
            if (camera.Parameters.Contains(PLCamera.ExposureTimeAbs))
            {
                exposureTimeSliderControl.Parameter = camera.Parameters[PLCamera.ExposureTimeAbs];
            }
            else
            {
                exposureTimeSliderControl.Parameter = camera.Parameters[PLCamera.ExposureTime];
            }
        }
        catch (Exception exception)
        {
            ShowException(exception);
        }
    }
}
  • 폼 닫기: 폼이 닫힐 때 카메라 객체를 파괴합니다.
  • 디바이스 선택: 새로운 카메라 디바이스가 선택되었을 때 현재 카메라 객체를 파괴하고 선택된 카메라와 연결을 엽니다.

 

k. 키 입력 및 타이머 콜백 처리

private void deviceListView_KeyDown(object sender, KeyEventArgs ev)
{
    if (ev.KeyCode == Keys.F5)
    {
        ev.Handled = true;
        UpdateDeviceList();
    }
}

private void updateDeviceListTimer_Tick(object sender, EventArgs e)
{
    UpdateDeviceList();
}
  • 키 입력 처리: F5 키가 눌렸을 때 디바이스 리스트를 업데이트합니다.
  • 타이머 콜백: 일정 시간마다 디바이스 리스트를 업데이트합니다.

 

 

MainForm 클래스는 Basler Pylon 카메라의 다양한 기능을 제어할 수 있는 메인 윈도우를 구현합니다. 이 클래스는 카메라 연결, 이미지 캡처, 설정 조정, 그리고 사용자 인터페이스 업데이트 등의 주요 기능을 담당합니다. 


해시태그

#CSharp #BaslerPylon #윈도우폼 #비전코딩 #프로그래밍 #오픈소스 #GitHub #코딩팁 #개발자

728x90