diff --git a/LunaTranslator/LunaTranslator/gui/rangeselect.py b/LunaTranslator/LunaTranslator/gui/rangeselect.py index 1ae52781..4fae90ad 100644 --- a/LunaTranslator/LunaTranslator/gui/rangeselect.py +++ b/LunaTranslator/LunaTranslator/gui/rangeselect.py @@ -66,29 +66,25 @@ class rangeadjust(Mainw): self._endPos = None def rectoffset(self, rect): - return [ + r = self.devicePixelRatioF() + _ = [ ( - rect.left() + globalconfig["ocrrangewidth"], - rect.top() + globalconfig["ocrrangewidth"], + rect.left() + int(globalconfig["ocrrangewidth"] * r), + rect.top() + int(globalconfig["ocrrangewidth"] * r), ), ( - rect.right() - globalconfig["ocrrangewidth"], - rect.bottom() - globalconfig["ocrrangewidth"], + rect.right() - int(globalconfig["ocrrangewidth"] * r), + rect.bottom() - int(globalconfig["ocrrangewidth"] * r), ), ] + return _ def setGeometry(self, x, y, w, h): - if QDesktopWidget().screenCount() > 1: - windows.MoveWindow(int(self.winId()), x, y, w, h, True) - else: - super().setGeometry(x, y, w, h) + windows.MoveWindow(int(self.winId()), x, y, w, h, True) def geometry(self): - if QDesktopWidget().screenCount() > 1: - rect = windows.GetWindowRect(int(self.winId())) - return QRect(rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1]) - else: - return super().geometry() + rect = windows.GetWindowRect(int(self.winId())) + return QRect(rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1]) def moveEvent(self, e): if self._rect: @@ -111,16 +107,17 @@ class rangeadjust(Mainw): return self._rect def setrect(self, rect): - self._rect = rect if rect: (x1, y1), (x2, y2) = rect + self.show() self.setGeometry( x1 - globalconfig["ocrrangewidth"], y1 - globalconfig["ocrrangewidth"], x2 - x1 + 2 * globalconfig["ocrrangewidth"], y2 - y1 + 2 * globalconfig["ocrrangewidth"], ) - self.show() + self._rect = rect + # 由于使用movewindow而非qt函数,导致内部执行绪有问题。 class rangeselct(QMainWindow): @@ -191,8 +188,7 @@ class rangeselct(QMainWindow): self.clickrelease = False self.mouseReleaseEvent(event) else: - self.start_point = event.pos() - self.end_point = self.start_point + self.end_point = self.start_point = event.pos() self.is_drawing = True self.__start = self.__end = windows.GetCursorPos() @@ -209,22 +205,14 @@ class rangeselct(QMainWindow): self.update() def getRange(self): - if QDesktopWidget().screenCount() > 1: - x1, y1, x2, y2 = ( - self.__start.x, - self.__start.y, - self.__end.x, - 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, y1, x2, y2 = ( + self.__start.x, + self.__start.y, + self.__end.x, + self.__end.y, + ) + x1, x2 = min(x1, x2), max(x1, x2) y1, y2 = min(y1, y2), max(y1, y2) @@ -233,6 +221,7 @@ class rangeselct(QMainWindow): def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton: self.end_point = event.pos() + self.__end = windows.GetCursorPos() self.close() self.callback(self.getRange()) diff --git a/LunaTranslator/LunaTranslator/myutils/hwnd.py b/LunaTranslator/LunaTranslator/myutils/hwnd.py index 826d8e93..c6fc3e69 100644 --- a/LunaTranslator/LunaTranslator/myutils/hwnd.py +++ b/LunaTranslator/LunaTranslator/myutils/hwnd.py @@ -55,10 +55,7 @@ def grabwindow(app, callback=None): hwnd = windows.GetForegroundWindow() _ = windows.GetClientRect(hwnd) - rate = dynamic_rate(hwnd, _) - 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) + p = screenshot(0, 0, _[2], _[3], hwnd).toImage() if not p.allGray(): p.save(fname + "_gdi." + app) if callback and os.path.exists(fname + "_gdi." + app): @@ -254,8 +251,8 @@ def mouseselectwindow(callback): threading.Thread(target=_loop).start() -def screenshot(x1, y1, x2, y2): - bs = winsharedutils.gdi_screenshot(x1, y1, x2, y2) +def screenshot(x1, y1, x2, y2, hwnd=None): + bs = winsharedutils.gdi_screenshot(x1, y1, x2, y2, hwnd) pixmap = QPixmap() pixmap.loadFromData(bs) return pixmap diff --git a/LunaTranslator/LunaTranslator/myutils/ocrutil.py b/LunaTranslator/LunaTranslator/myutils/ocrutil.py index 8bbd2924..e5a4fe98 100644 --- a/LunaTranslator/LunaTranslator/myutils/ocrutil.py +++ b/LunaTranslator/LunaTranslator/myutils/ocrutil.py @@ -51,7 +51,7 @@ def imagesolve(image): def imageCut(hwnd, x1, y1, x2, y2, viscompare=True, rawimage=False) -> QImage: - screen = QApplication.primaryScreen() + for _ in range(2): if _ % 2 == 0: @@ -62,34 +62,16 @@ def imageCut(hwnd, x1, y1, x2, y2, viscompare=True, rawimage=False) -> QImage: if rect is None: continue - rate = dynamic_rate(hwnd, rect) - hwndrate = windows.GetDpiForWindow(hwnd) / 96 - x1, y1 = windows.ScreenToClient( - 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), - ) + x1, y1 = windows.ScreenToClient(hwnd, x1, y1) + x2, y2 = windows.ScreenToClient(hwnd, x2, y2) + pix = screenshot(x1, y1, x2, y2, hwnd) if pix.toImage().allGray(): continue break except: print_exc() else: - - if QDesktopWidget().screenCount() > 1: - pix = screenshot(x1, y1, x2, y2) - else: - pix = screen.grabWindow( - QApplication.desktop().winId(), x1, y1, x2 - x1, y2 - y1 - ) + pix = screenshot(x1, y1, x2, y2) image = pix.toImage() if rawimage: diff --git a/LunaTranslator/LunaTranslator/winsharedutils.py b/LunaTranslator/LunaTranslator/winsharedutils.py index 8adeb838..cc09c1f4 100644 --- a/LunaTranslator/LunaTranslator/winsharedutils.py +++ b/LunaTranslator/LunaTranslator/winsharedutils.py @@ -363,18 +363,18 @@ PlayAudioInMem_Stop = utilsdll.PlayAudioInMem_Stop PlayAudioInMem_Stop.argtypes = c_void_p, c_void_p _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) -def gdi_screenshot(x1, y1, x2, y2): +def gdi_screenshot(x1, y1, x2, y2, hwnd=None): sz = c_size_t() rect = RECT() rect.left = x1 rect.top = y1 rect.right = x2 rect.bottom = y2 - bf = _gdi_screenshot(rect, pointer(sz)) + bf = _gdi_screenshot(hwnd, rect, pointer(sz)) data = cast(bf, POINTER(c_char))[: sz.value] c_free(bf) return data diff --git a/plugins/winrtutils/winrtsnapshot.cpp b/plugins/winrtutils/winrtsnapshot.cpp index 5553465a..9c4e5db5 100644 --- a/plugins/winrtutils/winrtsnapshot.cpp +++ b/plugins/winrtutils/winrtsnapshot.cpp @@ -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(), adapter.put_void())); winrt::com_ptr factory; winrt::check_hresult(adapter->GetParent(winrt::guid_of(), factory.put_void())); - - ID3D11DeviceContext *d3d_context = nullptr; - d3d_device->GetImmediateContext(&d3d_context); + + winrt::com_ptr d3d_context; + d3d_device->GetImmediateContext(d3d_context.put()); RECT 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.biSizeImage = captured_texture_desc.Width * captured_texture_desc.Height * 4; - std::unique_ptr p_buf(new BYTE[l_bmp_info.bmiHeader.biSizeImage]); + auto p_buf = std::make_unique(l_bmp_info.bmiHeader.biSizeImage); UINT l_bmp_row_pitch = captured_texture_desc.Width * 4; auto sptr = static_cast(resource.pData); 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); image->Save(output_file_path.c_str(), &encoderClsid, NULL); + delete image; Gdiplus::GdiplusShutdown(gdiplusToken); } void winrt_capture_window(wchar_t *savepath, HWND hwnd) diff --git a/plugins/winsharedutils/screenshot.cpp b/plugins/winsharedutils/screenshot.cpp index a3f118ba..00be1e8d 100644 --- a/plugins/winsharedutils/screenshot.cpp +++ b/plugins/winsharedutils/screenshot.cpp @@ -131,40 +131,39 @@ BYTE *SaveBitmapToBuffer(HBITMAP hBitmap, size_t *size) bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved2 = 0; 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)&bi, sizeof(BITMAPINFOHEADER), &dwWritten, NULL); + memcpy(buffer, &bmfHdr, sizeof(BITMAPFILEHEADER)); + memcpy(buffer + sizeof(BITMAPFILEHEADER), &bi, sizeof(BITMAPINFOHEADER)); // 获取位图阵列 lpmem = new char[dwBmBitsSize]; - lpbk = (LPSTR) new char[dwBmBitsSize]; GetBitmapBits(hBitmap, dwBmBitsSize, lpmem); // 正向的内存图象数据 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); - 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; // 清除 - delete[] lpbk; delete[] lpmem; 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)"); auto bf = SaveBitmapToBuffer(bm, size); - DeleteObject(bf); + DeleteObject(bm); return bf; }