diff --git a/Camera_connect/BaslerCamera.cs b/Camera_connect/BaslerCamera.cs new file mode 100644 index 0000000..41e1c7d --- /dev/null +++ b/Camera_connect/BaslerCamera.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using Basler.Pylon; +using System.Windows.Forms; + +namespace Camera_connect +{ + public class BaslerCamera + { + private readonly Main form; + private readonly object lockObject = new object(); + public int CameraNumber => CameraFinder.Enumerate().Count; + public event Action CameraImageEvent; + + private readonly List allCameras = new List(); + private readonly PixelDataConverter pxConvert = new PixelDataConverter(); + private bool isGrabbing; + + public BaslerCamera(Main form) + { + this.form = form; + } + + public void CameraInit() + { + var allCameraInfos = CameraFinder.Enumerate(); + allCameras.Clear(); + + foreach (var cameraInfo in allCameraInfos) + { + var camera = new Camera(cameraInfo); + camera.CameraOpened += Configuration.AcquireContinuous; + camera.StreamGrabber.GrabStarted += StreamGrabber_GrabStarted; + camera.StreamGrabber.ImageGrabbed += StreamGrabber_ImageGrabbed; + camera.Open(); + allCameras.Add(camera); + } + + isGrabbing = true; + } + + public void Close() + { + foreach (var camera in allCameras) + { + camera.StreamGrabber.Stop(); + camera.Close(); + camera.Dispose(); + } + + allCameras.Clear(); + isGrabbing = false; + MessageBox.Show("相機已斷開連接"); + } + + public void OneShot() + { + if (isGrabbing && allCameras.Count > 0) + { + var camera = allCameras[0]; + camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.SingleFrame); + camera.StreamGrabber.Start(1, GrabStrategy.OneByOne, GrabLoop.ProvidedByStreamGrabber); + } + else + { + MessageBox.Show("請確保相機已連接!"); + } + } + + public void KeepShot() + { + if (isGrabbing && allCameras.Count > 0) + { + var camera = allCameras[0]; + camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.Continuous); + camera.StreamGrabber.Start(GrabStrategy.OneByOne, GrabLoop.ProvidedByStreamGrabber); + } + else + { + MessageBox.Show("請確保相機已連接!"); + } + } + + public void Stop() + { + if (allCameras.Count > 0) + { + var camera = allCameras[0]; + camera.StreamGrabber.Stop(); // 停止抓取 + allCameras[0].StreamGrabber.Stop(); + CameraImageEvent = null; // 解除訂閱事件,防止影像更新 + isGrabbing = false; + } + else + { + MessageBox.Show("無可用的相機,請先連接 Basler 相機!", "停止失敗", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + } + + private void StreamGrabber_ImageGrabbed(object sender, ImageGrabbedEventArgs e) + { + lock (lockObject) + { + var grabResult = e.GrabResult; + if (grabResult.IsValid) + { + var bitmap = GrabResult2Bmp(grabResult); + CameraImageEvent?.Invoke(bitmap); + } + } + } + + private void StreamGrabber_GrabStarted(object sender, EventArgs e) + { + isGrabbing = true; + } + + private Bitmap GrabResult2Bmp(IGrabResult grabResult) + { + var bitmap = new Bitmap(grabResult.Width, grabResult.Height, PixelFormat.Format32bppArgb); + var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); + + pxConvert.OutputPixelFormat = PixelType.BGRA8packed; + pxConvert.Convert(bitmapData.Scan0, bitmapData.Stride * bitmap.Height, grabResult); + + bitmap.UnlockBits(bitmapData); + return bitmap; + } + } +} diff --git a/Camera_connect/Camera_connect.csproj b/Camera_connect/Camera_connect.csproj index 8ca0d1f..13c99ee 100644 --- a/Camera_connect/Camera_connect.csproj +++ b/Camera_connect/Camera_connect.csproj @@ -9,11 +9,20 @@ + + + + + + + + libs\Basler.Pylon.dll + - C:\Program Files\IDS\ids_peak\generic_sdk\samples\bin\x86_64\ids_peak_dotnet.dll + libs\ids_peak_dotnet.dll - C:\Program Files\IDS\ids_peak\generic_sdk\samples\bin\x86_64\ids_peak_ipl_dotnet.dll + libs\ids_peak_ipl_dotnet.dll diff --git a/Camera_connect/Main.cs b/Camera_connect/Main.cs index c5c7d94..abe7ef5 100644 --- a/Camera_connect/Main.cs +++ b/Camera_connect/Main.cs @@ -10,57 +10,118 @@ using System.IO; using System.Threading.Tasks; using System.Threading; using System.Reflection.Emit; +using Basler.Pylon; +using Emgu.CV; namespace Camera_connect { public partial class Main : Form { + private BaslerCamera Basler; public IDSCamera IDS_camera = new IDSCamera(); private bool isKeepShotting = false; // Ω󱱨s private Task keepShotTask; // Ω private CancellationTokenSource cts; // Ω + public PictureBox switchbox; //ഫ۾Ϲ public Main() { InitializeComponent(); } - //4103372214 + //IDSլ۾Ǹ 4103372214 private async void bt_connect_Click(object sender, EventArgs e) { - // ܳsuA - Label_status.Text = "IDSsu..."; + string? selectedCamera = comboBox1.SelectedItem?.ToString(); - // ŪΤJ - string IDS_serialnumber = camera_serialnumber.Text; - - // ˬdǦCO_ - if (string.IsNullOrWhiteSpace(IDS_serialnumber)) + if (string.IsNullOrWhiteSpace(selectedCamera)) { - Label_status.Text = "пJ۾Ǹ"; - MessageBox.Show("۾ǸରšI", "suT", MessageBoxButtons.OK, MessageBoxIcon.Warning); + Label_status.Text = "пܬ۾"; + MessageBox.Show("Хܬ۾I", "suT", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } - try + if (selectedCamera == "IDS") { - // Ұʳsu]BBzHOɭT^ - bool connectionResult = await Task.Run(() => IDS_camera.CameraInit(IDS_serialnumber)); + // ܳsuA + Label_status.Text = "IDSsu..."; - if (connectionResult) + // ŪΤJ + string IDS_serialnumber = camera_serialnumber.Text; + + // ˬdǦCO_ + if (string.IsNullOrWhiteSpace(IDS_serialnumber)) { - // ]mnɶ - IDS_camera.SetExposureTime(10000); - Label_status.Text = "IDSsu\"; + Label_status.Text = "пJ۾Ǹ"; + MessageBox.Show("۾ǸରšI", "suT", MessageBoxButtons.OK, MessageBoxIcon.Warning); + return; } - else + + try { - Label_status.Text = "IDSsu"; + // Ұʳsu]BBzHOɭT^ + bool connectionResult = await Task.Run(() => IDS_camera.CameraInit(IDS_serialnumber)); + + if (connectionResult) + { + // ]mnɶ + IDS_camera.SetExposureTime(10000); + Label_status.Text = "IDSsu\"; + } + else + { + Label_status.Text = "IDSsu"; + } + } + catch (Exception ex) + { + Label_status.Text = "su"; + MessageBox.Show($"suɵoͿ~G{ex.Message}", "suT", MessageBoxButtons.OK, MessageBoxIcon.Error); } } - catch (Exception ex) + else if (selectedCamera == "Basler") { - Label_status.Text = "su"; - MessageBox.Show($"suɵoͿ~G{ex.Message}", "suT", MessageBoxButtons.OK, MessageBoxIcon.Error); + try + { + // ܳsuA + Label_status.Text = "Baslersu..."; + + // l Basler ۾ + Basler = new BaslerCamera(this); + + bool connectionResult = await Task.Run(() => + { + if (Basler.CameraNumber > 0) + { + Basler.CameraImageEvent += Camera_CameraImageEvent; // q\ƥ + Basler.CameraInit(); + return true; + } + else + { + return false; + } + }); + + if (connectionResult) + { + Label_status.Text = "Baslersu\"; + } + else + { + Label_status.Text = "˴ Basler ۾"; + MessageBox.Show("˴ Basler ۾AнT{۾sO_`I", "suT", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + } + catch (Exception ex) + { + Label_status.Text = "Baslersu"; + MessageBox.Show($"su Basler ۾ɵoͿ~G{ex.Message}", "suT", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + else + { + Label_status.Text = "пܦĪ۾"; + MessageBox.Show("пܦĪ۾I", "suT", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } @@ -69,24 +130,88 @@ namespace Camera_connect { try { - if (IDS_camera != null) + string? selectedCamera = comboBox1.SelectedItem?.ToString(); + + if (selectedCamera == "IDS") { - Bitmap image = IDS_camera.GetPicture(); - if (image != null) + if (IDS_camera != null) { - pictureBox1.Image = image; - + Bitmap image = IDS_camera.GetPicture(); + if (image != null) + { + pictureBox1.Image = image; + } + } + } + else if (selectedCamera == "Basler") + { + if (Basler != null) + { + Basler.OneShot(); // 榸 + } + else + { + MessageBox.Show("Хsu Basler ۾I", "suT", MessageBoxButtons.OK, MessageBoxIcon.Warning); } - } } catch (Exception ex) { - + MessageBox.Show($"vɵoͿ~G{ex.Message}", "~", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void bt_KeepShot_Click(object sender, EventArgs e) + { + string? selectedCamera = comboBox1.SelectedItem?.ToString(); + + if (selectedCamera == "IDS") + { + // IDS ۾s޿ + StartKeepShot(() => IDS_camera.GetPicture()); + } + else if (selectedCamera == "Basler") + { + // Basler ۾s޿ + if (Basler != null) + { + if (Basler != null) + { + Basler.KeepShot(); // Ұʳs + } + else + { + MessageBox.Show("Хsu Basler ۾I", "suT", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + } + } + } + + private void bt_Stop_Click(object sender, EventArgs e) + { + if (!isKeepShotting) + { + return; + } + + string? selectedCamera = comboBox1.SelectedItem?.ToString(); + + if (selectedCamera == "IDS") + { + cts.Cancel(); + isKeepShotting = false; + } + else if (selectedCamera == "Basler") + { + if (Basler != null) + { + Basler.Stop(); + Basler.CameraImageEvent -= Camera_CameraImageEvent; + } + } + } + + private void StartKeepShot(Func captureMethod) { if (isKeepShotting) { @@ -103,36 +228,35 @@ namespace Camera_connect { try { - if (IDS_camera != null) + // եζǤJk + Bitmap image = captureMethod(); + if (image != null) { - Bitmap image = IDS_camera.GetPicture(); - if (image != null) + // s PictureBox Ϲ + pictureBox1.Invoke((MethodInvoker)delegate { - pictureBox1.Invoke((MethodInvoker)delegate - { - pictureBox1.Image = image; - }); - } + pictureBox1.Image = image; + }); } } catch (Exception ex) { - + // iHܰOxܿ~T } } }, token); } - private void bt_Stop_Click(object sender, EventArgs e) + private void Camera_CameraImageEvent(Bitmap bmp) { - if (!isKeepShotting) + // s@ PictureBox1 + pictureBox1.BeginInvoke(new MethodInvoker(delegate { - - return; - } - - cts.Cancel(); - isKeepShotting = false; + Bitmap old = pictureBox1.Image as Bitmap; + pictureBox1.Image = bmp; + if (old != null) + old.Dispose(); + })); } } diff --git a/Camera_connect/libs/Basler.Pylon.dll b/Camera_connect/libs/Basler.Pylon.dll new file mode 100644 index 0000000..8565877 Binary files /dev/null and b/Camera_connect/libs/Basler.Pylon.dll differ diff --git a/Camera_connect/libs/ids_peak_dotnet.dll b/Camera_connect/libs/ids_peak_dotnet.dll new file mode 100644 index 0000000..41df59b Binary files /dev/null and b/Camera_connect/libs/ids_peak_dotnet.dll differ diff --git a/Camera_connect/libs/ids_peak_ipl_dotnet.dll b/Camera_connect/libs/ids_peak_ipl_dotnet.dll new file mode 100644 index 0000000..24fc8f0 Binary files /dev/null and b/Camera_connect/libs/ids_peak_ipl_dotnet.dll differ