BYTE[]数组转化为灰度图像CBitimage显示到mfc窗口中(opencv结果在mfc中的显示)

2 篇文章 0 订阅
2 篇文章 0 订阅

     垂垂老矣的MFC让人又爱又恨,爱的是熟悉的套路和丰富的资源,恨的是他太复杂,杂,乱七八糟。如果你想快速的完成一项任务,用mfc是一个冒险的决定,因为你很有可能找不到你想要实现的功能的函数,源代码等等,你需要自己去写,更有甚者,你写都没法写,因为这里面封装太深,太杂乱,让你摸不着头。就有这样一件事一直困扰着我这个matlab爱好者,在matlab中,数组就是位图,位图就是数组,而到了mfc中,事情变得复杂了,如果你想把图像在两个体系里传递,除非已经有写好的接口,否则,靠自己来做,结果往往让人沮丧。比如opencv中的iplimage转为能在mfc中显示的cbitmap就是意见让人很费脑筋的事情,当然现在看来,在mfc体系内还有有办法完成这项工作的,那就是自己编写图像的头部,然后把数据写进去,这听起来确实很合理,但是,这其中的调试过程让人抓狂,而且还会造成很多莫名奇妙的错误,最终还是没法用。
      对于一般的图像来说,难点不是获取其内部的数据,因为这些已经被考虑到了,难点是在如何凭空(只有数据)创造出来一个图像,并显示出来,当然显示出来的前提就是规定格式,废话不多说,直接上代码。
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved

#pragma once
#include "stdafx.h"
// Modify the following definitions if you need to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER              // Allow use of features specific to Windows 7 or later.
#define WINVER 0x0700       // Change this to the appropriate value to target other versions of Windows.
#endif

#ifndef _WIN32_WINNT        // Allow use of features specific to Windows 7 or later.
#define _WIN32_WINNT 0x0700 // Change this to the appropriate value to target other versions of Windows.
#endif

#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN     // Exclude rarely-used items from Windows headers


// C RunTime Header Files


//#include "std.h"


/******************************************************************
*                                                                 *
*  Macros                                                         *
*                                                                 *
******************************************************************/
template<class Interface>
inline void
SafeRelease(
Interface **ppInterfaceToRelease
)
{
	if (*ppInterfaceToRelease != NULL)
	{
		(*ppInterfaceToRelease)->Release();

		(*ppInterfaceToRelease) = NULL;
	}
}
#ifndef Assert
#if defined( DEBUG ) || defined( _DEBUG )
#define Assert(b) if (!(b)) {OutputDebugStringA("Assert: " #b "\n");}
#else
#define Assert(b)
#endif //DEBUG || _DEBUG
#endif


#ifndef HINST_THISCOMPONENT
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
#endif

/******************************************************************
*                                                                 *
*  DemoApp                                                        *
*                                                                 *
******************************************************************/
class DemoApp
{
public:
	DemoApp();
	~DemoApp();

	// Register the window class and call methods for instantiating drawing resources
	HRESULT Initialize(HWND in_hwnd);

	// Process and dispatch messages
	void RunMessageLoop();
	// Draw content.
	HRESULT OnRender();
	BOOL CreateBitmpFromMemory(uchar * data, int w, int h, uint32_t pitch);
private:
	// Initialize device-independent resources.
	HRESULT CreateDeviceIndependentResources();

	// Initialize device-dependent resources.
	HRESULT CreateDeviceResources();

	// Release device-dependent resources.
	void DiscardDeviceResources();

	// Resize the render target.
	void OnResize(
		UINT width,
		UINT height
		);

	// The windows procedure
	static LRESULT CALLBACK WndProc(
		HWND hWnd,
		UINT message,
		WPARAM wParam,
		LPARAM lParam
		);

private:
	HWND m_hwnd;
	ID2D1Factory *m_pD2DFactory;
	ID2D1HwndRenderTarget *m_pRenderTarget;
	ID2D1SolidColorBrush *m_pBlackBrush;
	ID2D1Bitmap   * m_bitmap;

	ID2D1GdiInteropRenderTarget *m_pGDIRT;
};

上面是头文件,下面是实现文件。

 
 
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "stdafx.h"
#include "ldi_dril.h"


/******************************************************************
*                                                                 *
*  DemoApp::DemoApp constructor                                   *
*                                                                 *
*  Initialize member data.                                        *
*                                                                 *
******************************************************************/

DemoApp::DemoApp() :
m_hwnd(NULL),
m_pD2DFactory(NULL),
m_pRenderTarget(NULL),
m_pGDIRT(NULL),
m_pBlackBrush(NULL)
{
}

/******************************************************************
*                                                                 *
*  DemoApp::~DemoApp destructor                                   *
*                                                                 *
*  Release resources.                                             *
*                                                                 *
******************************************************************/

DemoApp::~DemoApp()
{
	SafeRelease(&m_pD2DFactory);
	SafeRelease(&m_pRenderTarget);
	SafeRelease(&m_pGDIRT);
	SafeRelease(&m_pBlackBrush);
}

/******************************************************************
*                                                                 *
*  DemoApp::Initialize                                            *
*                                                                 *
*  Create application window and device-independent resources.    *
*                                                                 *
******************************************************************/

HRESULT DemoApp::Initialize(HWND in_hwnd)
{
	HRESULT hr;
	m_hwnd = in_hwnd;
	// Initialize device-indpendent resources, such
	// as the Direct2D factory.
	hr = CreateDeviceIndependentResources();
	if (SUCCEEDED(hr))
	{
		hr = CreateDeviceResources();
	}
	return hr;
}

/******************************************************************
*                                                                 *
*  DemoApp::CreateDeviceIndependentResources                      *
*                                                                 *
*  This method is used to create resources which are not bound    *
*  to any device. Their lifetime effectively extends for the      *
*  duration of the app.                                           *
*                                                                 *
******************************************************************/

HRESULT DemoApp::CreateDeviceIndependentResources()
{
	HRESULT hr = S_OK;

	// Create a Direct2D factory.
	hr = D2D1CreateFactory(
		D2D1_FACTORY_TYPE_SINGLE_THREADED,
		&m_pD2DFactory
		);

	return hr;
}

/******************************************************************
*                                                                 *
*  DemoApp::CreateDeviceResources                                 *
*                                                                 *
*  This method creates resources which are bound to a particular  *
*  D3D device. It's all centralized here, in case the resources   *
*  need to be recreated in case of D3D device loss (eg. display   *
*  change, remoting, removal of video card, etc).                 *
*                                                                 *
******************************************************************/

HRESULT DemoApp::CreateDeviceResources()
{
	HRESULT hr = S_OK;
	if (!m_pRenderTarget)
	{
		RECT rc;
		GetClientRect(m_hwnd, &rc);

		D2D1_SIZE_U size = D2D1::SizeU(
			rc.right - rc.left,
			rc.bottom - rc.top
			);

		D2D1_RENDER_TARGET_PROPERTIES rtProps = D2D1::RenderTargetProperties();
		rtProps.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE;

		// Create a GDI compatible Hwnd render target.
		hr = m_pD2DFactory->CreateHwndRenderTarget(
			rtProps,
			D2D1::HwndRenderTargetProperties(m_hwnd, size),
			&m_pRenderTarget
			);


		if (SUCCEEDED(hr))
		{
			hr = m_pRenderTarget->QueryInterface(__uuidof(ID2D1GdiInteropRenderTarget), (void**)&m_pGDIRT);
		}
		if (SUCCEEDED(hr))
		{
			// Create a brush for drawing
			hr = m_pRenderTarget->CreateSolidColorBrush(
				D2D1::ColorF(D2D1::ColorF::Black),
				&m_pBlackBrush
				);
		}
	}
	return hr;
}


/******************************************************************
*                                                                 *
*  DemoApp::DiscardDeviceResources                                *
*                                                                 *
*  Discard device-specific resources which need to be recreated   *
*  when a Direct3D device is lost.                                *
*                                                                 *
******************************************************************/

void DemoApp::DiscardDeviceResources()
{
	SafeRelease(&m_pRenderTarget);
	SafeRelease(&m_pGDIRT);
	SafeRelease(&m_pBlackBrush);
}

/******************************************************************
*                                                                 *
*  DemoApp::RunMessageLoop                                        *
*                                                                 *
*  Main window message loop                                       *
*                                                                 *
******************************************************************/
void DemoApp::RunMessageLoop()
{
	MSG msg;

	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
}

/******************************************************************
*                                                                 *
*  DemoApp::OnRender                                              *
*                                                                 *
*  Called whenever the application needs to display the client    *
*  window.                                                        *
*  Note that this function will not render anything if the window *
*  is occluded (e.g. when the screen is locked).                  *
*  Also, this function will automatically discard device-specific *
*  resources if the Direct3D device disappears during function    *
*  invocation, and will recreate the resources the next time it's *
*  invoked.                                                       *
*                                                                 *
******************************************************************/
HRESULT DemoApp::OnRender()
{
	HRESULT hr=S_OK;
	if (SUCCEEDED(hr))
	{
		m_pRenderTarget->BeginDraw();

		// Reset to the identity transform.
		m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());

		// Clear the render target contents.
		m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));

		m_pRenderTarget->DrawEllipse(
			D2D1::Ellipse(
			D2D1::Point2F(150.0f, 150.0f),
			100.0f,
			100.0f),
			m_pBlackBrush,
			3.0
			);

		m_pRenderTarget->DrawLine(
			D2D1::Point2F(150.0f, 150.0f),
			D2D1::Point2F(
			(150.0f + 100.0f * 0.15425f),
			(150.0f - 100.0f * 0.988f)),
			m_pBlackBrush,
			3.0
			);

		m_pRenderTarget->DrawLine(
			D2D1::Point2F(150.0f, 150.0f),
			D2D1::Point2F(
			(150.0f + 100.0f * 0.525f),
			(150.0f + 100.0f * 0.8509f)),
			m_pBlackBrush,
			3.0
			);

		m_pRenderTarget->DrawLine(
			D2D1::Point2F(150.0f, 150.0f),
			D2D1::Point2F(
			(150.0f - 100.0f * 0.988f),
			(150.0f - 100.0f * 0.15425f)),
			m_pBlackBrush,
			3.0
			);
		uchar m_src[128 * 96 * 4];
		for (int i = 0; i < 128 * 96; i++)
		{
			m_src[i * 4 + 0] = 0;
			m_src[i * 4 + 1] = 255;
			m_src[i * 4 + 2] = 255;
			m_src[i * 4 + 3] = 1;
		}
			
		CreateBitmpFromMemory(m_src, 128, 96, 512);
		D2D1_RECT_F rectangle1 = D2D1::RectF(
			128,
			96,
			256,
			192
			);
		D2D1_RECT_F rectangle2 = D2D1::RectF(
			0,
			0,
			128,
			96
			);
		m_pRenderTarget->DrawBitmap(m_bitmap, &rectangle1, 1, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, &rectangle2);

		m_pRenderTarget->EndDraw();

		if (hr == D2DERR_RECREATE_TARGET)
		{
			hr = S_OK;
			DiscardDeviceResources();
		}
	}
	return hr;
}

//                      tranform function

BOOL DemoApp::CreateBitmpFromMemory(uchar * data, int w, int h, uint32_t pitch)
{
	HRESULT hr = S_OK;
	D2D1_SIZE_U size;
	size.width = w;
	size.height = h;

	// Create a pixel format and initial its format
	// and alphaMode fields.
	//指定RGB格式
	D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat(
		DXGI_FORMAT_B8G8R8A8_UNORM,
		D2D1_ALPHA_MODE_IGNORE
		);
	//设置属性
	D2D1_BITMAP_PROPERTIES property;
	property.pixelFormat = pixelFormat;
	property.dpiX = 0;
	property.dpiY = 0;
	// Create a Direct2D bitmap from the memory.
	hr = m_pRenderTarget->CreateBitmap(
		size,
		data,
		pitch,
		property,
		&m_bitmap
		);
	if (SUCCEEDED(hr))
	{
		return TRUE;
	}
	return FALSE;
}



下面是mfc winform的代码,基本没变化
头文件:
#pragma once
#include "afxwin.h"
#include "ldi_dril.h"
class CMFandopencvDlgAutoProxy;


// CMFandopencvDlg 对话框
class CMFandopencvDlg : public CDialogEx
{
	DECLARE_DYNAMIC(CMFandopencvDlg);
	friend class CMFandopencvDlgAutoProxy;

// 构造
public:
	CMFandopencvDlg(CWnd* pParent = NULL);	// 标准构造函数
	virtual ~CMFandopencvDlg();

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

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


// 实现
protected:
	CMFandopencvDlgAutoProxy* m_pAutoProxy;
	HICON m_hIcon;
	BOOL CanExit();
	DemoApp m_translator;
	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	afx_msg void OnClose();
	virtual void OnOK();
	virtual void OnCancel();
	DECLARE_MESSAGE_MAP()
public:
//	CStatic pic_ctr;
	afx_msg void OnBnClickedButton1();
};

下面是实现文件

// MFandopencvDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "MFandopencv.h"
#include "MFandopencvDlg.h"
#include "DlgProxy.h"
#include "afxdialogex.h"



#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 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()


// CMFandopencvDlg 对话框


IMPLEMENT_DYNAMIC(CMFandopencvDlg, CDialogEx);

CMFandopencvDlg::CMFandopencvDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CMFandopencvDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_pAutoProxy = NULL;
}

CMFandopencvDlg::~CMFandopencvDlg()
{
	// 如果该对话框有自动化代理,则
	//  将此代理指向该对话框的后向指针设置为 NULL,以便
	//  此代理知道该对话框已被删除。
	if (m_pAutoProxy != NULL)
		m_pAutoProxy->m_pDialog = NULL;
}

void CMFandopencvDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	//DDX_Control(pDX, IDC_PICTRUE_CTR0, pic_ctr);
}

BEGIN_MESSAGE_MAP(CMFandopencvDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_CLOSE()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, &CMFandopencvDlg::OnBnClickedButton1)
END_MESSAGE_MAP()


// CMFandopencvDlg 消息处理程序

BOOL CMFandopencvDlg::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:  在此添加额外的初始化代码
	m_translator.Initialize(m_hWnd);//初始化函数
	
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

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

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

void CMFandopencvDlg::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();
		m_translator.OnRender();
		//hdc = BeginPaint(hWnd, &ps);  
		
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMFandopencvDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

// 当用户关闭 UI 时,如果控制器仍保持着它的某个
//  对象,则自动化服务器不应退出。  这些
//  消息处理程序确保如下情形: 如果代理仍在使用,
//  则将隐藏 UI;但是在关闭对话框时,
//  对话框仍然会保留在那里。

void CMFandopencvDlg::OnClose()
{
	if (CanExit())
		CDialogEx::OnClose();
}

void CMFandopencvDlg::OnOK()
{
	if (CanExit())
		CDialogEx::OnOK();
}

void CMFandopencvDlg::OnCancel()
{
	if (CanExit())
		CDialogEx::OnCancel();
}

BOOL CMFandopencvDlg::CanExit()
{
	// 如果代理对象仍保留在那里,则自动化
	//  控制器仍会保持此应用程序。
	//  使对话框保留在那里,但将其 UI 隐藏起来。
	if (m_pAutoProxy != NULL)
	{
		ShowWindow(SW_HIDE);
		return FALSE;
	}

	return TRUE;
}



void CMFandopencvDlg::OnBnClickedButton1()
{
	
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值