Update winrtsnapshot.cpp
This commit is contained in:
恍兮惚兮 2024-05-27 12:14:04 +08:00
parent 4ad963d9bd
commit b452fada02
6 changed files with 49 additions and 81 deletions

View File

@ -66,29 +66,25 @@ class rangeadjust(Mainw):
self._endPos = None self._endPos = None
def rectoffset(self, rect): def rectoffset(self, rect):
return [ r = self.devicePixelRatioF()
_ = [
( (
rect.left() + globalconfig["ocrrangewidth"], rect.left() + int(globalconfig["ocrrangewidth"] * r),
rect.top() + globalconfig["ocrrangewidth"], rect.top() + int(globalconfig["ocrrangewidth"] * r),
), ),
( (
rect.right() - globalconfig["ocrrangewidth"], rect.right() - int(globalconfig["ocrrangewidth"] * r),
rect.bottom() - globalconfig["ocrrangewidth"], rect.bottom() - int(globalconfig["ocrrangewidth"] * r),
), ),
] ]
return _
def setGeometry(self, x, y, w, h): def setGeometry(self, x, y, w, h):
if QDesktopWidget().screenCount() > 1: windows.MoveWindow(int(self.winId()), x, y, w, h, True)
windows.MoveWindow(int(self.winId()), x, y, w, h, True)
else:
super().setGeometry(x, y, w, h)
def geometry(self): def geometry(self):
if QDesktopWidget().screenCount() > 1: rect = windows.GetWindowRect(int(self.winId()))
rect = windows.GetWindowRect(int(self.winId())) return QRect(rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1])
return QRect(rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1])
else:
return super().geometry()
def moveEvent(self, e): def moveEvent(self, e):
if self._rect: if self._rect:
@ -111,16 +107,17 @@ class rangeadjust(Mainw):
return self._rect return self._rect
def setrect(self, rect): def setrect(self, rect):
self._rect = rect
if rect: if rect:
(x1, y1), (x2, y2) = rect (x1, y1), (x2, y2) = rect
self.show()
self.setGeometry( self.setGeometry(
x1 - globalconfig["ocrrangewidth"], x1 - globalconfig["ocrrangewidth"],
y1 - globalconfig["ocrrangewidth"], y1 - globalconfig["ocrrangewidth"],
x2 - x1 + 2 * globalconfig["ocrrangewidth"], x2 - x1 + 2 * globalconfig["ocrrangewidth"],
y2 - y1 + 2 * globalconfig["ocrrangewidth"], y2 - y1 + 2 * globalconfig["ocrrangewidth"],
) )
self.show() self._rect = rect
# 由于使用movewindow而非qt函数导致内部执行绪有问题。
class rangeselct(QMainWindow): class rangeselct(QMainWindow):
@ -191,8 +188,7 @@ class rangeselct(QMainWindow):
self.clickrelease = False self.clickrelease = False
self.mouseReleaseEvent(event) self.mouseReleaseEvent(event)
else: else:
self.start_point = event.pos() self.end_point = self.start_point = event.pos()
self.end_point = self.start_point
self.is_drawing = True self.is_drawing = True
self.__start = self.__end = windows.GetCursorPos() self.__start = self.__end = windows.GetCursorPos()
@ -209,22 +205,14 @@ class rangeselct(QMainWindow):
self.update() self.update()
def getRange(self): def getRange(self):
if QDesktopWidget().screenCount() > 1:
x1, y1, x2, y2 = ( x1, y1, x2, y2 = (
self.__start.x, self.__start.x,
self.__start.y, self.__start.y,
self.__end.x, self.__end.x,
self.__end.y, self.__end.y,
) )
else:
start_point = self.mapToGlobal(self.start_point)
end_point = self.mapToGlobal(self.end_point)
x1, y1, x2, y2 = (
start_point.x(),
start_point.y(),
end_point.x(),
end_point.y(),
)
x1, x2 = min(x1, x2), max(x1, x2) x1, x2 = min(x1, x2), max(x1, x2)
y1, y2 = min(y1, y2), max(y1, y2) y1, y2 = min(y1, y2), max(y1, y2)
@ -233,6 +221,7 @@ class rangeselct(QMainWindow):
def mouseReleaseEvent(self, event): def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton: if event.button() == Qt.LeftButton:
self.end_point = event.pos() self.end_point = event.pos()
self.__end = windows.GetCursorPos()
self.close() self.close()
self.callback(self.getRange()) self.callback(self.getRange())

View File

@ -55,10 +55,7 @@ def grabwindow(app, callback=None):
hwnd = windows.GetForegroundWindow() hwnd = windows.GetForegroundWindow()
_ = windows.GetClientRect(hwnd) _ = windows.GetClientRect(hwnd)
rate = dynamic_rate(hwnd, _) p = screenshot(0, 0, _[2], _[3], hwnd).toImage()
w, h = int(_[2] / rate), int(_[3] / rate)
p = QApplication.primaryScreen().grabWindow(hwnd, 0, 0, w, h)
p = p.toImage().copy(0, 0, w, h)
if not p.allGray(): if not p.allGray():
p.save(fname + "_gdi." + app) p.save(fname + "_gdi." + app)
if callback and os.path.exists(fname + "_gdi." + app): if callback and os.path.exists(fname + "_gdi." + app):
@ -254,8 +251,8 @@ def mouseselectwindow(callback):
threading.Thread(target=_loop).start() threading.Thread(target=_loop).start()
def screenshot(x1, y1, x2, y2): def screenshot(x1, y1, x2, y2, hwnd=None):
bs = winsharedutils.gdi_screenshot(x1, y1, x2, y2) bs = winsharedutils.gdi_screenshot(x1, y1, x2, y2, hwnd)
pixmap = QPixmap() pixmap = QPixmap()
pixmap.loadFromData(bs) pixmap.loadFromData(bs)
return pixmap return pixmap

View File

@ -51,7 +51,7 @@ def imagesolve(image):
def imageCut(hwnd, x1, y1, x2, y2, viscompare=True, rawimage=False) -> QImage: def imageCut(hwnd, x1, y1, x2, y2, viscompare=True, rawimage=False) -> QImage:
screen = QApplication.primaryScreen()
for _ in range(2): for _ in range(2):
if _ % 2 == 0: if _ % 2 == 0:
@ -62,34 +62,16 @@ def imageCut(hwnd, x1, y1, x2, y2, viscompare=True, rawimage=False) -> QImage:
if rect is None: if rect is None:
continue continue
rate = dynamic_rate(hwnd, rect) x1, y1 = windows.ScreenToClient(hwnd, x1, y1)
hwndrate = windows.GetDpiForWindow(hwnd) / 96 x2, y2 = windows.ScreenToClient(hwnd, x2, y2)
x1, y1 = windows.ScreenToClient( pix = screenshot(x1, y1, x2, y2, hwnd)
hwnd, x1 * rate * hwndrate, y1 * rate * hwndrate
)
x2, y2 = windows.ScreenToClient(
hwnd, x2 * rate * hwndrate, y2 * rate * hwndrate
)
pix = screen.grabWindow(
hwnd,
int(x1 / rate / rate / hwndrate),
int(y1 / rate / rate / hwndrate),
int((x2 - x1) / rate / rate / hwndrate),
int((y2 - y1) / rate / rate / hwndrate),
)
if pix.toImage().allGray(): if pix.toImage().allGray():
continue continue
break break
except: except:
print_exc() print_exc()
else: else:
pix = screenshot(x1, y1, x2, y2)
if QDesktopWidget().screenCount() > 1:
pix = screenshot(x1, y1, x2, y2)
else:
pix = screen.grabWindow(
QApplication.desktop().winId(), x1, y1, x2 - x1, y2 - y1
)
image = pix.toImage() image = pix.toImage()
if rawimage: if rawimage:

View File

@ -363,18 +363,18 @@ PlayAudioInMem_Stop = utilsdll.PlayAudioInMem_Stop
PlayAudioInMem_Stop.argtypes = c_void_p, c_void_p PlayAudioInMem_Stop.argtypes = c_void_p, c_void_p
_gdi_screenshot = utilsdll.gdi_screenshot _gdi_screenshot = utilsdll.gdi_screenshot
_gdi_screenshot.argtypes = RECT, POINTER(c_size_t) _gdi_screenshot.argtypes = HWND, RECT, POINTER(c_size_t)
_gdi_screenshot.restype = POINTER(BYTE) _gdi_screenshot.restype = POINTER(BYTE)
def gdi_screenshot(x1, y1, x2, y2): def gdi_screenshot(x1, y1, x2, y2, hwnd=None):
sz = c_size_t() sz = c_size_t()
rect = RECT() rect = RECT()
rect.left = x1 rect.left = x1
rect.top = y1 rect.top = y1
rect.right = x2 rect.right = x2
rect.bottom = y2 rect.bottom = y2
bf = _gdi_screenshot(rect, pointer(sz)) bf = _gdi_screenshot(hwnd, rect, pointer(sz))
data = cast(bf, POINTER(c_char))[: sz.value] data = cast(bf, POINTER(c_char))[: sz.value]
c_free(bf) c_free(bf)
return data return data

View File

@ -88,9 +88,9 @@ void capture_window(HWND window_handle, const std::wstring &output_file_path)
winrt::check_hresult(idxgi_device2->GetParent(winrt::guid_of<IDXGIAdapter>(), adapter.put_void())); winrt::check_hresult(idxgi_device2->GetParent(winrt::guid_of<IDXGIAdapter>(), adapter.put_void()));
winrt::com_ptr<IDXGIFactory2> factory; winrt::com_ptr<IDXGIFactory2> factory;
winrt::check_hresult(adapter->GetParent(winrt::guid_of<IDXGIFactory2>(), factory.put_void())); winrt::check_hresult(adapter->GetParent(winrt::guid_of<IDXGIFactory2>(), factory.put_void()));
ID3D11DeviceContext *d3d_context = nullptr; winrt::com_ptr<ID3D11DeviceContext> d3d_context;
d3d_device->GetImmediateContext(&d3d_context); d3d_device->GetImmediateContext(d3d_context.put());
RECT rect{}; RECT rect{};
DwmGetWindowAttribute(window_handle, DWMWA_EXTENDED_FRAME_BOUNDS, &rect, sizeof(RECT)); DwmGetWindowAttribute(window_handle, DWMWA_EXTENDED_FRAME_BOUNDS, &rect, sizeof(RECT));
@ -176,7 +176,7 @@ void capture_window(HWND window_handle, const std::wstring &output_file_path)
l_bmp_info.bmiHeader.biPlanes = 1; l_bmp_info.bmiHeader.biPlanes = 1;
l_bmp_info.bmiHeader.biSizeImage = captured_texture_desc.Width * captured_texture_desc.Height * 4; l_bmp_info.bmiHeader.biSizeImage = captured_texture_desc.Width * captured_texture_desc.Height * 4;
std::unique_ptr<BYTE> p_buf(new BYTE[l_bmp_info.bmiHeader.biSizeImage]); auto p_buf = std::make_unique<BYTE[]>(l_bmp_info.bmiHeader.biSizeImage);
UINT l_bmp_row_pitch = captured_texture_desc.Width * 4; UINT l_bmp_row_pitch = captured_texture_desc.Width * 4;
auto sptr = static_cast<BYTE *>(resource.pData); auto sptr = static_cast<BYTE *>(resource.pData);
auto dptr = p_buf.get() + l_bmp_info.bmiHeader.biSizeImage - l_bmp_row_pitch; auto dptr = p_buf.get() + l_bmp_info.bmiHeader.biSizeImage - l_bmp_row_pitch;
@ -224,6 +224,7 @@ void capture_window(HWND window_handle, const std::wstring &output_file_path)
GetEncoderClsid(L"image/png", &encoderClsid); GetEncoderClsid(L"image/png", &encoderClsid);
image->Save(output_file_path.c_str(), &encoderClsid, NULL); image->Save(output_file_path.c_str(), &encoderClsid, NULL);
delete image;
Gdiplus::GdiplusShutdown(gdiplusToken); Gdiplus::GdiplusShutdown(gdiplusToken);
} }
void winrt_capture_window(wchar_t *savepath, HWND hwnd) void winrt_capture_window(wchar_t *savepath, HWND hwnd)

View File

@ -131,40 +131,39 @@ BYTE *SaveBitmapToBuffer(HBITMAP hBitmap, size_t *size)
bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0; bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER); bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
auto buffer = new BYTE[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize];
// 写入位图文件头 // 写入位图文件头
// WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL); // WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
// 写入位图信息头 // 写入位图信息头
// WriteFile(fh, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwWritten, NULL); // WriteFile(fh, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwWritten, NULL);
memcpy(buffer, &bmfHdr, sizeof(BITMAPFILEHEADER));
memcpy(buffer + sizeof(BITMAPFILEHEADER), &bi, sizeof(BITMAPINFOHEADER));
// 获取位图阵列 // 获取位图阵列
lpmem = new char[dwBmBitsSize]; lpmem = new char[dwBmBitsSize];
lpbk = (LPSTR) new char[dwBmBitsSize];
GetBitmapBits(hBitmap, dwBmBitsSize, lpmem); // 正向的内存图象数据 GetBitmapBits(hBitmap, dwBmBitsSize, lpmem); // 正向的内存图象数据
for (int i = 0; i < Bitmap.bmHeight; i++) for (int i = 0; i < Bitmap.bmHeight; i++)
{ {
memcpy(lpbk + Bitmap.bmWidth * i * 4, lpmem + Bitmap.bmWidth * (Bitmap.bmHeight - i - 1) * 4, Bitmap.bmWidth * 4); memcpy(buffer + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + Bitmap.bmWidth * i * 4, lpmem + Bitmap.bmWidth * (Bitmap.bmHeight - i - 1) * 4, Bitmap.bmWidth * 4);
} }
// 写位图数据 // 写位图数据
// WriteFile(fh, lpbk, dwBmBitsSize, &dwWritten, NULL); // WriteFile(fh, lpbk, dwBmBitsSize, &dwWritten, NULL);
auto buffer = new BYTE[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize];
memcpy(buffer, &bmfHdr, sizeof(BITMAPFILEHEADER));
memcpy(buffer + sizeof(BITMAPFILEHEADER), &bi, sizeof(BITMAPINFOHEADER));
memcpy(buffer + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER), lpbk, dwBmBitsSize);
*size = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize; *size = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize;
// 清除 // 清除
delete[] lpbk;
delete[] lpmem; delete[] lpmem;
return buffer; return buffer;
} }
DECLARE BYTE *gdi_screenshot(RECT rect, size_t *size) DECLARE BYTE *gdi_screenshot(HWND hwnd, RECT rect, size_t *size)
{ {
auto bm = GetBitmap(rect, GetDC(GetDesktopWindow())); if (!hwnd)
hwnd = GetDesktopWindow();
auto bm = GetBitmap(rect, GetDC(hwnd));
// SaveBitmapToFile(bm, LR"(.\2.bmp)"); // SaveBitmapToFile(bm, LR"(.\2.bmp)");
auto bf = SaveBitmapToBuffer(bm, size); auto bf = SaveBitmapToBuffer(bm, size);
DeleteObject(bf); DeleteObject(bm);
return bf; return bf;
} }