1

I have an external display and I want to show a borderless/frameless image with exactly the same height and width as the external monitor. I started out with OpenCV but I had problems getting a borderless image. After some searching I found this question:

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

where karlphillip's answer is of great help. However, I am stuck at the problem A.k. mentions in his/her comment to the answer:

This method works with images less than monitor resolution. If I have an image with a resolution equal to my monitor, it left a grey bar at the bottom. How to remove that, please?

Additionally, It seems that the image also has a 1px wide grey bar at the top. For my application it is extremely important that every pixel has exactly the value it is supposed to have and that no pixel is left out (or overwritten by a grey bar). The image must not be distorted in any way.

I am not looking for a super fast solution but I intend to write images at roughly 10Hz. Also, I am working on Windows only so the solution doesn't have to be cross-platform.

This is my code, I am working on Windows 10 with VS2019:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>

#include <iostream>
#include <vector>
#include <Windows.h>

int main() {

    // Pixels of external monitor, can be different later
    size_t N_x = 2560; // 1920
    size_t N_y = 1440; // 1080

    // My display resolution. Used to shift the OpenCV image
    size_t disp_width  = 2560;
    size_t disp_height = 1440;

    // To verify that the image is written correctly I generate a sawtooth image with a 4 pixel period.
    byte period = 4;
    byte slope = 110 / (period - 1);
    std::vector<byte> image_vec (N_y * N_x);

    for (size_t i = 0; i < N_y; i++) {
        for (size_t j = 0; j < N_x; j++) {
            image_vec.at(i * N_x + j) = slope * (j % period);
        }
    }

    cv::Mat image = cv::Mat(N_y, N_x, CV_8UC1);
    memcpy(image.data, image_vec.data(), image_vec.size() * sizeof(byte));

    // When I use cv::WINDOW_NORMAL instead of cv::WINDOW_FULLSCREEN the image gets distorted in the horizontal direction
    cv::namedWindow("Display Window", cv::WINDOW_FULLSCREEN);
    imshow("Display Window", image);

    // Grab the image and resize it, code taken from karlphillip's answer
    HWND win_handle = FindWindowA(0, "Display Window");
    if (!win_handle) {
        printf("Could not find window\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 = image.cols;
    unsigned int h = image.rows;
    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);

    cv::waitKey(0);

    return EXIT_SUCCESS;
}
ctrl
  • 15
  • 1
  • 5

2 Answers2

0

You can display the image in an app (that you can also write) and set the app to full screen mode using the ApplicationView class https://learn.microsoft.com/en-us/uwp/api/Windows.UI.ViewManagement.ApplicationView?redirectedfrom=MSDN. Example code is in https://github.com/microsoft/Windows-universal-samples/tree/master/Samples/FullScreenMode

https://learn.microsoft.com/en-us/uwp/api/windows.ui.viewmanagement.applicationview.tryenterfullscreenmode This approach is based on UWP so you may get problems using it on earlier versions

ralf htp
  • 9,149
  • 4
  • 22
  • 34
  • Thank you for your answer. I will have a look at it although I would prefer a solution/fix using the standard Win32 API. – ctrl Jan 15 '20 at 16:44
0

I had a look at UWP but this is not what I want for my application. In the end I chose to use OpenGL/FreeGLUT which works well after some trial and error. If someone is interested I can write a more elaborate answer.

ctrl
  • 15
  • 1
  • 5