windows下如何实现,写出具体的代码,并分为.h文件和.cpp文件
时间: 2024-03-10 14:43:53 浏览: 61
在 Windows 平台下,可以使用 Win32 API 或者 MFC(Microsoft Foundation Classes)等框架来显示图像窗口。以下是一个使用 Win32 API 的示例代码,可以在 Visual Studio 中编译运行。
首先,我们创建一个名为 `image_viewer.h` 的头文件,用于声明图像查看器的类和成员函数。代码如下:
```c++
#pragma once
#include <Windows.h>
#include <opencv2/opencv.hpp>
class ImageViewer
{
public:
ImageViewer();
~ImageViewer();
void Init(const char* title, int width, int height);
void ShowImage(const cv::Mat& image);
void WaitKey(int delay);
private:
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
private:
HWND m_hWnd;
HDC m_hDC;
HBITMAP m_hBitmap;
cv::Mat m_Image;
};
```
在这个头文件中,我们声明了一个名为 `ImageViewer` 的类,用于显示图像窗口。这个类中包含了图像窗口的初始化、图像显示、等待按键等功能。其中,`Init()`函数用于初始化图像窗口,`ShowImage()`函数用于显示图像,`WaitKey()`函数用于等待按键。我们还声明了一个名为 `WndProc()` 的静态成员函数,用于处理图像窗口的消息。
接下来,我们创建一个名为 `image_viewer.cpp` 的源文件,用于实现 `ImageViewer` 类中的成员函数。代码如下:
```c++
#include "image_viewer.h"
ImageViewer::ImageViewer()
: m_hWnd(nullptr), m_hDC(nullptr), m_hBitmap(nullptr)
{
}
ImageViewer::~ImageViewer()
{
if (m_hBitmap)
DeleteObject(m_hBitmap);
if (m_hDC)
ReleaseDC(m_hWnd, m_hDC);
if (m_hWnd)
DestroyWindow(m_hWnd);
}
void ImageViewer::Init(const char* title, int width, int height)
{
// 创建窗口类
WNDCLASS wc = {};
wc.lpfnWndProc = WndProc;
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = "ImageViewer";
RegisterClass(&wc);
// 创建窗口
m_hWnd = CreateWindow("ImageViewer", title, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, width, height, NULL, NULL, GetModuleHandle(NULL), this);
ShowWindow(m_hWnd, SW_SHOW);
UpdateWindow(m_hWnd);
// 创建位图
m_hDC = GetDC(m_hWnd);
m_hBitmap = CreateCompatibleBitmap(m_hDC, width, height);
}
void ImageViewer::ShowImage(const cv::Mat& image)
{
// 将图像数据复制到位图中
m_Image = image.clone();
cv::cvtColor(m_Image, m_Image, cv::COLOR_BGR2RGB);
BITMAPINFO bmpInfo = { sizeof(BITMAPINFOHEADER), m_Image.cols, -m_Image.rows, 1, 24, BI_RGB, 0, 0, 0, 0, };
SetDIBits(m_hDC, m_hBitmap, 0, m_Image.rows, m_Image.data, &bmpInfo, DIB_RGB_COLORS);
// 显示位图
HDC hMemDC = CreateCompatibleDC(m_hDC);
HGDIOBJ hOldBitmap = SelectObject(hMemDC, m_hBitmap);
BitBlt(m_hDC, 0, 0, m_Image.cols, m_Image.rows, hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldBitmap);
DeleteDC(hMemDC);
}
void ImageViewer::WaitKey(int delay)
{
MSG msg = {};
while (true)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Sleep(delay);
}
}
}
LRESULT CALLBACK ImageViewer::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
ImageViewer* pViewer = NULL;
if (message == WM_CREATE)
{
pViewer = (ImageViewer*)((LPCREATESTRUCT)lParam)->lpCreateParams;
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pViewer);
return DefWindowProc(hWnd, message, wParam, lParam);
}
else
{
pViewer = (ImageViewer*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
}
switch (message)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
if (pViewer->m_hBitmap)
{
HDC hMemDC = CreateCompatibleDC(hdc);
HGDIOBJ hOldBitmap = SelectObject(hMemDC, pViewer->m_hBitmap);
BitBlt(hdc, 0, 0, pViewer->m_Image.cols, pViewer->m_Image.rows, hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldBitmap);
DeleteDC(hMemDC);
}
EndPaint(hWnd, &ps);
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
```
在这个源文件中,我们实现了 `ImageViewer` 类中的三个成员函数:`Init()`、`ShowImage()` 和 `WaitKey()`。其中,`Init()`函数用于创建图像窗口和位图,`ShowImage()`函数用于将图像数据显示在位图中,`WaitKey()`函数用于等待按键事件。我们还实现了一个名为 `WndProc()` 的静态成员函数,用于处理图像窗口的消息。
最后,我们可以在主函数中使用 `ImageViewer` 类来显示图像窗口。以下是一个使用 `ImageViewer` 类的示例代码:
```c++
#include "image_viewer.h"
int main()
{
cv::Mat image = cv::imread("test.jpg");
ImageViewer viewer;
viewer.Init("Image Viewer", image.cols, image.rows);
viewer.ShowImage(image);
viewer.WaitKey(1);
return 0;
}
```
在这个示例代码中,我们先加载一张图像,并创建一个 `ImageViewer` 对象。然后使用 `Init()` 函数初始化图像窗口,使用 `ShowImage()` 函数将图像数据显示在窗口中,使用 `WaitKey()` 函数等待按键事件。这样可以在图像窗口中显示图像,并等待按键事件。
阅读全文