У меня есть внешний дисплей, и я хочу показать изображение без рамки и без рамки с той же высотой и шириной, что и внешний монитор. Я начал с OpenCV, но у меня были проблемы с получением изображения без полей. После некоторых поисков я нашел этот вопрос:
Как отобразить изображение в полноэкранном окне без полей в openCV
, где ответ karlphillip очень помогает. Однако я застрял в проблеме, которую Ак упоминает в своем комментарии к ответу:
Этот метод работает с изображениями с меньшим разрешением монитора. Если у меня есть изображение с разрешением, равным моему монитору, оно оставляет серую полосу внизу. Как это убрать, пожалуйста?
Кроме того, кажется, что изображение также имеет серую полосу шириной 1px в верхней части. Для моего приложения чрезвычайно важно, чтобы каждый пиксель имел именно то значение, которое он должен иметь , и чтобы ни один пиксель не был пропущен (или перезаписан серой полосой). Изображение не должно быть искажено каким-либо образом.
Я не ищу сверхбыстрого решения, но я намерен записывать изображения примерно с частотой 10 Гц. Кроме того, я работаю только на Windows, поэтому решение не должно быть кроссплатформенным.
Это мой код, я работаю на Windows 10 с 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;
}