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;
}