目录

1.新建工程

2.文件及属性配置

2.1文件拷贝

2.2VS项目属性配置

2.2.1包含目录和库目录添加

2.2.2附加依赖项添加

3.添加基于官方mfc代码改写的CGXBitmap类

3.1添加CGXBitmap类

3.2编写CGXBitmap.h和.cpp文件

4.编写Qt .h和 .cpp文件

5.运行效果

6.下载链接

7.双相机代码移植Qt版


1.新建工程

该项目是通过阅读大恒官方C++项目的代码进行移植的一个Qt简单demo,废话不多说直接上步骤。

​​​​

至此一个Qt项目创建完毕。

2.文件及属性配置

因为需要使用大恒官方的API,那么就需要使用官方提供的库文件和头文件。可以通过该步骤添加到项目中。(方法不唯一,这里为了移植到其他电脑才这样做的)

2.1文件拷贝

2.2VS项目属性配置

2.2.1包含目录和库目录添加

2.2.2附加依赖项添加

至此整个项目的属性配置和文件就配置完成了。

3.添加基于官方mfc代码改写的CGXBitmap类

CGXBitmap类是我基于大恒官方提供的C++代码中mfc版CGXBitmap类改写的。具体功能有:显示图像、保存图像等功能。具体步骤如下:

3.1添加CGXBitmap类

3.2编写CGXBitmap.h和.cpp文件

在添加的CGXBitmap.h 填写如下内容

//
/*CGXBitmap.h*/
/
#pragma once#include <QWidget>
#include "ui_CGXBitmap.h"
#include <QLabel>
#include <iostream>
#include <GalaxyIncludes.h>using namespace std;#pragma execution_character_set("utf-8")class CGXBitmap : public QWidget
{Q_OBJECTpublic:CGXBitmap(QWidget *parent = Q_NULLPTR);~CGXBitmap();private:Ui::CGXBitmap ui;bool               m_bIsColor;                       //是否支持彩色相机int64_t            m_nImageHeight;                   //原始图像高int64_t            m_nImageWidth;                    //原始图像宽BITMAPINFO         *m_pBmpInfo;                         //BITMAPINFO 结构指针,显示图像时使用char               m_chBmpBuf[2048];                //BIMTAPINFO 存储缓冲区,m_pBmpInfo即指向此缓冲区uchar              *m_pImageBuffer;                  //保存翻转后的图像用于显示
private:CGXBitmap& operator=(const CGXBitmap&);CGXBitmap(const CGXBitmap&);public:QLabel              *m_pLabel;QImage            *m_pImage;//显示图像void Show(CImageDataPointer& objCImageDataPointer);//图像处理后并显示图像void ShowImageProcess(CImageProcessConfigPointer& objCfg, CImageDataPointer& objCImageDataPointer);//存储Bmp图像void SaveBmp(CImageDataPointer& objCImageDataPointer, const std::string& strFilePath);//存储Raw图像void SaveRaw(CImageDataPointer& objCImageDataPointer, const std::string& strFilePath);//通过GX_PIXEL_FORMAT_ENTRY获取最优Bit位GX_VALID_BIT_LIST GetBestValudBit(GX_PIXEL_FORMAT_ENTRY emPixelFormatEntry);LPCWSTR stringToLPCWSTR(std::string orig);void addDevicePtr(CGXDevicePointer& objCGXDevicePointer);private://判断PixelFormat是否为8位bool __IsPixelFormat8(GX_PIXEL_FORMAT_ENTRY emPixelFormatEntry);//为彩色相机图像显示准备资源void __ColorPrepareForShowImg();//为黑白相机图像显示准备资源void __MonoPrepareForShowImg();//判断是否兼容bool __IsCompatible(BITMAPINFO *pBmpInfo, uint64_t nWidth, uint64_t nHeight);//更新Bitmap的信息void __UpdateBitmap(CImageDataPointer& objCImageDataPointer);//将m_pBufferRGB中图像显示到界面void __DrawImg(uchar* pBuffer);//计算宽度所占的字节数int64_t __GetStride(int64_t nWidth, bool bIsColor);//是否支持彩色void __IsSupportColor(CGXDevicePointer& objCGXDevicePointer, bool &bIsColorFilter);};

在添加的CGXBitmap.cpp填写如下内容:

#include "CGXBitmap.h"
//---------------------------------------------------------------------------------
/**
\brief   构造函数
\param   objCGXDevicePointer 图像设备指针
\param   parent 窗体指针
\return  无
*/
//----------------------------------------------------------------------------------
CGXBitmap::CGXBitmap(QWidget *parent): QWidget(parent), m_bIsColor(false), m_nImageHeight(0), m_nImageWidth(0), m_pImage(NULL), m_pBmpInfo(NULL), m_pImageBuffer(NULL)
{ui.setupUi(this);//初始化绘图框m_pLabel = new QLabel(this);m_pLabel->move(0, 0);m_pLabel->resize(751, 551);}void CGXBitmap::addDevicePtr(CGXDevicePointer& objCGXDevicePointer)
{if (objCGXDevicePointer.IsNull()){throw std::runtime_error("Argument is error");}memset(m_chBmpBuf, 0, sizeof(m_chBmpBuf));gxstring strValue = "";//获得图像宽度、高度等m_nImageWidth = (int64_t)objCGXDevicePointer->GetRemoteFeatureControl()->GetIntFeature("Width")->GetValue();m_nImageHeight = (int64_t)objCGXDevicePointer->GetRemoteFeatureControl()->GetIntFeature("Height")->GetValue();//获取是否为彩色相机__IsSupportColor(objCGXDevicePointer, m_bIsColor);if (m_bIsColor){__ColorPrepareForShowImg();}else{__MonoPrepareForShowImg();}
}
//---------------------------------------------------------------------------------
/**
\brief   析构函数\return  无
*/
//----------------------------------------------------------------------------------
CGXBitmap::~CGXBitmap()
{}//----------------------------------------------------------------------------------
/**
\brief     判断PixelFormat是否为8位
\param     emPixelFormatEntry 图像数据格式
\return    true为8为数据,false为非8位数据
*/
//----------------------------------------------------------------------------------
bool CGXBitmap::__IsPixelFormat8(GX_PIXEL_FORMAT_ENTRY emPixelFormatEntry)
{bool bIsPixelFormat8 = false;const unsigned  PIXEL_FORMATE_BIT = 0x00FF0000;  ///<用于与当前的数据格式进行与运算得到当前的数据位数unsigned uiPixelFormatEntry = (unsigned)emPixelFormatEntry;if ((uiPixelFormatEntry & PIXEL_FORMATE_BIT) == GX_PIXEL_8BIT){bIsPixelFormat8 = true;}return bIsPixelFormat8;
}//----------------------------------------------------------------------------------
/**
\brief     通过GX_PIXEL_FORMAT_ENTRY获取最优Bit位
\param     emPixelFormatEntry 图像数据格式
\return    最优Bit位
*/
//----------------------------------------------------------------------------------
GX_VALID_BIT_LIST CGXBitmap::GetBestValudBit(GX_PIXEL_FORMAT_ENTRY emPixelFormatEntry)
{GX_VALID_BIT_LIST emValidBits = GX_BIT_0_7;switch (emPixelFormatEntry){case GX_PIXEL_FORMAT_MONO8:case GX_PIXEL_FORMAT_BAYER_GR8:case GX_PIXEL_FORMAT_BAYER_RG8:case GX_PIXEL_FORMAT_BAYER_GB8:case GX_PIXEL_FORMAT_BAYER_BG8:{emValidBits = GX_BIT_0_7;break;}case GX_PIXEL_FORMAT_MONO10:case GX_PIXEL_FORMAT_BAYER_GR10:case GX_PIXEL_FORMAT_BAYER_RG10:case GX_PIXEL_FORMAT_BAYER_GB10:case GX_PIXEL_FORMAT_BAYER_BG10:{emValidBits = GX_BIT_2_9;break;}case GX_PIXEL_FORMAT_MONO12:case GX_PIXEL_FORMAT_BAYER_GR12:case GX_PIXEL_FORMAT_BAYER_RG12:case GX_PIXEL_FORMAT_BAYER_GB12:case GX_PIXEL_FORMAT_BAYER_BG12:{emValidBits = GX_BIT_4_11;break;}case GX_PIXEL_FORMAT_MONO14:{//暂时没有这样的数据格式待升级break;}case GX_PIXEL_FORMAT_MONO16:case GX_PIXEL_FORMAT_BAYER_GR16:case GX_PIXEL_FORMAT_BAYER_RG16:case GX_PIXEL_FORMAT_BAYER_GB16:case GX_PIXEL_FORMAT_BAYER_BG16:{//暂时没有这样的数据格式待升级break;}default:break;}return emValidBits;
}//---------------------------------------------------------------------------------
/**
\brief   为彩色相机图像显示准备资源\return  无
*/
//----------------------------------------------------------------------------------
void CGXBitmap::__ColorPrepareForShowImg()
{//--------------------------------------------------------------------//---------------------------初始化bitmap头---------------------------m_pBmpInfo = (BITMAPINFO *)m_chBmpBuf;m_pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);m_pBmpInfo->bmiHeader.biWidth = (LONG)m_nImageWidth;m_pBmpInfo->bmiHeader.biHeight = (LONG)m_nImageHeight;m_pBmpInfo->bmiHeader.biPlanes = 1;m_pBmpInfo->bmiHeader.biBitCount = 24;m_pBmpInfo->bmiHeader.biCompression = BI_RGB;m_pBmpInfo->bmiHeader.biSizeImage = 0;m_pBmpInfo->bmiHeader.biXPelsPerMeter = 0;m_pBmpInfo->bmiHeader.biYPelsPerMeter = 0;m_pBmpInfo->bmiHeader.biClrUsed = 0;m_pBmpInfo->bmiHeader.biClrImportant = 0;
}//---------------------------------------------------------------------------------
/**
\brief   为黑白相机图像显示准备资源\return  无
*/
//----------------------------------------------------------------------------------
void CGXBitmap::__MonoPrepareForShowImg()
{//---------------------------------------------------------------------//----------------------初始化bitmap头---------------------------------m_pBmpInfo = (BITMAPINFO *)m_chBmpBuf;m_pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);m_pBmpInfo->bmiHeader.biWidth = (LONG)m_nImageWidth;m_pBmpInfo->bmiHeader.biHeight = (LONG)m_nImageHeight;m_pBmpInfo->bmiHeader.biPlanes = 1;m_pBmpInfo->bmiHeader.biBitCount = 8; // 黑白图像为8m_pBmpInfo->bmiHeader.biCompression = BI_RGB;m_pBmpInfo->bmiHeader.biSizeImage = 0;m_pBmpInfo->bmiHeader.biXPelsPerMeter = 0;m_pBmpInfo->bmiHeader.biYPelsPerMeter = 0;m_pBmpInfo->bmiHeader.biClrUsed = 0;m_pBmpInfo->bmiHeader.biClrImportant = 0;// 黑白图像需要初始化调色板for (int i = 0; i < 256; i++){m_pBmpInfo->bmiColors[i].rgbBlue = i;m_pBmpInfo->bmiColors[i].rgbGreen = i;m_pBmpInfo->bmiColors[i].rgbRed = i;m_pBmpInfo->bmiColors[i].rgbReserved = 0;}//为经过翻转后的图像数据分配空间if (m_pImageBuffer != NULL){delete m_pImageBuffer;m_pImageBuffer = NULL;}m_pImageBuffer = new BYTE[(size_t)(m_nImageWidth * m_nImageHeight)];if (m_pImageBuffer == NULL){throw std::runtime_error("Fail to allocate memory");}
}//----------------------------------------------------------------------------------
/**
\brief     判断是否兼容
\param     pBmpInfo BITMAPINFO指针
\param     nWidth 图像宽
\param     nHeight 图像高
\return    true为一样,false不一样
*/
//----------------------------------------------------------------------------------
bool CGXBitmap::__IsCompatible(BITMAPINFO *pBmpInfo, uint64_t nWidth, uint64_t nHeight)
{if (pBmpInfo == NULL|| pBmpInfo->bmiHeader.biHeight != nHeight|| pBmpInfo->bmiHeader.biWidth != nWidth){return false;}return true;
}//----------------------------------------------------------------------------------
/**
\brief     检查图像是否改变并更新Buffer并为图像显示准备资源
\param     objCImageDataPointer  图像数据对象
\return    无
*/
//----------------------------------------------------------------------------------
void CGXBitmap::__UpdateBitmap(CImageDataPointer& objCImageDataPointer)
{if (!__IsCompatible(m_pBmpInfo, objCImageDataPointer->GetWidth(), objCImageDataPointer->GetHeight())){m_nImageWidth = objCImageDataPointer->GetWidth();m_nImageHeight = objCImageDataPointer->GetHeight();if (m_bIsColor){__ColorPrepareForShowImg();}else{__MonoPrepareForShowImg();}}
}//---------------------------------------------------------------------------------
/**
\brief   将m_pBufferRGB中图像显示到界面
\param   pBuffer  图像数据Buffer指针
\return  无
*/
//----------------------------------------------------------------------------------
void CGXBitmap::__DrawImg(uchar* pBuffer)
{if (m_pImage != NULL){delete m_pImage;m_pImage = NULL;}//数据转换m_pImage = new QImage(pBuffer, m_nImageWidth, m_nImageHeight, QImage::Format_Indexed8);// 不失真缩放m_pImage->scaled(m_nImageWidth, m_nImageHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);m_pLabel->setScaledContents(true);m_pLabel->setPixmap(QPixmap::fromImage(*m_pImage));
}
//----------------------------------------------------------------------------------
/**
\brief     计算宽度所占的字节数
\param     nWidth  图像宽度
\param     bIsColor  是否是彩色相机
\return    图像一行所占的字节数
*/
//----------------------------------------------------------------------------------
int64_t CGXBitmap::__GetStride(int64_t nWidth, bool bIsColor)
{return bIsColor ? nWidth * 3 : nWidth;
}//----------------------------------------------------------------------------------
/**
\brief     用于显示图像
\param     objCImageDataPointer  图像数据对象
\return    无
*/
//----------------------------------------------------------------------------------
void CGXBitmap::Show(CImageDataPointer& objCImageDataPointer)
{GX_VALID_BIT_LIST emValidBits = GX_BIT_0_7;uchar* pBuffer = NULL;if (objCImageDataPointer.IsNull()){throw std::runtime_error("NULL pointer dereferenced");}//检查图像是否改变并更新Buffer__UpdateBitmap(objCImageDataPointer);emValidBits = GetBestValudBit(objCImageDataPointer->GetPixelFormat());if (m_bIsColor){pBuffer = (uchar*)objCImageDataPointer->ConvertToRGB24(emValidBits, GX_RAW2RGB_NEIGHBOUR, true);__DrawImg(pBuffer);}else{if (__IsPixelFormat8(objCImageDataPointer->GetPixelFormat())){pBuffer = (uchar*)objCImageDataPointer->GetBuffer();}else{pBuffer = (uchar*)objCImageDataPointer->ConvertToRaw8(emValidBits);}__DrawImg(pBuffer);}}//----------------------------------------------------------------------------------
/**
\brief     用于图像处理后并显示图像
\param     objCfg  图像处理调节参数对象
\param     objCImageDataPointer  图像数据对象
\return    无
*/
//----------------------------------------------------------------------------------
void CGXBitmap::ShowImageProcess(CImageProcessConfigPointer& objCfg, CImageDataPointer& objCImageDataPointer)
{if ((objCfg.IsNull()) || (objCImageDataPointer.IsNull())){throw std::runtime_error("NULL pointer dereferenced");}//检查图像是否改变并更新Buffer__UpdateBitmap(objCImageDataPointer);BYTE* pBuffer = (BYTE*)objCImageDataPointer->ImageProcess(objCfg);if (m_bIsColor){__DrawImg(pBuffer);}else{// 黑白相机需要翻转数据后显示for (int i = 0; i < m_nImageHeight; i++){memcpy(m_pImageBuffer + i * m_nImageWidth, pBuffer + (m_nImageHeight - i - 1) * m_nImageWidth, (size_t)m_nImageWidth);}__DrawImg(m_pImageBuffer);}
}
//----------------------------------------------------------------------------------
/**
\brief     存储Bmp图像
\param     objCImageDataPointer  图像数据对象
\param     strFilePath  显示图像文件名
\return    无
*/
//----------------------------------------------------------------------------------
void CGXBitmap::SaveBmp(CImageDataPointer& objCImageDataPointer, const std::string& strFilePath)
{GX_VALID_BIT_LIST emValidBits = GX_BIT_0_7;uchar* pBuffer = NULL;if ((objCImageDataPointer.IsNull()) || (strFilePath == "")){throw std::runtime_error("Argument is error");}//检查图像是否改变并更新Buffer__UpdateBitmap(objCImageDataPointer);emValidBits = GetBestValudBit(objCImageDataPointer->GetPixelFormat());if (m_bIsColor){pBuffer = (uchar*)objCImageDataPointer->ConvertToRGB24(emValidBits, GX_RAW2RGB_NEIGHBOUR, true);}else{if (__IsPixelFormat8(objCImageDataPointer->GetPixelFormat())){pBuffer = (uchar*)objCImageDataPointer->GetBuffer();}else{pBuffer = (uchar*)objCImageDataPointer->ConvertToRaw8(emValidBits);}// 黑白相机需要翻转数据后显示for (int i = 0; i < m_nImageHeight; i++){memcpy(m_pImageBuffer + i * m_nImageWidth, pBuffer + (m_nImageHeight - i - 1) * m_nImageWidth, (size_t)m_nImageWidth);}pBuffer = m_pImageBuffer;}DWORD                 dwImageSize = (DWORD)(__GetStride(m_nImageWidth, m_bIsColor) * m_nImageHeight);BITMAPFILEHEADER     stBfh = { 0 };DWORD               dwBytesRead = 0;stBfh.bfType = (WORD)'M' << 8 | 'B';            //定义文件类型stBfh.bfOffBits = m_bIsColor ? sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER): sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (256 * 4);   //定义文件头大小true为彩色,false为黑白stBfh.bfSize = stBfh.bfOffBits + dwImageSize; //文件大小DWORD dwBitmapInfoHeader = m_bIsColor ? sizeof(BITMAPINFOHEADER): sizeof(BITMAPINFOHEADER) + (256 * 4);    //定义BitmapInfoHeader大小true为彩色,false为黑白//创建文件HANDLE hFile = ::CreateFile(stringToLPCWSTR(strFilePath),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);if (hFile == INVALID_HANDLE_VALUE){throw std::runtime_error("Handle is invalid");}::WriteFile(hFile, &stBfh, sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL);::WriteFile(hFile, m_pBmpInfo, dwBitmapInfoHeader, &dwBytesRead, NULL); //黑白和彩色自适应::WriteFile(hFile, pBuffer, dwImageSize, &dwBytesRead, NULL);CloseHandle(hFile);
}
//----------------------------------------------------------------------------------
/**
\brief     存储Raw图像
\param     objCImageDataPointer  图像数据对象
\param     strFilePath  显示图像文件名
\return    无
*/
//----------------------------------------------------------------------------------
void CGXBitmap::SaveRaw(CImageDataPointer& objCImageDataPointer, const std::string& strFilePath)
{if ((objCImageDataPointer.IsNull()) || (strFilePath == "")){throw std::runtime_error("Argument is error");}//检查图像是否改变并更新Buffer__UpdateBitmap(objCImageDataPointer);DWORD   dwImageSize = (DWORD)objCImageDataPointer->GetPayloadSize();  // 写入文件的长度DWORD   dwBytesRead = 0;                // 文件读取的长度BYTE* pbuffer = (BYTE*)objCImageDataPointer->GetBuffer();if (!m_bIsColor){// 黑白相机需要翻转数据后显示for (int i = 0; i < m_nImageHeight; i++){memcpy(m_pImageBuffer + i * m_nImageWidth, pbuffer + (m_nImageHeight - i - 1) * m_nImageWidth, (size_t)m_nImageWidth);}pbuffer = m_pImageBuffer;}// 创建文件HANDLE hFile = ::CreateFile(stringToLPCWSTR(strFilePath),GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);if (hFile == INVALID_HANDLE_VALUE)   // 创建失败则返回{throw std::runtime_error("Handle is invalid");}else                                 // 保存Raw图像          {::WriteFile(hFile, pbuffer, dwImageSize, &dwBytesRead, NULL);CloseHandle(hFile);}
}
//----------------------------------------------------------------------------------
/**
\brief     是否支持彩色
\param     objCGXDevicePointer  [in]    设备句柄
\param     bIsColorFilter       [out]   是否支持彩色\return
*/
//----------------------------------------------------------------------------------
void CGXBitmap::__IsSupportColor(CGXDevicePointer& objCGXDevicePointer, bool &bIsColorFilter)
{GX_STATUS emStatus = GX_STATUS_SUCCESS;bool      bIsImplemented = false;bool      bIsMono = false;gxstring  strPixelFormat = "";strPixelFormat = objCGXDevicePointer->GetRemoteFeatureControl()->GetEnumFeature("PixelFormat")->GetValue();strPixelFormat.substr(0, 4);if (0 == memcmp(strPixelFormat.c_str(), "Mono", 4)){bIsMono = true;}else{bIsMono = false;}bIsImplemented = objCGXDevicePointer->GetRemoteFeatureControl()->IsImplemented("PixelColorFilter");// 若当前为非黑白且支持PixelColorFilter则为彩色if ((!bIsMono) && (bIsImplemented)){bIsColorFilter = true;}else{bIsColorFilter = false;}
}LPCWSTR CGXBitmap::stringToLPCWSTR(std::string orig)
{size_t origsize = orig.length() + 1;const size_t newsize = 100;size_t convertedChars = 0;wchar_t* wcstring = (wchar_t*)malloc(sizeof(wchar_t) * (orig.length() - 1));mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);return wcstring;
}

CGXBitmap.ui不做修改

4.编写Qt .h和 .cpp文件

接下来编写最后的核心文件,具体文件以自己命名为主。

编写daheng_SingleCam_for_qt.h(我的界面是用代码生成的,没有使用拖曳的方式生成,目的是为了提供更好的代码观感)

#pragma once#include <QtWidgets/QMainWindow>
#include "ui_daheng_SingleCam_for_qt.h"
#include <GalaxyIncludes.h>
#include <iostream>
#include "CGXBitmap.h"
#include <QPushButton>
#include <QLabel>
#include <QCloseEvent>using namespace std;#pragma execution_character_set("utf-8")class daheng_SingleCam_for_qt : public QMainWindow
{Q_OBJECT//用户继承采集事件处理类class CSampleCaptureEventHandler : public ICaptureEventHandler{public://---------------------------------------------------------------------------------/**\brief   采集回调函数\param   objImageDataPointer      图像处理参数\param   pFrame                   用户参数\return  无*///----------------------------------------------------------------------------------void DoOnImageCaptured(CImageDataPointer&objImageDataPointer, void* pUserParam){try{daheng_SingleCam_for_qt* pSingleCamDlg = (daheng_SingleCam_for_qt*)pUserParam;//显示图像pSingleCamDlg->m_pBitmap->Show(objImageDataPointer);//判断是否需要保存图像//if (pSingleCamDlg->m_pBitmap->m_bSaveImage == true)//{//    pSingleCamDlg->m_pBitmap->SavePicture(objImageDataPointer);// pSingleCamDlg->m_pBitmap->m_bSaveImage = false;//}}catch (CGalaxyException){}catch (std::exception){}}};
public:daheng_SingleCam_for_qt(QWidget *parent = Q_NULLPTR);CGXBitmap  *m_pBitmap;             //图像操作类private:Ui::daheng_SingleCam_for_qtClass ui;//Qt控件QPushButton *m_pBtnOpenDevice;     //打开设备按钮QPushButton *m_pBtnCloseDevice;     //关闭设备按钮QPushButton *m_pBtnStartSnap;       //开始采集按钮QPushButton *m_pBtnStopSnap;        //停止采集按钮QLabel      *m_pLabel;              //状态栏显示文字//用于界面更新的标识bool        m_bIsOpen;              //打开设备标识bool        m_bIsSnap;              //采集图像标识//大恒相机APICGXFeatureControlPointer           *m_pFeatureEventHandler;                //远端设备事件回调对象CSampleCaptureEventHandler          *m_pCaptureEventHandler;                //采集回调对象CGXDevicePointer                    m_ObjDevicePtr;                         //设备句柄CGXStreamPointer                  m_ObjStreamPtr;                         //设备流CGXFeatureControlPointer           m_ObjFeatureControlPtr;                 //属性控制器CGXFeatureControlPointer         m_ObjStreamFeatureControlPtr;           //流层控制器//槽函数void on_Btn_OpenDevice_clicked();void on_Btn_CloseDevice_clicked();void on_Btn_StartSnap_clicked();void on_Btn_StopSnap_clicked();//关闭窗口事件重写void closeEvent(QCloseEvent *event);//更新界面void UpdateUI();};

daheng_SingleCam_for_qt.cpp

#include "daheng_SingleCam_for_qt.h"daheng_SingleCam_for_qt::daheng_SingleCam_for_qt(QWidget *parent): QMainWindow(parent), m_bIsOpen(false), m_bIsSnap(false)
{ui.setupUi(this);//控件初始化m_pBtnOpenDevice = new QPushButton(this);m_pBtnOpenDevice->setText("打开设备");m_pBtnOpenDevice->move(0, 0);m_pBtnCloseDevice = new QPushButton(this);m_pBtnCloseDevice->setText("关闭设备");m_pBtnCloseDevice->move(0, 50);m_pBtnStartSnap = new QPushButton(this);m_pBtnStartSnap->setText("开始采集");m_pBtnStartSnap->move(0, 100);m_pBtnStopSnap = new QPushButton(this);m_pBtnStopSnap->setText("停止采集");m_pBtnStopSnap->move(0, 150);m_pBitmap = new CGXBitmap(this);m_pBitmap->move(100, 0);m_pBitmap->resize(800, 607);m_pLabel = new QLabel(this);m_pLabel->setText("欢迎使用大恒相机[for Qt]");statusBar()->addWidget(m_pLabel);//将label控件添加到状态栏//连接信号和槽函数connect(m_pBtnOpenDevice, &QPushButton::clicked, this, &daheng_SingleCam_for_qt::on_Btn_OpenDevice_clicked);connect(m_pBtnCloseDevice, &QPushButton::clicked, this, &daheng_SingleCam_for_qt::on_Btn_CloseDevice_clicked);connect(m_pBtnStartSnap, &QPushButton::clicked, this, &daheng_SingleCam_for_qt::on_Btn_StartSnap_clicked);connect(m_pBtnStopSnap, &QPushButton::clicked, this, &daheng_SingleCam_for_qt::on_Btn_StopSnap_clicked);//大恒API库调用try{//初始化设备IGXFactory::GetInstance().Init();m_pCaptureEventHandler = new CSampleCaptureEventHandler();//更新界面UpdateUI();}catch (CGalaxyException& e){if (m_pCaptureEventHandler != NULL){delete m_pCaptureEventHandler;m_pCaptureEventHandler = NULL;}m_pLabel->setText(QString::fromStdString(e.what()));return;}catch (std::exception& e){if (m_pCaptureEventHandler != NULL){delete m_pCaptureEventHandler;m_pCaptureEventHandler = NULL;}m_pLabel->setText(QString::fromStdString(e.what()));return;}
}
//---------------------------------------------------------------------------------
/**
\brief   更新界面\return  无
*/
//----------------------------------------------------------------------------------
void daheng_SingleCam_for_qt::UpdateUI()
{m_pBtnOpenDevice->setEnabled(!m_bIsOpen);m_pBtnCloseDevice->setEnabled(m_bIsOpen);m_pBtnStartSnap->setEnabled(m_bIsOpen && !m_bIsSnap);m_pBtnStopSnap->setEnabled(m_bIsOpen && m_bIsSnap);
}void daheng_SingleCam_for_qt::on_Btn_OpenDevice_clicked()
{bool bIsDeviceOpen = false;       //设备是否打开标识bool bIsStreamOpen = false;      //设备流是否打开标识try{//枚举设备GxIAPICPP::gxdeviceinfo_vector vectorDeviceInfo;IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);if (vectorDeviceInfo.size() == 0){m_bIsOpen = false;bIsDeviceOpen = false;m_pLabel->setText("无可用设备!");return;}//打开第一个设备以及设备下面第一个流m_ObjDevicePtr = IGXFactory::GetInstance().OpenDeviceBySN(vectorDeviceInfo[0].GetSN(), GX_ACCESS_EXCLUSIVE);//打开方式:独占m_bIsOpen = true;bIsDeviceOpen = true;//获取远端设备属性控制器m_ObjFeatureControlPtr = m_ObjDevicePtr->GetRemoteFeatureControl();//为画图对象分配设备指针m_pBitmap->addDevicePtr(m_ObjDevicePtr);//判断设备流是否大于零,如果大于零则打开流int nStreamCount = m_ObjDevicePtr->GetStreamCount();if (nStreamCount){m_ObjStreamPtr = m_ObjDevicePtr->OpenStream(0);//获取流层属性控制器m_ObjStreamFeatureControlPtr = m_ObjStreamPtr->GetFeatureControl();bIsStreamOpen = true;}else{throw exception("未发现设备流!");}//提高网络相机的采集性能,设置方法如下(目前只有千兆网系列相机支持设置最优包长)GX_DEVICE_CLASS_LIST ObjDeviceClass =m_ObjDevicePtr->GetDeviceInfo().GetDeviceClass();if (ObjDeviceClass == GX_DEVICE_CLASS_GEV){//判断设备是否支持流通道数据包功能if (m_ObjStreamFeatureControlPtr->IsImplemented("GevSCPSPacketSize")){//获取当前网络环境的最优包长值int nPacketSize = m_ObjStreamPtr->GetOptimalPacketSize();//将最优包长值设置为当前设备的流通道包长值m_ObjFeatureControlPtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize);}}//更新界面UpdateUI();m_pLabel->setText(QString("打开设备成功!"));}catch (CGalaxyException& e){//判断设备流是否已打开if (bIsStreamOpen){m_ObjStreamPtr->Close();}//判断设备是否已打开if (bIsDeviceOpen){m_ObjDevicePtr->Close();}m_pLabel->setText(QString::fromStdString(e.what()));return;}catch (exception& e){//判断设备流是否已打开if (bIsStreamOpen){m_ObjStreamPtr->Close();}//判断设备是否已打开if (bIsDeviceOpen){m_ObjDevicePtr->Close();}m_pLabel->setText(QString::fromStdString(e.what()));return;}
}void daheng_SingleCam_for_qt::on_Btn_CloseDevice_clicked()
{try{//判断是否已停止采集if (m_bIsSnap){//发送停采命令m_ObjFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();//关闭流层采集m_ObjStreamPtr->StopGrab();//注销采集回调m_ObjStreamPtr->UnregisterCaptureCallback();}}catch (CGalaxyException){//do noting}try{//关闭流对象m_ObjStreamPtr->Close();}catch (CGalaxyException){//do noting}try{//关闭设备m_ObjDevicePtr->Close();m_pLabel->setText(QString("关闭设备成功!"));}catch (CGalaxyException){//do noting}m_bIsOpen = false;m_bIsSnap = false;//更新界面UpdateUI();
}void daheng_SingleCam_for_qt::on_Btn_StartSnap_clicked()
{// TODO: Add your control notification handler code heretry{try{//设置Buffer处理模式m_ObjStreamFeatureControlPtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst");}catch (...){}//注册回调函数m_ObjStreamPtr->RegisterCaptureCallback(m_pCaptureEventHandler, this);//开启流层通道m_ObjStreamPtr->StartGrab();//发送开采命令m_ObjFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();m_bIsSnap = true;//更新界面UpdateUI();m_pLabel->setText(QString("开始采集!"));}catch (CGalaxyException& e){m_pLabel->setText(QString::fromStdString(e.what()));return;}catch (std::exception& e){m_pLabel->setText(QString::fromStdString(e.what()));return;}
}void daheng_SingleCam_for_qt::on_Btn_StopSnap_clicked()
{// TODO: Add your control notification handler code heretry{//发送停采命令m_ObjFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();//关闭流层通道m_ObjStreamPtr->StopGrab();//注销采集回调m_ObjStreamPtr->UnregisterCaptureCallback();m_bIsSnap = false;//更新界面UpdateUI();m_pLabel->setText(QString("停止采集!"));}catch (CGalaxyException& e){m_pLabel->setText(QString::fromStdString(e.what()));return;}catch (std::exception& e){m_pLabel->setText(QString::fromStdString(e.what()));return;}
}void daheng_SingleCam_for_qt::closeEvent(QCloseEvent *event)
{try{//判断是否停止采集if (m_bIsSnap){//发送停采命令m_ObjFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();//关闭流层通道m_ObjStreamPtr->StopGrab();//注销采集回调m_ObjStreamPtr->UnregisterCaptureCallback();m_bIsSnap = false;}}catch (CGalaxyException& e){}catch (exception& e){}try{//判断是否关闭设备if (m_bIsOpen){//关闭流对象m_ObjStreamPtr->Close();//关闭设备m_ObjDevicePtr->Close();m_bIsOpen = false;}}catch (CGalaxyException& e){}catch (exception& e){}try{//释放设备资源IGXFactory::GetInstance().Uninit();}catch (CGalaxyException& e){}catch (exception& e){}if (m_pCaptureEventHandler != NULL){delete m_pCaptureEventHandler;m_pCaptureEventHandler = NULL;}event->accept();
}

5.运行效果

因为目前我只有一个黑白相机,没办法测试彩色相机是否可行。

6.下载链接

基于Qt大恒工业相机二次开发demo-C++-QT文档类资源-CSDN下载基于Qt大恒工业相机二次开发demo-C++,重写的CGXBitmap类,移植性强更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/qq_42816065/85043886

7.双相机代码移植Qt版

可以实现两个相机的同步采集和图片保存,有兴趣的也可以下载查看使用,该项目需要自己重新配置属性。

大恒双相机C++QT工程文件建议使用Release调试-QT文档类资源-CSDN下载大恒双相机C++QT工程文件建议使用Release调试更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/qq_42816065/85043927

基于Qt大恒工业相机二次开发demo-C++相关推荐

  1. 【Qt】基于Qt的CAN分析仪二次开发

    CAN分析仪有上位机,能够满足我们大多数情况下的使用,但当我们想扩展CAN的使用,如对消息进行封装,实现特定的执行功能时,就需要根据库文件进行二次开发.下面是使用zlg进行二次开发的一次尝试. 请提前 ...

  2. NX/UG二次开发—QT—基于QT平台的UG二次开发

    1.新建QT工程,选择C++库,工程名称qtugdemo: 2.添加对话框文件: 3.将UG入口函数考入到qtugdemo.cpp中,并添加如下代码: 4.修改*.pro文件,添加UG函数需要的lib ...

  3. 大恒工业相机C#语言winform平台开发例程

    大恒工业相机winform快速开发 例程一.连续采集,返回bitmap格式图像 例程二.软触发采集,返回bitmap格式图像 例程三.硬触发采集,返回bitmap格式图像 例程四.作为TCP客户端接收 ...

  4. 大华摄像头二次开发-web端实现实时视频监控

    最近客户提需要,需要在现有的系统中集成视频监控功能,摄像头是大华的.而大华又没有关于java的sdk,官网只能下载到c++的demo和dll文件.无奈只能自己在网上找了,最后找到了一些解决办法,把实现 ...

  5. Qt+大恒相机+OpenCV+MinGW界面开发

    Qt+大恒相机+OpenCV+MinGW界面开发 遇到的坑有哪些? 大恒相机接口的问题(C与C++选谁,傻傻分不清) OpenCV版本与MinGW编译平台适应性问题(编译通过,但是一运行就异常退出) ...

  6. 基于QT的安卓手机蓝牙APP开发

    摘要:前段时间用QT写了一个串口调试助手,感觉还可以.因为QT是跨平台的,同样一套代码可以在windows上面跑,也可以在linux上面跑,也可以在安卓手机上面跑.而且不需要修改任何东西,编译器会自动 ...

  7. Python基于周立功盒子的二次开发的封装和调用

    Python基于周立功盒子的二次开发的封装和调用 一.介绍     前面我们介绍如何拿到官网给的例程并使用起来,但在使用的过程中,我们发现官网给的例子非常的冗长,可读性不好,于是我进行分解和封装,使得 ...

  8. 基于百度编辑器Ueditor的二次开发

    基于百度编辑器Ueditor的二次开发 官网下载 基本配置 简化后端配置,不请求后端配置项 后端接口规范 修改图片上传 说明及修改 新增按钮及弹窗(自定义附件上传) 按钮文案修改 在业务开发的时候,曾 ...

  9. 基于屌丝青年网样式二次开发的WordPress主题:LIiu-One主题

    源码下载:基于屌丝青年网样式二次开发的WordPress主题:LIiu-One主题-小程序文档类资源-CSDN下载 wordpress主题,基于屌丝青年网样式二次开发LIiu-One主题仿屌丝青年网模 ...

最新文章

  1. 创建本地数据库时发生错误及其解决方案
  2. R语言螺旋线型线性不可分数据xgboost分类:使用xgboost模型来解决螺旋数据的分类问题、可视化模型预测的结果、添加超平面区域渲染并与原始数据标签进行对比分析
  3. Linux海量数据高并发实时同步架构方案杂谈
  4. 科技创业公司的效率工具箱
  5. sublime 插件
  6. ITK:区域最大图像过滤器
  7. python卸载不了怎么办说目录有错_错误:无法在安装目录中创建或删除文件
  8. 【echart数组数据】echarts两条或两条以上x轴不同的线合并x轴 含有不连续数据
  9. 17款开源论坛系统/Forum Software(转载)
  10. android 4.4.2截屏方法,android4.4.2 使用 uiautoviewer 截屏报错
  11. 重物码垛搬运机器人_节卡机器人:5G下的智慧物流——柔性生产物流系统
  12. 一道六年级数学题,求阴影面积,那我只能用Python代码了
  13. python中函数startswith的用法_Python中用startswith()函数判断字符串开头的教程
  14. 【codevs1227】方格取数2,费用流
  15. 小Q系列故事——大笨钟
  16. 107 nginx rewrite规则和alias
  17. HAProxy从零开始到掌握
  18. php mysql update 不成功也不提示_php与MySQL(基本操作)
  19. 前端开发常用哪些工具软件?
  20. Web前端开发技术(第3版)储久良 实验12

热门文章

  1. 17个设计灵感创意网站
  2. latex文档排版时空出一行的命令
  3. java app 图标_App 更换应用图标
  4. Javaweb基础入门(IDEA版)值得学习的JavaWeb教程
  5. C语言提取gpgga例子
  6. Python3,为了给女神暗送秋波,我默默的写了一个图片字符画生成器,真香。
  7. 使用face++接口实现人脸相似度比对
  8. 易语言怎么写删除c盘文件夹,易语言删除文件目录的方法
  9. 神奇了!AR技术可测量实物体积!
  10. Origin绘图教程(一)