关闭

MFC调用摄像头拍照,通过curl把图片传给java后台

标签: mfcCurl json C++图片摄像头Java
581人阅读 评论(0) 收藏 举报
分类:

接着上一篇博客的背景。

现在需要实现的功能是,在前端MFC上进行拍照并显示,之后把图片传给后台。

首先第一个部分是拍照的实现,通过百度,发现大家都是在使用opencv这个插件,容易实现。

(一)VS2010配置openCV(这个配置好麻烦)

      参考的链接: http://johnhany.net/2013/11/environment-for-opencv-with-vs2010/

     (1)下载安装openCV

         下载到的文件名为“opencv-2.4.9.exe”,是个自解压文件,大小350MB左右.官网或者我发的链接 (资源统一在后面)

           下载好之后,解压到任意一个文件夹,比如“E:\softwares

    (2)环境变量的配置

     

       OpenCV库函数需要通过用户环境变量调用所需要的库文件。点击:开始->计算机(右击)->属性->高级系统设置->高级->环境    变量,在用户变量里增加一项:

                变量名:path

                变量值:E:\softwares\opencv\build\x86\vc10\bin

        如果已经有path项,在其变量值结尾添加英文分号“;”,再加上上面那个值。

        这里的“x86”代表目标程序是32位的,如果要写64位的程序则选择“x64”文件夹。并不是根据开发环境(你的机器)选择的。

        后面的“vc10”代表使用Visual C++ 2010开发。如果使用Visual Studio 2012,则填写“E:\softwares\opencv\build\x86\vc11\bin”。

    注销用户,重新登录Windows,保证环境变量更新并起作用。

(3)在VS2010中配置

在Solution Explorer中右击工程名,选择Properties。

new-proj-4

        在弹出的窗口“OpencvTest Property Pages中,Configuration选择“Debug”(或者默认的“Active(Debug)”),Platform选择“Win32”。在左边选择Configuration Properties->VC++ Directories,在右边的General中编辑Include Directories,增加以下三项:

                E:\softwares\opencv\build\include

                E:\softwares\opencv\build\include\opencv

                E:\softwares\opencv\build\include\opencv2

其实只需要填入第一行即可。由于“include\opencv”包含C版本的头文件,“include\opencv2”包含C++版本的头文件。所以编写代码时,在头文件名称前加上“opencv/”或“opencv2/”来区分两种版本。

Library Directories中增加以下一项:

                E:\softwares\opencv\build\x86\vc10\lib

 把Configuration改为“Release”,然后对Include DirectoriesLibrary Directories做同样的修改。如果只写练习程序,只用debug功能,那么“Release”可以不用修改。如果使用Visual Studio 2012,则填写“E:\softwares\opencv\build\x86\vc11\lib”。

        仍然在“OpencvTest Property Pages”窗口下,Configuration选择“Debug”。在左边选择Configuration Properites->Linker->Input,在右面编辑Additional Dependencies,增加以下若干项(可以根据自己的需要适当删减,关于各个模块的功能,请参考这里):

                 opencv_calib3d249d.lib
                opencv_contrib249d.lib
                opencv_core249d.lib
                opencv_features2d249d.lib
                opencv_flann249d.lib
                opencv_gpu249d.lib
                opencv_highgui249d.lib
                opencv_imgproc249d.lib
                opencv_legacy249d.lib
                opencv_ml249d.lib
                opencv_objdetect249d.lib
                opencv_ts249d.lib
                opencv_video249d.lib

(同样,如果仅使用debug模式,这一步可以跳过)把Configuration改为“Release”,在Additional Dependencies增加以下若干项(在文件名上的区别仅在于在末尾少了一个“d”):

                 opencv_calib3d249.lib
                opencv_contrib249.lib
                opencv_core249.lib
                opencv_features2d249.lib
                opencv_flann249.lib
                opencv_gpu249.lib
                opencv_highgui249.lib
                opencv_imgproc249.lib
                opencv_legacy249.lib
                opencv_ml249.lib
                opencv_objdetect249.lib
                opencv_ts249.lib
                opencv_video249.lib

至此 opencv配置好了,可以使用了。

(二)实现拍照功能

主要是在网上找的资源进行整合的,本人对C++不是很会,所以不会讲解原理,只讲实现。
(1)界面部分
  需要添加两个Picture Control 控件,三个button按钮。按钮添加三个点击事件,分别对应打开摄像头,关闭摄像头和拍照。
(2)CvvImage.h和CvvImage.cpp文件
需要导入这两个文件,网上可以找到
(3)添加三个点击事件的方法,同时添加一个定时器方法,用来拍照功能。
(4)注意整个工程的控件ID必须是对应的
具体的请看代码

(三)图片显示

这个需要注意的就是图片路径
(四)图片上传
这个是通过前面学习的Curl的post方法传输的
具体请看代码中的http_post_file
int http_post_file(const char *url, const char *filename)
{
    CURL *curl = NULL;
    CURLcode res;

      struct curl_httppost *post=NULL;
      struct curl_httppost *last=NULL;
      struct curl_slist *headerlist=NULL;

	  static const char buf[] = "Expect:";

    if(filename == NULL || url == NULL)
        return -1;

    printf("URL: %s\n", url);
    printf("filename: %s\n", filename);

    /* Add simple file section */
    if( curl_formadd(&post, &last, CURLFORM_COPYNAME, "file",
               CURLFORM_FILE, filename, CURLFORM_END) != 0)
    {
        fprintf(stderr, "curl_formadd error.\n");
        return -1;
    }
    
      /* Fill in the submit field too, even if this is rarely needed */
      curl_formadd(&post, &last,
               CURLFORM_COPYNAME, "submit",
               CURLFORM_COPYCONTENTS, "OK",
               CURLFORM_END);


	  //headerlist = curl_slist_append(headerlist, "Accept-Encoding:UTF-8");  
        //headerlist = curl_slist_append(headerlist, "Content-type: application/form-data;charset:UTF-8");  
     headerlist = curl_slist_append(headerlist, buf); 

    //curl_global_init(CURL_GLOBAL_ALL);
    curl = curl_easy_init();
    if(curl == NULL)
    {
        fprintf(stderr, "curl_easy_init() error.\n");
		curl_formfree(post);
        return -1;
    }

    curl_easy_setopt(curl, CURLOPT_HEADER, 0);
    curl_easy_setopt(curl, CURLOPT_URL, url); /*Set URL*/
    curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
    int timeout = 5;
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1);

    res = curl_easy_perform(curl);
    if(res != CURLE_OK)
    {
        fprintf(stderr, "curl_easy_perform[%d] error.\n", res);
		curl_formfree(post);
        return -1;
    }

    curl_easy_cleanup(curl);    

    return 0;
}
在实现中,headlist必须有,这个是post的头,没有无法实现上传图片

展示一下代码
TestDlg.h
// TestCurlJsonDlg.h : 头文件
//
#include "CvvImage.h"
#include "opencv/cv.h"
#include "opencv/highgui.h"

#pragma once


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

// 对话框数据
	enum { IDD = IDD_TESTCURLJSON_DIALOG };

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


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();

	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedButton1();
	char m_showDate;
	char m_show2;
	CString m_show;
	afx_msg void OnTimer(UINT_PTR nIDEvent);
	afx_msg void OnBnClickedButton2();
	afx_msg void OnBnClickedButton3();
	afx_msg void OnBnClickedButton4();
	afx_msg void OnBnClickedButton5();
};
cpp文件
// TestCurlJsonDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "TestCurlJson.h"
#include "TestCurlJsonDlg.h"
#include "afxdialogex.h"

//#include<iostream>

//curl添加
#include "curl/curl.h"
#include <string>

#include <sys/stat.h>
#include <fcntl.h>

#pragma comment(lib, "libcurld_imp.lib") 

//json
#include "json\json.h" 
#pragma comment(lib,"json_vc71_libmtd.lib")






#ifdef _DEBUG
#define new DEBUG_NEW
#endif

//opencv 全局变量
CvCapture* capture;
CRect rect;
CDC *pDC;
HDC hDC;
CWnd *pwnd;


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 对话框数据
	enum { IDD = IDD_ABOUTBOX };

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

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{	
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CTestCurlJsonDlg 对话框




CTestCurlJsonDlg::CTestCurlJsonDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CTestCurlJsonDlg::IDD, pParent)
	, m_show(_T(""))
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CTestCurlJsonDlg::DoDataExchange(CDataExchange* pDX)
{
	// 处理MFC默认的数据交换 
	CDialogEx::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_EDIT1, m_show);
}

BEGIN_MESSAGE_MAP(CTestCurlJsonDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_BUTTON1, &CTestCurlJsonDlg::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON2, &CTestCurlJsonDlg::OnBnClickedButton2)
	ON_BN_CLICKED(IDC_BUTTON3, &CTestCurlJsonDlg::OnBnClickedButton3)
	ON_BN_CLICKED(IDC_BUTTON4, &CTestCurlJsonDlg::OnBnClickedButton4)
	ON_BN_CLICKED(IDC_BUTTON5, &CTestCurlJsonDlg::OnBnClickedButton5)


END_MESSAGE_MAP()


// CTestCurlJsonDlg 消息处理程序

BOOL CTestCurlJsonDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	
	// TODO: 在此添加额外的初始化代码
	pwnd = GetDlgItem(IDB_BITMAP1);
	//pwnd->MoveWindow(35,30,352,288);
	pDC =pwnd->GetDC();
	//pDC =GetDC();
	hDC= pDC->GetSafeHdc();
	pwnd->GetClientRect(&rect);

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

void CTestCurlJsonDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CTestCurlJsonDlg::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 CTestCurlJsonDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


void CTestCurlJsonDlg::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: Add your message handler code here and/or call default
	/************************************************************************/
	/* 显示摄像头                                                           */
	/************************************************************************/
	IplImage* m_Frame;
	m_Frame=cvQueryFrame(capture);
	CvvImage m_CvvImage;
	m_CvvImage.CopyOf(m_Frame,1);	
	if (true)
	{
		m_CvvImage.DrawToHDC(hDC, &rect);
		//cvWaitKey(10);
	}


	CDialog::OnTimer(nIDEvent);
}


//curl回调方法
size_t http_data_writer(void* data, size_t size, size_t nmemb, void* content)  
{  
    long totalSize = size*nmemb;  
    std::string* symbolBuffer = (std::string*)content;  
    if(symbolBuffer)  
    {  
        symbolBuffer->append((char *)data, ((char*)data)+totalSize);  
    }  
    return totalSize;  
}


//转换格式
wchar_t* ConvertUtf8ToUnicode(const char* utf8)
{
	if(!utf8)
	{
		wchar_t* buf = (wchar_t*)malloc(2);
		memset(buf,0,2);
		return buf;
	}
	int nLen = ::MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,(LPCSTR)utf8,-1,NULL,0);
	//返回需要的unicode长度  
	WCHAR * wszUNICODE = new WCHAR[nLen+1];  
	memset(wszUNICODE, 0, nLen * 2 + 2);  
	nLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)utf8, -1, wszUNICODE, nLen);    //把utf8转成unicode
	return wszUNICODE;
}

std::string wstring2string(const std::wstring & wstr)
{
   std::string str("");
   int nLen = WideCharToMultiByte(CP_ACP,0,(LPCWSTR)wstr.c_str(),(int)wstr.length(),NULL,0,NULL,NULL);
   if(nLen <= 0) {return str;}
   str.resize(nLen,'\0');
   WideCharToMultiByte(CP_ACP,0,(LPCWSTR)wstr.c_str(),(int)wstr.length(),(LPSTR)str.c_str(),nLen,NULL,NULL);
   return str ;
}

std::wstring string2wstring(const std::string & str)
{
   std::wstring wstr(L"");
   int nLen = MultiByteToWideChar(CP_ACP,0,(LPCSTR)str.c_str(),(int)str.length(),0,0);
   if(nLen <= 0){return wstr;}
   wstr.resize(nLen,L'\0');
   MultiByteToWideChar(CP_ACP,0,(LPCSTR)str.c_str(),(int)str.length(),(LPWSTR)wstr.c_str(),nLen);
   return wstr;
}

std::string U2Utf(const std::wstring& wstrUnicode)//Unicode转utf8    
{    
    std::string strRet;
    if( wstrUnicode.empty() )  
        return strRet; 
    int nLen = WideCharToMultiByte(CP_UTF8, 0, wstrUnicode.c_str(), -1, NULL, 0, NULL, NULL);    
    char* pBuffer=new char[nLen+1];  
    pBuffer[nLen] = '\0';  
    nLen = WideCharToMultiByte(CP_UTF8, 0, wstrUnicode.c_str(), -1, pBuffer, nLen, NULL, NULL);   
    strRet.append(pBuffer);  
    delete[] pBuffer;  
    return strRet;    
}  


void CTestCurlJsonDlg::OnBnClickedButton1()
{
	//已实现传递和调用参数
    CURL *curl;
    CURLcode code;  
    curl = curl_easy_init();

	 if (curl)
     {
			curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.116:8080/TianMen/PushExitMessageAction!test.action");   // 指定url
			std::string licenstr = "licensePlate=鄂A123456&driverName=张三"; 
			//const char* licenChar = licenstr.c_str();
			std::wstring licenwstr = string2wstring(licenstr);
			licenstr = U2Utf(licenwstr);
			//std::string canshu = licenstr;
			curl_easy_setopt(curl, CURLOPT_POSTFIELDS, licenstr.c_str());	   //传递参数 参数必须是const char*	
			//curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "licensePlate=abcd123");	   //传递参数
			curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_data_writer);   //回调函数
			//设置写数据 回调函数必须有 
			std::string strData;  
			curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&strData);  
			// 执行请求  
			code = curl_easy_perform(curl); 
			if(code == CURLcode::CURLE_OK)  
			{  
					UpdateData(TRUE);				    
					std::string result;
				    long responseCode = 0;  
					curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);  
					if (responseCode < 200 || responseCode >= 300 || strData.empty()) { curl_easy_cleanup(curl);return ; }  
					const char *p=strData.data();
					WCHAR *p_new = ConvertUtf8ToUnicode(p);
					std::string p_str = wstring2string(p_new);

					Json::Reader reader;//json解析  
                    Json::Value value;//表示一个json格式的对象
					
					if(reader.parse(p_str,value))//解析出json放到json中区  
						{  
							std::string total=value["total"].asString(); 
							std::string out;
							result.append(value["licensePlate"].asString()+"\n");
							result.append(value["driverName"].asString()+"\n");
							//std::cout<<total<<std::endl;  
							const Json::Value arrayObj=value["rows"];//迭代器  
							
							for (int i=0; i < arrayObj.size();i++)    
							{  
								out=arrayObj[i]["shiftNumber"].asString(); 
								   	  
	                             //m_show = out;  
								//m_show = out.c_str();
								result.append(out);

							}  
						} 
					    m_show = result.c_str();
					   UpdateData(FALSE); 

					 getchar();  
						
			}
	  }
	  curl_easy_cleanup(curl);
}

int http_post_file(const char *url, const char *filename)
{
    CURL *curl = NULL;
    CURLcode res;

      struct curl_httppost *post=NULL;
      struct curl_httppost *last=NULL;
      struct curl_slist *headerlist=NULL;

	  static const char buf[] = "Expect:";

    if(filename == NULL || url == NULL)
        return -1;

    printf("URL: %s\n", url);
    printf("filename: %s\n", filename);

    /* Add simple file section */
    if( curl_formadd(&post, &last, CURLFORM_COPYNAME, "file",
               CURLFORM_FILE, filename, CURLFORM_END) != 0)
    {
        fprintf(stderr, "curl_formadd error.\n");
        return -1;
    }
    
      /* Fill in the submit field too, even if this is rarely needed */
      curl_formadd(&post, &last,
               CURLFORM_COPYNAME, "submit",
               CURLFORM_COPYCONTENTS, "OK",
               CURLFORM_END);


	  //headerlist = curl_slist_append(headerlist, "Accept-Encoding:UTF-8");  
        //headerlist = curl_slist_append(headerlist, "Content-type: application/form-data;charset:UTF-8");  
     headerlist = curl_slist_append(headerlist, buf); 

    //curl_global_init(CURL_GLOBAL_ALL);
    curl = curl_easy_init();
    if(curl == NULL)
    {
        fprintf(stderr, "curl_easy_init() error.\n");
		curl_formfree(post);
        return -1;
    }

    curl_easy_setopt(curl, CURLOPT_HEADER, 0);
    curl_easy_setopt(curl, CURLOPT_URL, url); /*Set URL*/
    curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
    int timeout = 5;
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1);

    res = curl_easy_perform(curl);
    if(res != CURLE_OK)
    {
        fprintf(stderr, "curl_easy_perform[%d] error.\n", res);
		curl_formfree(post);
        return -1;
    }

    curl_easy_cleanup(curl);    

    return 0;
}

void CTestCurlJsonDlg::OnBnClickedButton2()
{
	// TODO: 在此添加控件通知处理程序代码
	//char sFilePath[128]="d:\\abc\1.bmp";
	//const char * localfile = "F:\\abc\\123456ab.bmp";
	const char * localfile = "C:/Users/admin/Documents/Visual Studio 2010/Projects/TestCurlJson/TestCurlJson/1123.bmp";
	 //POST File
    http_post_file("http://192.168.0.116:8080/TianMen/UploadFile.servlet", localfile);

	getchar();

}

void CTestCurlJsonDlg::OnBnClickedButton3()
{
	// TODO: 在此添加控件通知处理程序代码
	if(!capture)
	{
		capture = cvCaptureFromCAM(0);
		//AfxMessageBox("OK");
	}

	if (!capture)
	{
		//AfxMessageBox("无法打开摄像头");
		return;
	}

	// 测试
	IplImage* m_Frame;
	m_Frame=cvQueryFrame(capture);
	CvvImage m_CvvImage;
	m_CvvImage.CopyOf(m_Frame,1);	
	if (true)
	{
		m_CvvImage.DrawToHDC(hDC, &rect);
		//cvWaitKey(10);
	}

	// 设置计时器,每10ms触发一次事件
	SetTimer(1,10,NULL);
}


void CTestCurlJsonDlg::OnBnClickedButton4()
{
	// TODO: 在此添加控件通知处理程序代码
	cvReleaseCapture(&capture);
	CDC MemDC; 
	CBitmap m_Bitmap1;
	m_Bitmap1.LoadBitmap(IDB_BITMAP1); 
	MemDC.CreateCompatibleDC(NULL);
	MemDC.SelectObject(&m_Bitmap1);
	pDC->StretchBlt(rect.left,rect.top,rect.Width(),rect.Height(),&MemDC,0,0,48,48,SRCCOPY); 
}


void CTestCurlJsonDlg::OnBnClickedButton5()
{
	// TODO: 在此添加控件通知处理程序代码
	 if (!capture)
		return;

	IplImage * m_GrabFrame=cvQueryFrame(capture);
	if (!m_GrabFrame)
		return;

	/*static	char countsnap='1';
	CString   m_name="";
	m_name=+countsnap;
	m_name+=".bmp";  */
	
	IplImage * m_snap=cvCreateImage(cvGetSize(m_GrabFrame),m_GrabFrame->depth,m_GrabFrame->nChannels);
	cvCopy(m_GrabFrame,m_snap,NULL);

	const char* pFileName = "1123.bmp";
	cvSaveImage(pFileName,m_snap);	//把图像写入文件

    //CString BmpName = dlg.GetPathName();     //获取文件路径名   如   D:\pic\abc.bmp  路径
	std::string fileName(pFileName);
	std::string fileRoad = "C:/Users/admin/Documents/Visual Studio 2010/Projects/TestCurlJson/TestCurlJson/"+fileName;
	CString BmpName = string2wstring(fileRoad).c_str();
    //CString EntName = dlg.GetFileExt();      //获取文件扩展名                        bmp

      //定义变量存储图片信息
      BITMAPINFO *pBmpInfo;       //记录图像细节
      BYTE *pBmpData;             //图像数据
      BITMAPFILEHEADER bmpHeader; //文件头
      BITMAPINFOHEADER bmpInfo;   //信息头
      CFile bmpFile;              //记录打开文件

      //以只读的方式打开文件 读取bmp图片各部分 bmp文件头 信息 数据
      if(!bmpFile.Open(BmpName, CFile::modeRead|CFile::typeBinary)) 
        return;
      if (bmpFile.Read(&bmpHeader,sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER))
        return;
      if (bmpFile.Read(&bmpInfo,sizeof(BITMAPINFOHEADER)) != sizeof(BITMAPINFOHEADER))
        return;
      pBmpInfo = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER)];
      //为图像数据申请空间
      memcpy(pBmpInfo,&bmpInfo,sizeof(BITMAPINFOHEADER));
      DWORD dataBytes = bmpHeader.bfSize - bmpHeader.bfOffBits;
      pBmpData = (BYTE*)new char[dataBytes];
      bmpFile.Read(pBmpData,dataBytes);
      bmpFile.Close();

      //显示图像
      CWnd *pWnd=GetDlgItem(IDC_SHOW); //获得pictrue控件窗口的句柄
      CRect rect;
      pWnd->GetClientRect(&rect); //获得pictrue控件所在的矩形区域
      CDC *pDC=pWnd->GetDC(); //获得pictrue控件的DC
      pDC->SetStretchBltMode(COLORONCOLOR);
      StretchDIBits(pDC->GetSafeHdc(),0,0,rect.Width(),rect.Height(),0,0,
      bmpInfo.biWidth,bmpInfo.biHeight,pBmpData,pBmpInfo,DIB_RGB_COLORS,SRCCOPY);

}
最后,展示一下效果












       

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:6196次
    • 积分:197
    • 等级:
    • 排名:千里之外
    • 原创:14篇
    • 转载:0篇
    • 译文:0篇
    • 评论:3条
    最新评论