| 12 | } |
| 13 | |
| 14 | std::optional<cv::Mat> DesktopDupScreencap::screencap() |
| 15 | { |
| 16 | // 初始化 D3D 设备和 DXGI 工厂(只需要初始化一次) |
| 17 | if (!d3d_device_) { |
| 18 | if (!init()) { |
| 19 | LogError << "failed to init_d3d_device"; |
| 20 | uninit(); |
| 21 | return std::nullopt; |
| 22 | } |
| 23 | } |
| 24 | |
| 25 | // 确保输出匹配当前窗口所在的显示器(每次截图时检查,支持窗口移动) |
| 26 | if (!ensure_output_for_monitor()) { |
| 27 | LogError << "failed to ensure_output_for_monitor"; |
| 28 | return std::nullopt; |
| 29 | } |
| 30 | |
| 31 | // 如果输出刚初始化,前几张图片可能是空的,跳过 |
| 32 | if (output_just_initialized_) { |
| 33 | for (int i = 0; i < 3; ++i) { |
| 34 | auto opt = screencap_impl(); |
| 35 | if (opt) { |
| 36 | const auto& br = *(opt->end<cv::Vec4b>() - 1); |
| 37 | if (br[3] == 255) { // only check alpha |
| 38 | output_just_initialized_ = false; |
| 39 | break; |
| 40 | } |
| 41 | } |
| 42 | LogWarn << "blank image, continue"; |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | auto img = screencap_impl(); |
| 47 | if (!img) { |
| 48 | return std::nullopt; |
| 49 | } |
| 50 | return bgra_to_bgr(*img); |
| 51 | } |
| 52 | |
| 53 | bool DesktopDupScreencap::init() |
| 54 | { |
nothing calls this directly
no test coverage detected