首页 > 其他分享 >用VC2019+MFC 创建一个DLL封装MD工业相机库然后用EXE调用这个相机库采图并且显示

用VC2019+MFC 创建一个DLL封装MD工业相机库然后用EXE调用这个相机库采图并且显示

时间:2024-11-27 23:34:41浏览次数:7  
标签:status MD MFC int hCamera CMindVisionCallDlg code void 机库

主要描述:

用VC2019+MFC 创建一个DLL封装MD工业相机库,再建一个EXE调用这个相机库采图并且显示。

先创建库工程:
新建一个库工程,

创建完成,添加一个DllFunction.h头文件,一个DllFunction.cpp 源文件

拷贝相关SDK文件到对应的目录下

(略,自行拷贝到相应位置,路径加进工程)

源码如下

DllFunction.h

#pragma once

extern "C" __declspec(dllexport) int InitCamera(int indexCam = 0);
extern "C" __declspec(dllexport) int GetImage();
extern "C" __declspec(dllexport) int Reconnect();
extern "C" __declspec(dllexport) int UninitCamera();

DllFunction.cpp

#pragma once

#include <Windows.h>
//引用相机的SDK包,lib文件的路径根据您的开发环境修改。
#include "CameraApi.h"	 
#include "CameraGrabber.h"
#ifdef _WIN64
#pragma comment(lib, "..\\MVCAMSDK_X64.lib")
#else
#pragma comment(lib, "..\\MVCAMSDK.lib")
#endif

tSdkCameraCapbility m_sCameraInfo; //相机特性描述
UINT            m_threadID;//图像抓取线程的ID
HANDLE          m_hDispThread;//图像抓取线程的句柄
BOOL            m_bExit;//用来通知图像抓取线程结束
BOOL            m_bTrigger;
double			m_fExpTime;//当前的帧曝光时间,单位为us
double			m_fExpLineTime;//当前的行曝光时间,单位为us
INT 			m_iAnalogGain;//当前的信号模拟增益值,步进值为m_fAnalogGainStep

BYTE* m_pFrameBuffer;//用于将原始图像数据转换为RGB的缓冲区(采集线程中)
BYTE* pOutBuffer;
BOOL	        m_bPause;//是否暂停图像
CameraHandle    m_hCamera;	//相机的设备句柄|the handle of the camera we use
tSdkFrameHead   m_sFrInfo;//用于保存当前图像帧的帧头信息


//功能:初始化相机,进行相机的初始化操作
extern "C" __declspec(dllexport) int InitCamera(int indexCam = 0)
{
	if (m_hCamera != 0)
	{
		if (NULL != m_hDispThread)
		{
			m_bExit = TRUE;
			::WaitForSingleObject(m_hDispThread, INFINITE);
			CloseHandle(m_hDispThread);
			m_hDispThread = NULL;
		}
		CameraStop(m_hCamera);
		CameraUnInit(m_hCamera);
	}
	CameraSetCallbackFunction(m_hCamera, NULL, (PVOID)0, NULL);

	tSdkCameraDevInfo sCameraList[10];
	INT iCameraNums;
	CameraSdkStatus status;
	CameraSdkInit(1);

	void* m_Grabber;
	tSdkCameraDevInfo m_DevInfo;
	status = CameraGrabber_CreateFromDevicePage(&m_Grabber);
	if (status != CAMERA_STATUS_SUCCESS)
	{
		return -1;
	}

	CameraGrabber_GetCameraDevInfo(m_Grabber, &m_DevInfo);
	CameraGrabber_GetCameraHandle(m_Grabber, &m_hCamera);

	CameraGetCapability(m_hCamera, &m_sCameraInfo);
	m_pFrameBuffer = CameraAlignMalloc(m_sCameraInfo.sResolutionRange.iWidthMax * 200000, 16); //20万行线扫

	BOOL m_bMonoSensor = m_sCameraInfo.sIspCapacity.bMonoSensor;
	
	if (m_sCameraInfo.sIspCapacity.bMonoSensor)
	{
		CameraSetIspOutFormat(m_hCamera, CAMERA_MEDIA_TYPE_MONO8);
	}

	CameraSetTriggerMode(m_hCamera, 1);

	CameraPlay(m_hCamera);

	return 0;
}

extern "C" __declspec(dllexport) int GetImage()
{
	tSdkFrameHead 	sFrameInfo;
	BYTE* pbyBuffer;
	CameraSdkStatus status;
	CameraSoftTrigger(m_hCamera);
	status = CameraGetImageBuffer(m_hCamera, &sFrameInfo, &pbyBuffer, 10000);
	if (status == CAMERA_STATUS_SUCCESS)
	{
		status = CameraImageProcess(m_hCamera, pbyBuffer, m_pFrameBuffer, &sFrameInfo); 
		status = CameraSaveImage(m_hCamera, (char*)"H:\\test.bmp", m_pFrameBuffer, &sFrameInfo, FILE_BMP, 100);  //no -22

		CameraReleaseImageBuffer(m_hCamera, pbyBuffer);
	}
	return status;
}

extern "C" __declspec(dllexport) int Reconnect()
{
	CameraSdkStatus status = CameraReConnect(m_hCamera);
	return status;
}

extern "C" __declspec(dllexport) int UninitCamera()
{
	CameraSdkStatus status = CameraUnInit(m_hCamera);
	CameraAlignFree(m_pFrameBuffer);
	return status;
}



再创建一个exe程序,用来调用创建的dll文件 。

创建,下一步选择基于对话框的项目,下一步后的打印相关的、COM相关的全部不用选择,其他的默认就可以。
拖拉一些控件到对话框窗口上,最终如下图

文件源码如下

MindVisionCallDlg.h: 头文件


#pragma once


// CMindVisionCallDlg 对话框
class CMindVisionCallDlg : public CDialogEx
{
// 构造
public:
	CMindVisionCallDlg(CWnd* pParent = nullptr);	// 标准构造函数

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_MINDVISIONCALL_DIALOG };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedBtnInit();
	afx_msg void OnBnClickedBtnReconn();
	afx_msg void OnBnClickedBtnGrab();
	afx_msg void OnClose();
	CStatic m_cPreview;
};

MindVisionCallDlg.cpp: 实现文件


#include "pch.h"
#include "framework.h"
#include "MindVisionCall.h"
#include "MindVisionCallDlg.h"
#include "afxdialogex.h"

#include "DllFunction.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

CMindVisionCallDlg::CMindVisionCallDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MINDVISIONCALL_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMindVisionCallDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_STATIC_PREVIEW, m_cPreview);
}

BEGIN_MESSAGE_MAP(CMindVisionCallDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN_INIT, &CMindVisionCallDlg::OnBnClickedBtnInit)
	ON_BN_CLICKED(IDC_BTN_RECONN, &CMindVisionCallDlg::OnBnClickedBtnReconn)
	ON_BN_CLICKED(IDC_BTN_GRAB, &CMindVisionCallDlg::OnBnClickedBtnGrab)
	ON_WM_CLOSE()
END_MESSAGE_MAP()

BOOL CMindVisionCallDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CMindVisionCallDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this);
		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

HCURSOR CMindVisionCallDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CMindVisionCallDlg::OnBnClickedBtnInit()
{
	int code = InitCamera(1);
	if (code)
	{

	}
	CString Info;
	Info.Format(_T("Result = %d"), code);
	SetDlgItemText(IDC_STC_INFO, Info);
}

void CMindVisionCallDlg::OnBnClickedBtnReconn()
{
	int code = Reconnect();
	if (code)
	{

	}
	CString Info;
	Info.Format(_T("Result = %d"), code);
	SetDlgItemText(IDC_STC_INFO, Info);
}

void CMindVisionCallDlg::OnBnClickedBtnGrab()
{
	int code = GetImage();
	if (0 == code)
	{
	
		CClientDC dc(this);
		CDC* mdc = new CDC;
		mdc->CreateCompatibleDC(&dc);
		CBitmap bitmap;
		bitmap.m_hObject = (HBITMAP)::LoadImageA(AfxGetInstanceHandle(), (char*)"H:\\test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

		mdc->SelectObject(bitmap);
		CRect rect;
		::GetWindowRect(m_cPreview.GetSafeHwnd(), &rect);
		ScreenToClient(&rect);

		BITMAP sBitMap;
		bitmap.GetBitmap(&sBitMap);
		dc.StretchBlt(rect.left, rect.top, rect.Width(), rect.Height(), mdc, 0, 0, sBitMap.bmWidth, sBitMap.bmHeight, SRCCOPY);

		delete mdc;
	}
	CString Info;
	Info.Format(_T("Result = %d"), code);
	SetDlgItemText(IDC_STC_INFO, Info);
}


void CMindVisionCallDlg::OnClose()
{
	int code = UninitCamera();
	if (code)
	{

	}
	CDialogEx::OnClose();
}

两个工程保存在同一个方案,然后建立项目依赖,如此就两个工程一起编译。

最后运行效果,

(本节结束)

标签:status,MD,MFC,int,hCamera,CMindVisionCallDlg,code,void,机库
From: https://blog.csdn.net/ljygood2/article/details/144011582

相关文章

  • 【高性能编程】SIMD类型指令基本概念与使用示例
    一、SIMD基本概念SIMD指令即单指令多数据流(SingleInstructionMultipleData)指令,是一种能够在同一时间同步执行同一条指令,以对多个数据元素进行并行处理的技术,以下是具体介绍:原理传统的单指令单数据(SISD)架构中,CPU需要分别访问内存以获取操作数,然后逐个进行运算。而SIM......
  • 高性能AMD香港服务器:卓越性能与优势完美结合
    高性能AMD香港鼎峰服务器:卓越性能与全面优势的完美结合在当今数字化时代,高性能服务器已成为企业和开发者不可或缺的重要工具。香港鼎峰服务器凭借其卓越的性能和全面的优势,在众多服务器提供商中脱颖而出,成为众多企业和开发者的首选。香港鼎峰服务器采用先进的硬件设施和高......
  • 网络安全-安全散列函数,信息摘要SHA-1,MD5原理
    安全散列函数     单向散列函数或者安全散列函数之所以重要,不仅在于消息认证(消息摘要。数据指纹)。还有数字签名(加强版的消息认证)和验证数据的完整性。常见的单向散列函数有MD5和SHA散列函数的要求    散列函数的目的是文件、消息或者其它数据块产生“指纹......
  • 【超详细】MDK工程模版
    MDK工程模版新建MDK工程文件夹采用分层的思想进行工程管理,目录结构如下:名称作用Drivers存放硬件相关的驱动文件Middlewares存放第三方中间文件Output存放工程输出的文件Projects存放MDK工程文件User存放HAL库用户配置文件、main.c、中断处理文件以及分散的启动加载文件Do......
  • cmd运行
    声明!学习视频来自B站up主泷羽sec有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关,切勿触碰法律底线,否则后果自负!!!!有兴趣的小伙伴可以点击下面连接进入b站主页B站泷......
  • P5572 [CmdOI2019] 简单的数论题 题解
    题目描述\(T\)组数据,给定\(n\gem\),求:\[\sum_{i=1}^n\sum_{j=1}^m\varphi(\frac{\text{lcm}(i,j)}{\gcd(i,j)})\\\]对\(23333\)取模。数据范围\(1\leT\le3\cdot10^4,1\lem\len\le5\cdot10^4\)。时间限制\(\texttt{2s}\),空间限制\(\texttt{128......
  • 高性能计算-ARM(neon)向量化优化(SIMD)和循环展开效率对(14)
    1.目标对数组求和,对比ARM(neon)向量化优化(SIMD)和循环展开,还有O0O1优化的效率对比。2.测试代码#include<arm_neon.h>#include<stdio.h>#include<stdlib.h>#include<time.h>#defineN1024000int32_tneonSum(int32_t*arr,intn){//保存计算元素向量......
  • KTL 一个支持C++14写公式的K线工具 - 0.9.2版,通达信mdt全景数据复盘大盘,Qt自定义图表
    K,K线,Candle蜡烛图。T,技术分析,工具平台L,公式Language语言使用c++14,Lite小巧简易。项目仓库:https://github.com/bbqz007/KTL    国内仓库:https://gitee.com/bbqz007/KTL 当前0.9.2新添加功能基于QCharts跟通达信mdt数据文件。使用者能够使用QCharts自定义数据处理图表。......
  • 在当前工作目录下,以管理员身份运行cmd(如何通过命令提升管理员权限?)
    思路一、听说cmder可以右键打开当前工作目录的命令窗口,不过我懒得安装验证了。思路二、我发现百度找到的教程都不真正满足我的需求,最后从一篇文章得到了启发。我整理了需求,提示AI生成bat脚本代码,代码微改后,在当前工作目录下,可以用管理员身份运行cmd。【前置知识】Windows环......
  • 【VMD-SSA-LSSVM】基于变分模态分解与麻雀优化Lssvm的负荷预测【多变量】(Matlab代码实
     ......