C语言 如何在openCV的全屏无边框窗口中显示图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6512094/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 09:01:39  来源:igfitidea点击:

How to display an image in full screen borderless window in openCV

cimagewinapiopencv

提问by DanielHsH

I want to display an image in OpenCV in a full screen borderless window. In other words, only the image pixels will appear, without menu, toolbar, or window background.

我想在全屏无边框窗口中显示 OpenCV 中的图像。换句话说,只会出现图像像素,而不会出现菜单、工具栏或窗口背景。

Using imshow()or cvShowImage()don't enable it:

使用imshow()cvShowImage()不启用它:

  1. The window grows to be full screen in width but not in height. It misses few pixels.
  2. I could not make it borderless even by changing settings of window handler.
  1. 窗口在宽度上增长到全屏,但在高度上没有增长。它错过了几个像素。
  2. 即使通过更改窗口处理程序的设置,我也无法使其无边框。

I think that the problem is rooted in cvNamedWindow()method which creates main WS_OVERLAPPEDwindow, then creates a child and all functions like imshow()or cvGetWindowHandle()operate on the child.

我认为问题的根源在于cvNamedWindow()创建主WS_OVERLAPPED窗口的方法,然后创建一个子窗口以及所有类似imshow()cvGetWindowHandle()操作子窗口的函数。

Thus even windows command:

因此,即使是 windows 命令:

SetWindowLong((HWND)cvGetWindowHandle(winName), GWL_STYLE, WS_VISIBLE | WS_EX_TOPMOST | WS_POPUP);

Doesnt help, since the child cannot become borderless WS_POPUP. Someone got a workaround?

没有帮助,因为孩子不能成为无国界的WS_POPUP。有人有解决方法吗?

  • Maybe, showing opencv mat to window without using opencv built in methods
  • Or some kind of windows trick
  • 也许,在不使用 opencv 内置方法的情况下向窗口显示 opencv mat
  • 或者某种窗户技巧

P.S. I tried the following code:

PS我尝试了以下代码:

cvMoveWindow("AAA",0,0);
cvSetWindowProperty("AAA", CV_WINDOW_FULLSCREEN, CV_WINDOW_FULLSCREEN);

// Also I tried this:
HWND hwnd = (HWND)cvGetWindowHandle("AAA");
RECT windowRect;
windowRect.left = 0;
windowRect.top = 0;
windowRect.right = cxScreen; //Display resolution
windowRect.bottom = cyScreen; //Display resolution
AdjustWindowRect(&windowRect,WS_VISIBLE,false);
long p_OldWindowStyle = SetWindowLongPtr(hwnd,GWL_STYLE,WS_POPUP);
SetWindowPos(hwnd,HWND_TOP,0,0,windowRect.right,windowRect.bottom,SWP_FRAMECHANGED | SWP_SHOWWINDOW);
SetWindowLong(hwnd, GWL_STYLE, WS_VISIBLE | WS_EX_TOPMOST | WS_POPUP); 

回答by karlphillip

Have you issued cvShowImage()to display the window? Because it seems you are not doing it. Anyway, you might want to call the win32 API for this instead, so add a call to ShowWindow(hwnd, SW_SHOW);after SetWindowPos().

你有没有发出cvShowImage()显示窗口?因为看起来你没有这样做。无论如何,您可能希望为此调用 win32 API,因此添加对ShowWindow(hwnd, SW_SHOW);after的调用SetWindowPos()

If your current call to SetWindowPos()doesn't do the trick, check this answer: Hide border of window, if i know a handle of this window

如果您当前调用的方法SetWindowPos()不起作用,请检查此答案:隐藏窗口边框,如果我知道此窗口的句柄

I recommend you doing your tests without calling cvSetWindowProperty()at first, just to make sure you can find a method that works.

我建议您cvSetWindowProperty()先不调用就进行测试,以确保您可以找到有效的方法。

Just a note, if you check modules/highgui/src/window_w32.cppyou can see how OpenCV creates windows on Windows.

请注意,如果您检查一下,modules/highgui/src/window_w32.cpp您可以看到 OpenCV 如何在 Windows 上创建窗口。

EDIT:

编辑

The following code implements the tips I gave before and bypasses the problems the OP reported. The trick is NOT using cvGetWindowHandle()to retrieve the windows' handle and use directly win32API for that: FindWindow()

下面的代码实现了我之前给出的提示,并绕过了OP报告的问题。诀窍是不cvGetWindowHandle()用于检索 Windows 的句柄并直接使用win32API:FindWindow()

IplImage* cv_img = cvLoadImage("test.jpg", CV_LOAD_IMAGE_UNCHANGED);
if(!cv_img)
{
    printf("Failed cvLoadImage\n");
    return -1;
}

cvNamedWindow("main_win", CV_WINDOW_AUTOSIZE);
cvMoveWindow("main_win", 0, 0);
cvSetWindowProperty("main_win", CV_WINDOW_FULLSCREEN, CV_WINDOW_FULLSCREEN);

cvShowImage("main_win", cv_img);

//HWND cv_hwnd = (HWND)cvGetWindowHandle("main_win");
//if (!cv_hwnd)
//{
//  printf("Failed cvGetWindowHandle\n");
//}
//printf("cvGetWindowHandle returned %p\n", *cv_hwnd);

HWND win_handle = FindWindow(0, L"main_win");
if (!win_handle)
{
    printf("Failed FindWindow\n");
}

SetWindowLong(win_handle, GWL_STYLE, GetWindowLong(win_handle, GWL_EXSTYLE) | WS_EX_TOPMOST);
ShowWindow(win_handle, SW_SHOW);

cvWaitKey(0);

cvReleaseImage(&cv_img);
cvDestroyWindow("main_win");

This code will make the window created by OpenCV borderless, but you still might have to tweak one thing or another to make this operation perfect. You'll see why. One idea is to resize the window and make it the size of the image.

此代码将使 OpenCV 创建的窗口无边框,但您可能仍需要调整一件事或另一件事以使此操作完美。你会明白为什么。一种想法是调整窗口大小并使其成为图像的大小。

EDIT:

编辑

Well, since you stated:

好吧,既然你说:

writing a demo might be very hard

编写演示可能非常困难

I also decided to do this last part for you, since I'm such a nice guy =]

我也决定为你做最后一部分,因为我真是个好人 =]

This is a small improvement of the code above:

这是对上面代码的一个小改进:

HWND win_handle = FindWindow(0, L"main_win");
if (!win_handle)
{
    printf("Failed FindWindow\n");
}

// Resize
unsigned int flags = (SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER);
flags &= ~SWP_NOSIZE;
unsigned int x = 0;
unsigned int y = 0;
unsigned int w = cv_img->width;
unsigned int h = cv_img->height;
SetWindowPos(win_handle, HWND_NOTOPMOST, x, y, w, h, flags);

// Borderless
SetWindowLong(win_handle, GWL_STYLE, GetWindowLong(win_handle, GWL_EXSTYLE) | WS_EX_TOPMOST);
ShowWindow(win_handle, SW_SHOW);

And on my system it displays exactly what you asked on the question.

在我的系统上,它准确显示了您在问题中提出的问题。