This commit is contained in:
恍兮惚兮 2024-05-27 00:17:36 +08:00
parent f12c6fff88
commit 4ad963d9bd
7 changed files with 226 additions and 32 deletions

View File

@ -7,13 +7,13 @@ from PyQt5.QtWidgets import (
QDialog,
QDesktopWidget,
)
from PyQt5.QtGui import QPainter, QPen, QColor
from PyQt5.QtGui import QPainter, QPen, QColor, QResizeEvent
from PyQt5.QtCore import Qt, QPoint, QRect, QEvent
from myutils.config import _TR
import gobject
from myutils.config import globalconfig
from gui.resizeablemainwindow import Mainw
import windows
import windows, winsharedutils
class rangeadjust(Mainw):
@ -131,25 +131,24 @@ class rangeselct(QMainWindow):
Qt.FramelessWindowHint | Qt.Tool
) # |Qt.WindowStaysOnTopHint )
self.rectlabel = QLabel(self)
self.setAttribute(Qt.WA_TranslucentBackground)
# self.setAttribute(Qt.WA_TranslucentBackground)
self.setWindowOpacity(0.5)
self.setMouseTracking(True)
self.setCursor(Qt.CrossCursor)
self.reset()
def reset(self):
# screens = QDesktopWidget().screenCount()
# desktop = QDesktopWidget().screenGeometry(0)
# for i in range(1, screens):
# desktop = desktop.united(QDesktopWidget().screenGeometry(i))
desktop = QApplication.primaryScreen().virtualGeometry()
self.setGeometry(desktop)
self.rectlabel.setGeometry(desktop)
self.setCursor(Qt.CrossCursor)
winsharedutils.maximum_window(int(self.winId()))
# desktop = QApplication.primaryScreen().virtualGeometry()
# self.setGeometry(desktop)
self.is_drawing = False
self.setMouseTracking(True)
self.start_point = QPoint()
self.end_point = QPoint()
self.__start = None
self.__end = None
self.startauto = False
self.clickrelease = False
self.rectlabel.resize(0, 0)
self.rectlabel.setStyleSheet(
" border:%spx solid %s; background-color: rgba(0,0,0, 0.01)"
% (globalconfig["ocrrangewidth"], globalconfig["ocrrangecolor"])
@ -246,8 +245,8 @@ def rangeselct_function(parent, callback, clickrelease, startauto):
global screen_shot_ui
if screen_shot_ui is None:
screen_shot_ui = rangeselct(parent)
screen_shot_ui.reset()
screen_shot_ui.show()
screen_shot_ui.reset()
screen_shot_ui.callback = callback
windows.SetFocus(int(screen_shot_ui.winId()))

View File

@ -252,3 +252,10 @@ def mouseselectwindow(callback):
pass
threading.Thread(target=_loop).start()
def screenshot(x1, y1, x2, y2):
bs = winsharedutils.gdi_screenshot(x1, y1, x2, y2)
pixmap = QPixmap()
pixmap.loadFromData(bs)
return pixmap

View File

@ -5,7 +5,7 @@ from PyQt5.QtWidgets import QApplication, QDesktopWidget
from PyQt5.QtGui import QImage
from PyQt5.QtCore import QByteArray, QBuffer
from myutils.commonbase import ArgsEmptyExc
from myutils.hwnd import dynamic_rate
from myutils.hwnd import dynamic_rate, screenshot
from myutils.utils import stringfyerror
from traceback import print_exc
import gobject, winsharedutils
@ -83,20 +83,9 @@ def imageCut(hwnd, x1, y1, x2, y2, viscompare=True, rawimage=False) -> QImage:
except:
print_exc()
else:
if QDesktopWidget().screenCount() > 1:
desktop = QApplication.primaryScreen().virtualGeometry()
pix = screen.grabWindow(
QApplication.desktop().winId(),
desktop.x(),
desktop.y(),
desktop.width(),
desktop.height(),
)
x1 = x1 - desktop.x()
y1 = y1 - desktop.y()
x2 = x2 - desktop.x()
y2 = y2 - desktop.y()
pix = pix.copy(x1, y1, x2 - x1, y2 - y1)
pix = screenshot(x1, y1, x2, y2)
else:
pix = screen.grabWindow(
QApplication.desktop().winId(), x1, y1, x2 - x1, y2 - y1

View File

@ -20,7 +20,7 @@ from ctypes import (
c_double,
c_char,
)
from ctypes.wintypes import WORD, HANDLE, HWND, LONG, DWORD
from ctypes.wintypes import WORD, HANDLE, HWND, LONG, DWORD, RECT, BYTE
from windows import WINDOWPLACEMENT
import gobject, csv
@ -126,7 +126,9 @@ def SAPI_Speak(content, v, voiceid, rate, volume):
return data
def distance(s1, s2): # 词典更适合用编辑距离,因为就一两个字符,相似度会很小,预翻译适合用相似度
def distance(
s1, s2
): # 词典更适合用编辑距离,因为就一两个字符,相似度会很小,预翻译适合用相似度
return _levenshtein_distance(len(s1), s1, len(s2), s2)
@ -359,3 +361,24 @@ PlayAudioInMem.restype = c_int
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.restype = POINTER(BYTE)
def gdi_screenshot(x1, y1, x2, y2):
sz = c_size_t()
rect = RECT()
rect.left = x1
rect.top = y1
rect.right = x2
rect.bottom = y2
bf = _gdi_screenshot(rect, pointer(sz))
data = cast(bf, POINTER(c_char))[: sz.value]
c_free(bf)
return data
maximum_window = utilsdll.maximum_window
maximum_window.argtypes = (HWND,)

View File

@ -28,8 +28,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/version)
include(generate_product_version)
set(VERSION_MAJOR 2)
set(VERSION_MINOR 52)
set(VERSION_PATCH 8)
set(VERSION_MINOR 53)
set(VERSION_PATCH 0)
add_library(pch pch.cpp)
target_precompile_headers(pch PUBLIC pch.h)

View File

@ -11,7 +11,7 @@ generate_product_version(
VERSION_PATCH ${VERSION_PATCH}
)
add_library(winsharedutils MODULE audio.cpp ../implsapi.cpp hwnd.cpp darklistener.cpp theme.cpp version.cpp otsu.cpp cinterface.cpp clipboard.cpp lnk.cpp dllmain.cpp levenshtein.cpp muteprocess.cpp sapi_dll.cpp simplemecab.cpp SimpleBrowser.cpp MWebBrowser.cpp icon.cpp maglistener.cpp ${versioninfo})
add_library(winsharedutils MODULE screenshot.cpp audio.cpp ../implsapi.cpp hwnd.cpp darklistener.cpp theme.cpp version.cpp otsu.cpp cinterface.cpp clipboard.cpp lnk.cpp dllmain.cpp levenshtein.cpp muteprocess.cpp sapi_dll.cpp simplemecab.cpp SimpleBrowser.cpp MWebBrowser.cpp icon.cpp maglistener.cpp ${versioninfo})
target_precompile_headers(winsharedutils REUSE_FROM pch)
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
set_target_properties(winsharedutils PROPERTIES OUTPUT_NAME "winsharedutils64")

View File

@ -0,0 +1,176 @@

#include "define.h"
void GetVirtualDesktopRect(RECT &rect)
{
// 获取虚拟桌面的尺寸和位置
rect.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
rect.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
rect.right = rect.left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
rect.bottom = rect.top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
}
HBITMAP GetBitmap(RECT &rect, HDC hDC)
{
HDC hMemDC;
int x, y;
int nWidth, nHeight;
HBITMAP hBitmap, hOldBitmap;
hMemDC = CreateCompatibleDC(hDC);
// RECT rect;
// GetVirtualDesktopRect(rect);
hBitmap = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
BitBlt(hMemDC, 0, 0, rect.right - rect.left, rect.bottom - rect.top, hDC, rect.left, rect.top, SRCCOPY);
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
DeleteDC(hMemDC);
return hBitmap;
}
int SaveBitmapToFile(HBITMAP hBitmap, LPCWSTR lpFileName)
{
WORD wBitCount; // 位图中每个像素所占字节数
// 定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数
DWORD dwPaletteSize = 0, dwBmBitsSize, dwDIBSize, dwWritten;
BITMAP Bitmap; // 位图属性结构
BITMAPFILEHEADER bmfHdr; // 位图文件头结构
BITMAPINFOHEADER bi; // 位图信息头结构
HANDLE fh; // 定义文件,分配内存句柄,调色板句柄
LPSTR lpbk, lpmem;
wBitCount = 32;
// 设置位图信息头结构
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight; // 为负,正向的位图;为正,倒向的位图
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;
// 创建位图文件
fh = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE)
return FALSE;
// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
// 写入位图文件头
WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
// 写入位图信息头
WriteFile(fh, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwWritten, NULL);
// 获取位图阵列
lpmem = new char[dwBmBitsSize];
lpbk = (LPSTR) new char[dwBmBitsSize];
GetBitmapBits(hBitmap, dwBmBitsSize, lpmem); // 正向的内存图象数据
// 转化为倒向数据(仅在bmHeight为正时需要)
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);
}
// 写位图数据
WriteFile(fh, lpbk, dwBmBitsSize, &dwWritten, NULL);
// 清除
delete[] lpbk;
delete[] lpmem;
CloseHandle(fh);
return TRUE;
}
BYTE *SaveBitmapToBuffer(HBITMAP hBitmap, size_t *size)
{
WORD wBitCount; // 位图中每个像素所占字节数
// 定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数
DWORD dwPaletteSize = 0, dwBmBitsSize, dwDIBSize, dwWritten;
BITMAP Bitmap; // 位图属性结构
BITMAPFILEHEADER bmfHdr; // 位图文件头结构
BITMAPINFOHEADER bi; // 位图信息头结构
LPSTR lpbk, lpmem;
wBitCount = 32;
// 设置位图信息头结构
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight; // 为负,正向的位图;为正,倒向的位图
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;
// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
// 写入位图文件头
// WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
// 写入位图信息头
// WriteFile(fh, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwWritten, NULL);
// 获取位图阵列
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);
}
// 写位图数据
// 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)
{
auto bm = GetBitmap(rect, GetDC(GetDesktopWindow()));
// SaveBitmapToFile(bm, LR"(.\2.bmp)");
auto bf = SaveBitmapToBuffer(bm, size);
DeleteObject(bf);
return bf;
}
DECLARE void maximum_window(HWND hwnd)
{
RECT rect;
GetVirtualDesktopRect(rect);
MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
}