@@ -67,6 +67,20 @@ std::optional<cv::Mat> FramePoolScreencap::screencap()
6767
6868 cv::Mat raw (texture_desc_.Height , texture_desc_.Width , CV_8UC4, mapped.pData , mapped.RowPitch );
6969
70+ // 先按 alpha 通道裁剪掉四周 alpha != 255 的边框
71+ cv::Mat alpha_channel;
72+ cv::extractChannel (raw, alpha_channel, 3 );
73+
74+ cv::Mat alpha_bin;
75+ cv::threshold (alpha_channel, alpha_bin, UCHAR_MAX - 1 , UCHAR_MAX, cv::THRESH_BINARY);
76+
77+ cv::Rect alpha_roi = cv::boundingRect (alpha_bin);
78+ if (alpha_roi.empty ()) {
79+ LogError << " No opaque pixels found" ;
80+ return std::nullopt ;
81+ }
82+ cv::Mat trimmed = raw (alpha_roi);
83+
7084 // 获取窗口客户区矩形(相对于窗口)
7185 RECT client_rect = { 0 };
7286 if (!GetClientRect (hwnd_, &client_rect)) {
@@ -88,39 +102,36 @@ std::optional<cv::Mat> FramePoolScreencap::screencap()
88102 return std::nullopt ;
89103 }
90104
91- int border_left = client_top_left.x - window_rect.left ;
92- int border_top = client_top_left.y - window_rect.top ;
93-
94- // 神秘小算法
95- // 检查 alpha 通道值,找到真正的边框位置
96- for (int i = 0 ; i < border_left; ++i) {
97- if (raw.at <cv::Vec4b>(border_top, i)[3 ] != 255 ) {
98- continue ;
99- }
100- border_left = i;
101- break ;
102- }
105+ // 计算边框位置,减去 alpha 裁剪的偏移
106+ int border_left = client_top_left.x - window_rect.left - alpha_roi.x ;
107+ int border_top = client_top_left.y - window_rect.top - alpha_roi.y ;
103108
104109 // 获取客户区大小
105110 int client_width = client_rect.right - client_rect.left ;
106111 int client_height = client_rect.bottom - client_rect.top ;
107112
108- if (client_width > raw.cols ) {
109- client_width = raw.cols ;
113+ if (border_left < 0 ) {
114+ border_left = 0 ;
115+ }
116+ if (border_top < 0 ) {
117+ border_top = 0 ;
118+ }
119+ if (client_width > trimmed.cols ) {
120+ client_width = trimmed.cols ;
110121 }
111- if (border_left + client_width > raw .cols ) {
112- border_left = raw .cols - client_width;
122+ if (border_left + client_width > trimmed .cols ) {
123+ border_left = trimmed .cols - client_width;
113124 }
114- if (client_height > raw .rows ) {
115- client_height = raw .rows ;
125+ if (client_height > trimmed .rows ) {
126+ client_height = trimmed .rows ;
116127 }
117- if (border_top + client_height > raw .rows ) {
118- border_top = raw .rows - client_height;
128+ if (border_top + client_height > trimmed .rows ) {
129+ border_top = trimmed .rows - client_height;
119130 }
120131
121132 // 裁剪出客户区(去掉边框)
122133 cv::Rect client_roi (border_left, border_top, client_width, client_height);
123- cv::Mat image = raw (client_roi);
134+ cv::Mat image = trimmed (client_roi);
124135
125136 return bgra_to_bgr (image);
126137}
0 commit comments