1 创建相机类 DhCamera
相机类
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using GxIAPINET;
namespace multiCam
{
internal class DhCamera
{
IGXStream cam_stream;//相机流对象
IGXFeatureControl cam_remote_control;//远端属性控制器
IGXFeatureControl cam_control; //本地属性控制器
IGXFeatureControl cam_stream_control;//流属性控制器
IGXDevice cam;
string m_sn;//相机SN
public string m_id;//公共的ID变量,在ComboBox中添加相机设备名称
public static int cam_num;//全局静态变量,主程序中也要实用
static bool colorFlag = false;// 回调函数的 静态变量,是否彩色相机
public PictureBox pictureBox;
//相机初始化//第一步,对相机资源进行初始化
public static void InitCam()
{
IGXFactory.GetInstance().Init();
}
public static void UinitCam()
{
//最后通过反初始化释放所有资源;
IGXFactory.GetInstance().Uninit();
}
//相机信息
public void InfoCam(int index)
{
//先定义一个设备列表,用来存放枚举到的设备
List<IGXDeviceInfo> iGXDeviceInfos = new List<IGXDeviceInfo>();
//枚举同一网段下的相机 无ALL
IGXFactory.GetInstance().UpdateDeviceList(1000, iGXDeviceInfos);
//枚举同一网络下所有相机 有ALL
//IGXFactory.GetInstance().UpdateAllDeviceList(1000, iGXDeviceInfos);
m_sn = iGXDeviceInfos[index].GetSN();
m_id = iGXDeviceInfos[index].GetDeviceID();
}
//相机数量
public static void GetCamNum()
{
//先定义一个设备列表,用来存放枚举到的设备
List<IGXDeviceInfo> iGXDeviceInfos = new List<IGXDeviceInfo>();
//枚举同一网段下的相机 无ALL
IGXFactory.GetInstance().UpdateDeviceList(1000, iGXDeviceInfos);
//枚举同一网络下所有相机 有ALL
//IGXFactory.GetInstance().UpdateAllDeviceList(1000, iGXDeviceInfos);
cam_num = iGXDeviceInfos.Count;
}
//打开相机
public void OpenCam()
{
//打开相机
//第四步,打开相机,可以通过IP、SN、MAC、ID等唯一标识符打开相机
//这里通过SN打开相机,打开相机的方式有三种: 只读、控制、独占
cam = IGXFactory.GetInstance().OpenDeviceBySN(m_sn, GX_ACCESS_MODE.GX_ACCESS_CONTROL);
//获取相机属性控制器
cam_remote_control = cam.GetRemoteFeatureControl();
cam_control = cam.GetFeatureControl();
//打开流通道
cam_stream = cam.OpenStream(0);
//打开流对象属性控制器
cam_stream_control = cam_stream.GetFeatureControl();
//是否彩色相机
__IsSupportColor(ref colorFlag);
}
public void StartAqc()
{
//注册回调函数
cam_stream.RegisterCaptureCallback(cam, _CallCaptureBack);
//开启流通道采集
cam_stream.StartGrab();
//发送开采命令,设备参数字符串可以去文档里查看
cam_remote_control.GetCommandFeature("AcquisitionStart").Execute();
}
/// <summary>
/// 是否支持彩色
/// </summary>
/// <param name="bIsColorFilter">是否支持彩色</param>
private void __IsSupportColor(ref bool bIsColorFilter)
{
bool bIsImplemented = false;
bool bIsMono = false;
string strPixelFormat = "";
strPixelFormat = cam.GetRemoteFeatureControl().GetEnumFeature("PixelFormat").GetValue();
if (0 == string.Compare(strPixelFormat, 0, "Mono", 0, 4))
{
bIsMono = true;
}
else
{
bIsMono = false;
}
bIsImplemented = cam.GetRemoteFeatureControl().IsImplemented("PixelColorFilter");
// 若当前为非黑白且支持PixelColorFilter则为彩色
if ((!bIsMono) && (bIsImplemented))
{
bIsColorFilter = true;
}
else
{
bIsColorFilter = false;
}
}
//创建回调函数
//其中回调函数中包含一个自定义变量和一个图像数据
public void _CallCaptureBack(object userParam, IFrameData imgData)
{
//获取并打印图像宽高
int imgHeight = (int)imgData.GetHeight();
int imgWidth = (int)imgData.GetWidth();
//将图像显示在 PictureBox中
//判断是黑板还是彩色相机
if (colorFlag)//彩色
{
//获取图像buffer
IntPtr buffer = imgData.ConvertToRGB24(GX_VALID_BIT_LIST.GX_BIT_0_7, GX_BAYER_CONVERT_TYPE_LIST.GX_RAW2RGB_NEIGHBOUR, false);
//将图像转成BMP格式
Bitmap bitmap = new Bitmap(imgWidth, imgHeight, imgWidth * 3, System.Drawing.Imaging.PixelFormat.Format24bppRgb, buffer);
//显示图像
//由于回调函数相当于开了一个线程,但pictureBox主界面中的对象;
//因此需要使用托管的方式对picturebox进行操作
Action action = () =>
{
pictureBox.Image = bitmap;
};
pictureBox.BeginInvoke(action);
}
else//黑白
{
//如果是黑白相机,直接转为bmp
Bitmap bitmap = new Bitmap(imgWidth, imgHeight, imgWidth, System.Drawing.Imaging.PixelFormat.Format8bppIndexed, imgData.GetBuffer());
//需要使用调色盘进行像素翻转
System.Drawing.Imaging.ColorPalette colorPalette = bitmap.Palette;
for (int i = 0; i < 255; i++)
{
colorPalette.Entries[i] = System.Drawing.Color.FromArgb(i, i, i);
}
bitmap.Palette = colorPalette;
//显示图像
//由于回调函数相当于开了一个线程,但pictureBox主界面中的对象;
//因此需要使用托管的方式对picturebox进行操作
Action action = () =>
{
pictureBox.Image = bitmap;
};
pictureBox.BeginInvoke(action);
}
}
private void CloseCam()
{
//停止采集和关闭相机
//关闭相机首先需要先停止流采集;再注销前面所注册的所有回调函数;
//关闭采集命令
cam_remote_control.GetCommandFeature("AcquisitionStop").Execute();
//关闭流通道
cam_stream.StopGrab();
//关闭回调函数
cam_stream.UnregisterCaptureCallback();
//关闭相机
cam.Close();
//最后通过反初始化释放所有资源;
//多相机要等所有相机都关闭后,再反初始化;;所以此处先注释掉
//IGXFactory.GetInstance().Uninit();
}
}
}
2 主界面
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using GxIAPINET;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace multiCam
{
public partial class multiCamForm : Form
{
//先要做一个PictureBox的列表,后面需要将PictureBox的列表放入到类的PictureBox中
List<PictureBox> pictureBoxes = new List<PictureBox>();
//全局变量相机类的对象的数组
DhCamera[] cam;
public multiCamForm()
{
InitializeComponent();
DhCamera.InitCam();
//将3个PictureBox添加到PictureBox的列表中
pictureBoxes.Add(pictureBox1);
pictureBoxes.Add(pictureBox2);
pictureBoxes.Add(pictureBox3);
}
private void multiCamForm_Load(object sender, EventArgs e)
{
//获取相机数量
DhCamera.GetCamNum();
tBoxCamNum.Text = "检测到" + DhCamera.cam_num.ToString() + "个相机";
cam = new DhCamera[DhCamera.cam_num];//根据获取到的相机数量定义相机数组长度
//通过一个循环,对获取到的相机实例化
for (int i = 0; i < DhCamera.cam_num; i++)
{
cam[i] = new DhCamera();
//枚举方式获取相机SN编码
cam[i].InfoCam(i);
//将相机ID放入到ComboBox中
cBoxCamName.Items.Add(cam[i].m_id);
//将主窗口中的的PictureBox循环的放入到 我们创建相机类对象中去
cam[i].pictureBox = pictureBoxes[i];
}
//对所有的相机进行一个选择
cBoxCamName.Items.Add("All");
}
private void btOpenCam_Click(object sender, EventArgs e)
{
//通过一个循环,对获取到的相机实例化
for (int i = 0; i < DhCamera.cam_num; i++)
{
cam[i].OpenCam();
}
}
}
}