1 Star 0 Fork 6

levis1228/JamTools

forked from borelist/JamTools 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
jamscreenshot.py 117.23 KB
一键复制 编辑 原始数据 按行查看 历史
Fandes 提交于 2023-07-23 12:12 . fix:固定字体
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371
import gc
import math
import os
import re
import sys
import time
import cv2
from numpy import array, zeros, uint8, float32,array
from PyQt5.QtCore import QPoint, QRectF, QMimeData
from PyQt5.QtCore import QRect, Qt, pyqtSignal, QStandardPaths, QTimer, QSettings, QUrl
from PyQt5.QtGui import QCursor, QBrush, QScreen,QWindow
from PyQt5.QtGui import QPixmap, QPainter, QPen, QIcon, QFont, QImage, QColor
from PyQt5.QtWidgets import QApplication, QLabel, QPushButton, QTextEdit, QFileDialog, QMenu, QGroupBox, QSpinBox, \
QWidget
from PyQt5.QtWidgets import QSlider, QColorDialog
from jamWidgets import FramelessEnterSendQTextEdit,Freezer
from jampublic import OcrimgThread, Commen_Thread, TipsShower, PLATFORM_SYS,CONFIG_DICT
from jamroll_screenshot import Splicing_shots
import jamresourse
from pynput.mouse import Controller
def cut_polypng(img, pointlist): # 多边形裁剪
xlist = [i[0] for i in pointlist]
ylist = [i[1] for i in pointlist]
w = max(xlist) - min(xlist)
h = max(ylist) - min(ylist)
x0, y0 = min(xlist), min(ylist)
for i, lis in enumerate(pointlist):
pointlist[i] = [lis[0] - x0, lis[1] - y0]
img = img[y0:y0 + h, x0:x0 + w]
pts = array(pointlist)
pts = array([pts])
# 和原始图像一样大小的0矩阵,作为mask
mask = zeros(img.shape[:2], uint8)
# 在mask上将多边形区域填充为白色
cv2.polylines(mask, pts, 1, 255) # 描绘边缘
cv2.fillPoly(mask, pts, 255) # 填充
# 逐位与,得到裁剪后图像,此时是黑色背景
dstimg = cv2.bitwise_and(img, img, mask=mask)
return dstimg
def cut_mutipic(img, pointlist): # 透视裁剪
xlist = [i[0] for i in pointlist]
ylist = [i[1] for i in pointlist]
w = max(xlist) - min(xlist)
h = max(ylist) - min(ylist)
bl = w / abs(pointlist[0][0] - pointlist[1][0])
x0, y0 = min(xlist), min(ylist)
for i, lis in enumerate(pointlist):
pointlist[i] = [lis[0] - x0, lis[1] - y0]
img = img[y0:y0 + h, x0:x0 + w]
pts = array(pointlist)
pts = array([pts])
# 和原始图像一样大小的0矩阵,作为mask
mask = zeros(img.shape[:2], uint8)
# 在mask上将多边形区域填充为白色
cv2.polylines(mask, pts, 1, 255) # 描绘边缘
cv2.fillPoly(mask, pts, 255) # 填充
# 逐位与,得到裁剪后图像,此时是黑色背景
dstimg = cv2.bitwise_and(img, img, mask=mask)
# cv2.imshow("dst", dst)
tw = max(math.sqrt((pointlist[0][1] - pointlist[3][1]) ** 2 + (pointlist[0][0] - pointlist[3][0]) ** 2),
math.sqrt((pointlist[1][1] - pointlist[2][1]) ** 2 + (pointlist[1][0] - pointlist[2][0]) ** 2))
th = max(math.sqrt((pointlist[0][1] - pointlist[3][1]) ** 2 + (pointlist[0][0] - pointlist[3][0]) ** 2),
math.sqrt((pointlist[2][1] - pointlist[1][1]) ** 2 + (pointlist[2][0] - pointlist[1][0]) ** 2),
h)
# if bl>1:
# th=th*bl
tw, th = int(tw), int(th)
org = array(pointlist, float32)
dst = array([[0, 0],
[tw, 0],
[tw, th],
[0, th]], float32)
warpR = cv2.getPerspectiveTransform(org, dst)
result = cv2.warpPerspective(dstimg, warpR, (tw, th), borderMode=cv2.BORDER_TRANSPARENT)
# cv2.namedWindow("result",0)
# cv2.imshow("result", result)
# cv2.waitKey(0)
return result
def get_opposite_color(color: QColor):
return QColor(255 - color.red(), 255 - color.green(), 255 - color.blue())
def image_fill(image, x, y, color: tuple = (0, 0, 255), d=0): # 泛洪填充
src = image.copy() # 先创建一个副本
cv2.floodFill(src, None, (x, y), color, (d, d, d), (d, d, d), cv2.FLOODFILL_FIXED_RANGE)
# cv2.circle(src, (x, y), 2, color=(0, 255, 0), thickness=4)
# cv2.imshow('flood_fill', src)
return src
def get_line_interpolation(p1, p2): # 线性插值
res = []
dy = p1[1] - p2[1]
dx = p1[0] - p2[0]
n = max(abs(dy), abs(dx))
nx = dx / n
ny = dy / n
for i in range(n):
res.append([p2[0] + i * nx, p2[1] + i * ny])
return res
class ColorButton(QPushButton):
select_color_signal = pyqtSignal(str)
def __init__(self, color, parent):
super(ColorButton, self).__init__("", parent)
self.color = QColor(color).name()
self.setStyleSheet("background-color:{}".format(self.color))
self.clicked.connect(self.sendcolor)
def sendcolor(self):
self.select_color_signal.emit(self.color)
class HoverButton(QPushButton):
hoversignal = pyqtSignal(int)
def enterEvent(self, e) -> None:
super(HoverButton, self).enterEvent(e)
self.hoversignal.emit(1)
print("enter")
def leaveEvent(self, e):
super(HoverButton, self).leaveEvent(e)
# time.sleep(2)
self.hoversignal.emit(0)
print("leave")
class HoverGroupbox(QGroupBox):
hoversignal = pyqtSignal(int)
def enterEvent(self, e) -> None:
super(HoverGroupbox, self).enterEvent(e)
self.hoversignal.emit(1)
print("enter")
def leaveEvent(self, e):
super(HoverGroupbox, self).leaveEvent(e)
# time.sleep(2)
self.hoversignal.emit(0)
print("leave")
class CanMoveGroupbox(QGroupBox): # 移动groupbox
def __init__(self, parent):
super(CanMoveGroupbox, self).__init__(parent)
self.drag = False
self.p_x, self.p_y = 0, 0
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton and event.x() < 100:
self.setCursor(Qt.SizeAllCursor)
self.drag = True
self.p_x, self.p_y = event.x(), event.y()
# super(CanMoveGroupbox, self).mousePressEvent(event)
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton:
self.setCursor(Qt.ArrowCursor)
self.drag = False
# super(CanMoveGroupbox, self).mouseReleaseEvent(event)
def mouseMoveEvent(self, event):
if self.isVisible():
if self.drag:
self.move(event.x() + self.x() - self.p_x, event.y() + self.y() - self.p_y)
# super(CanMoveGroupbox, self).mouseMoveEvent(event)
class Finder(): # 选择智能选区
def __init__(self, parent):
self.h = self.w = 0
self.rect_list = self.contours = []
self.area_threshold = 200
self.parent = parent
self.img = None
def find_contours_setup(self):
try:
self.area_threshold = self.parent.parent.ss_areathreshold.value()
except:
self.area_threshold = 200
# t1 = time.process_time()
# self.img = cv2.imread('j_temp/get.png')
# t2 = time.process_time()
self.h, self.w, _ = self.img.shape
gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY) # 灰度化
# t3 = time.process_time()
# ret, th = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY)
th = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 2) # 自动阈值
# th = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_TRUNC, 11, 2) # 自动阈值
# t4 = time.process_time()
self.contours = cv2.findContours(th, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[-2]
self.find_contours()
# print('setuptime', t2 - t1, t3 - t2, t4 - t3)
def find_contours(self):
draw_img = cv2.drawContours(self.img.copy(), self.contours, -1, (0, 255, 0), 1)
# cv2.imshow("tt", draw_img)
# cv2.imwrite("test.png", self.img.copy())
# cv2.waitKey(0)
# newcontours = []
self.rect_list = [[0, 0, self.w, self.h]]
for i in self.contours:
x, y, w, h = cv2.boundingRect(i)
area = cv2.contourArea(i)
if area > self.area_threshold and w > 10 and h > 10:
# cv2.rectangle(self.img, (x, y), (x + w, y + h), (0, 0, 255), 1)
# newcontours.append(i)
self.rect_list.append([x, y, x + w, y + h])
print('contours:', len(self.contours), 'left', len(self.rect_list))
def find_targetrect(self, point):
# print(len(self.rect_list))
# point = (1000, 600)
target_rect = [0, 0, self.w, self.h]
target_area = 1920 * 1080
for rect in self.rect_list:
if point[0] in range(rect[0], rect[2]):
# print('xin',rect)
if point[1] in range(rect[1], rect[3]):
# print('yin', rect)
area = (rect[3] - rect[1]) * (rect[2] - rect[0])
# print(area,target_area)
if area < target_area:
target_rect = rect
target_area = area
# print('target', target_area, target_rect)
# x,y,w,h=target_rect[0],target_rect[1],target_rect[2]-target_rect[0],target_rect[3]-target_rect[1]
# cv2.rectangle(self.img, (x, y), (x + w, y + h), (0, 0, 255), 1)
# cv2.imwrite("img.png", self.img)
return target_rect
def clear_setup(self):
self.h = self.w = 0
self.rect_list = self.contours = []
self.img = None
class MaskLayer(QLabel):
def __init__(self, parent=None):
super().__init__(parent)
self.parent = parent
self.setAttribute(Qt.WA_TranslucentBackground, True)
self.setMouseTracking(True)
def paintEvent(self, e):
super().paintEvent(e)
if self.parent.on_init:
print('oninit return')
return
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
if self.parent.painter_tools["perspective_cut_on"]: # 透视裁剪工具
# painter.setPen(QPen(self.parent.pencolor, 3, Qt.SolidLine))
color = get_opposite_color(self.parent.pencolor)
for i in range(len(self.parent.perspective_cut_pointlist)):
painter.setPen(QPen(color, 10, Qt.SolidLine))
painter.drawPoint(
QPoint(self.parent.perspective_cut_pointlist[i][0], self.parent.perspective_cut_pointlist[i][1]))
painter.setPen(QPen(color, 3, Qt.SolidLine))
if i < len(self.parent.perspective_cut_pointlist) - 1:
painter.drawLine(self.parent.perspective_cut_pointlist[i][0],
self.parent.perspective_cut_pointlist[i][1],
self.parent.perspective_cut_pointlist[i + 1][0],
self.parent.perspective_cut_pointlist[i + 1][1])
else:
painter.drawLine(self.parent.perspective_cut_pointlist[i][0],
self.parent.perspective_cut_pointlist[i][1],
self.parent.mouse_posx, self.parent.mouse_posy)
painter.drawLine(self.parent.perspective_cut_pointlist[0][0],
self.parent.perspective_cut_pointlist[0][1],
self.parent.mouse_posx, self.parent.mouse_posy)
# 画网格
painter.setPen(QPen(QColor(120, 180, 120, 180), 1, Qt.SolidLine))
if len(self.parent.perspective_cut_pointlist) >= 2:
p0 = self.parent.perspective_cut_pointlist[0]
p1 = self.parent.perspective_cut_pointlist[1]
pp1 = pp0 = (self.parent.mouse_posx, self.parent.mouse_posy)
if len(self.parent.perspective_cut_pointlist) > 2:
pp1 = self.parent.perspective_cut_pointlist[2]
dx1 = pp1[0] - p1[0]
dy1 = pp1[1] - p1[1]
dx0 = pp0[0] - p0[0]
dy0 = pp0[1] - p0[1]
maxs = max(math.sqrt(dy0 ** 2 + dx0 ** 2), math.sqrt(dy1 ** 2 + dx1 ** 2))
if maxs > 25:
n = maxs // 25
ddx0 = dx0 / (n + 1)
ddy0 = dy0 / (n + 1)
ddx1 = dx1 / (n + 1)
ddy1 = dy1 / (n + 1)
for i in range(int(n) + 1):
painter.drawLine(pp0[0] - i * ddx0, pp0[1] - i * ddy0, pp1[0] - i * ddx1, pp1[1] - i * ddy1)
if len(self.parent.perspective_cut_pointlist) >= 3:
p0 = self.parent.perspective_cut_pointlist[1]
p1 = self.parent.perspective_cut_pointlist[2]
pp1 = (self.parent.mouse_posx, self.parent.mouse_posy)
pp0 = self.parent.perspective_cut_pointlist[0]
dx1 = pp1[0] - p1[0]
dy1 = pp1[1] - p1[1]
dx0 = pp0[0] - p0[0]
dy0 = pp0[1] - p0[1]
maxs = max(math.sqrt(dy0 ** 2 + dx0 ** 2), math.sqrt(dy1 ** 2 + dx1 ** 2))
if maxs > 25:
n = maxs // 25
ddx0 = dx0 / (n + 1)
ddy0 = dy0 / (n + 1)
ddx1 = dx1 / (n + 1)
ddy1 = dy1 / (n + 1)
for i in range(int(n) + 1):
painter.drawLine(pp0[0] - i * ddx0, pp0[1] - i * ddy0, pp1[0] - i * ddx1, pp1[1] - i * ddy1)
elif self.parent.painter_tools["polygon_ss_on"]: # 多边形截图
color = get_opposite_color(self.parent.pencolor)
for i in range(len(self.parent.polygon_ss_pointlist)):
painter.setPen(QPen(color, 3, Qt.SolidLine))
if i < len(self.parent.polygon_ss_pointlist) - 1:
painter.drawLine(self.parent.polygon_ss_pointlist[i][0],
self.parent.polygon_ss_pointlist[i][1],
self.parent.polygon_ss_pointlist[i + 1][0],
self.parent.polygon_ss_pointlist[i + 1][1])
else:
painter.drawLine(self.parent.polygon_ss_pointlist[i][0],
self.parent.polygon_ss_pointlist[i][1],
self.parent.mouse_posx, self.parent.mouse_posy)
painter.setPen(QPen(QColor(200, 200, 200, 222), 2, Qt.DashDotLine))
painter.drawLine(self.parent.polygon_ss_pointlist[0][0],
self.parent.polygon_ss_pointlist[0][1],
self.parent.mouse_posx, self.parent.mouse_posy)
elif not (self.parent.painter_tools['selectcolor_on'] or self.parent.painter_tools['bucketpainter_on']):
# 正常显示选区
rect = QRect(min(self.parent.x0, self.parent.x1), min(self.parent.y0, self.parent.y1),
abs(self.parent.x1 - self.parent.x0), abs(self.parent.y1 - self.parent.y0))
painter.setPen(QPen(Qt.green, 2, Qt.SolidLine))
painter.drawRect(rect)
painter.drawRect(0, 0, self.width(), self.height())
painter.setPen(QPen(QColor(0, 150, 0), 8, Qt.SolidLine))
painter.drawPoint(
QPoint(self.parent.x0, min(self.parent.y1, self.parent.y0) + abs(self.parent.y1 - self.parent.y0) // 2))
painter.drawPoint(
QPoint(min(self.parent.x1, self.parent.x0) + abs(self.parent.x1 - self.parent.x0) // 2, self.parent.y0))
painter.drawPoint(
QPoint(self.parent.x1, min(self.parent.y1, self.parent.y0) + abs(self.parent.y1 - self.parent.y0) // 2))
painter.drawPoint(
QPoint(min(self.parent.x1, self.parent.x0) + abs(self.parent.x1 - self.parent.x0) // 2, self.parent.y1))
painter.drawPoint(QPoint(self.parent.x0, self.parent.y0))
painter.drawPoint(QPoint(self.parent.x0, self.parent.y1))
painter.drawPoint(QPoint(self.parent.x1, self.parent.y0))
painter.drawPoint(QPoint(self.parent.x1, self.parent.y1))
x = y = 100
if self.parent.x1 > self.parent.x0:
x = self.parent.x0 + 5
else:
x = self.parent.x0 - 72
if self.parent.y1 > self.parent.y0:
y = self.parent.y0 + 15
else:
y = self.parent.y0 - 5
painter.setPen(QPen(Qt.darkGreen, 2, Qt.SolidLine))
painter.drawText(x, y,
'{}x{}'.format(abs(self.parent.x1 - self.parent.x0), abs(self.parent.y1 - self.parent.y0)))
painter.setPen(Qt.NoPen)
painter.setBrush(QColor(0, 0, 0, 120))
painter.drawRect(0, 0, self.width(), min(self.parent.y1, self.parent.y0))
painter.drawRect(0, min(self.parent.y1, self.parent.y0), min(self.parent.x1, self.parent.x0),
self.height() - min(self.parent.y1, self.parent.y0))
painter.drawRect(max(self.parent.x1, self.parent.x0), min(self.parent.y1, self.parent.y0),
self.width() - max(self.parent.x1, self.parent.x0),
self.height() - min(self.parent.y1, self.parent.y0))
painter.drawRect(min(self.parent.x1, self.parent.x0), max(self.parent.y1, self.parent.y0),
max(self.parent.x1, self.parent.x0) - min(self.parent.x1, self.parent.x0),
self.height() - max(self.parent.y1, self.parent.y0))
# 以下为鼠标放大镜
if not (self.parent.painter_tools['drawcircle_on'] or self.parent.painter_tools['drawrect_bs_on'] or
self.parent.painter_tools['pen_on'] or self.parent.painter_tools['eraser_on'] or
self.parent.painter_tools['drawtext_on'] or self.parent.painter_tools['backgrounderaser_on']
or self.parent.painter_tools['drawpix_bs_on'] or self.parent.move_rect):
select_color_mode = True if self.parent.painter_tools['selectcolor_on'] or self.parent.painter_tools['bucketpainter_on'] else False # 取色器或油漆桶
if self.parent.mouse_posx > self.width() - 140:
enlarge_box_x = self.parent.mouse_posx - 140
else:
enlarge_box_x = self.parent.mouse_posx + 20
if self.parent.mouse_posy > self.height() - 140:
enlarge_box_y = self.parent.mouse_posy - 120
else:
enlarge_box_y = self.parent.mouse_posy + 20
enlarge_rect = QRect(enlarge_box_x, enlarge_box_y, 120, 120)
painter.setPen(QPen(QColor(Qt.green), 1, Qt.SolidLine))
painter.drawRect(enlarge_rect)
painter.setBrush(QBrush(QColor(80, 80, 80, 180)))
painter.drawRect(QRect(enlarge_box_x, enlarge_box_y-43, enlarge_rect.width(), 43))
painter.setBrush(Qt.NoBrush)
# painter.drawRect(QRect(enlarge_box_x, enlarge_box_y-42, enlarge_rect.width(), 42))
color = QColor(self.parent.qimg.pixelColor(self.parent.mouse_posx, self.parent.mouse_posy))
RGB_color = [color.red(), color.green(), color.blue()]
HSV_color = cv2.cvtColor(array([[RGB_color]], dtype=uint8),cv2.COLOR_RGB2HSV).tolist()[0][0]
painter.drawText(enlarge_box_x, enlarge_box_y - 6,
' POS:({},{}) {}'.format(self.parent.mouse_posx, self.parent.mouse_posy,color.name().upper()if select_color_mode else ""))
painter.drawText(enlarge_box_x, enlarge_box_y - 18,
" HSV:({},{},{})".format(HSV_color[0], HSV_color[1], HSV_color[2]))
painter.drawText(enlarge_box_x, enlarge_box_y - 30,
" RGB:({},{},{})".format(RGB_color[0],RGB_color[1],RGB_color[2]))
if select_color_mode:
painter.setBrush(QBrush(color))
painter.drawRect(QRect(enlarge_box_x - 20, enlarge_box_y, 20, 20))
painter.setBrush(Qt.NoBrush)
try: # 鼠标放大镜
painter.setCompositionMode(QPainter.CompositionMode_Source)
rpix = QPixmap(self.width() + 120, self.height() + 120)
rpix.fill(QColor(0, 0, 0))
rpixpainter = QPainter(rpix)
rpixpainter.drawPixmap(60, 60, self.parent.pixmap())
rpixpainter.end()
larger_pix = rpix.copy(self.parent.mouse_posx, self.parent.mouse_posy, 120, 120).scaled(
120 + self.parent.tool_width * 10, 120 + self.parent.tool_width * 10)
pix = larger_pix.copy(larger_pix.width() // 2 - 60, larger_pix.height() // 2 - 60, 120, 120)
painter.drawPixmap(enlarge_box_x, enlarge_box_y, pix)
painter.setPen(QPen(Qt.green, 1, Qt.SolidLine))
painter.drawLine(enlarge_box_x, enlarge_box_y + 60, enlarge_box_x + 120, enlarge_box_y + 60)
painter.drawLine(enlarge_box_x + 60, enlarge_box_y, enlarge_box_x + 60, enlarge_box_y + 120)
except:
print('draw_enlarge_box fail')
painter.end()
class PaintLayer(QLabel):
def __init__(self, parent=None):
super().__init__(parent)
self.parent = parent
self.setAttribute(Qt.WA_TranslucentBackground, True)
# self.setAutoFillBackground(False)
# self.setPixmap(QPixmap())
self.setMouseTracking(True)
self.px = self.py = -50
self.pixpng = QPixmap(":/msk.jpg")
def paintEvent(self, e):
super().paintEvent(e)
if self.parent.on_init:
print('oninit return')
return
if 1 in self.parent.painter_tools.values(): # 如果有画笔工具打开
painter = QPainter(self)
color = QColor(self.parent.pencolor)
color.setAlpha(255)
width = self.parent.tool_width
if self.parent.painter_tools['selectcolor_on'] or self.parent.painter_tools['bucketpainter_on']:
width = 5
color = QColor(Qt.white)
painter.setPen(QPen(color, 1, Qt.SolidLine))
rect = QRectF(self.px - width // 2, self.py - width // 2,
width, width)
painter.drawEllipse(rect) # 画鼠标圆
painter.end()
# self.pixPainter.begin()
try:
self.pixPainter = QPainter(self.pixmap())
self.pixPainter.setRenderHint(QPainter.Antialiasing)
except:
print('pixpainter fail!')
while len(self.parent.eraser_pointlist): # 橡皮擦工具
# self.pixPainter.setRenderHint(QPainter.Antialiasing)
self.pixPainter.setBrush(QColor(0, 0, 0, 0))
self.pixPainter.setPen(Qt.NoPen)
self.pixPainter.setCompositionMode(QPainter.CompositionMode_Clear)
new_pen_point = self.parent.eraser_pointlist.pop(0)
if self.parent.old_pen is None:
self.parent.old_pen = new_pen_point
continue
if self.parent.old_pen[0] != -2 and new_pen_point[0] != -2:
self.pixPainter.drawEllipse(new_pen_point[0] - self.parent.tool_width / 2,
new_pen_point[1] - self.parent.tool_width / 2,
self.parent.tool_width, self.parent.tool_width)
if abs(new_pen_point[0] - self.parent.old_pen[0]) > 1 or abs(
new_pen_point[1] - self.parent.old_pen[1]) > 1:
interpolateposs = get_line_interpolation(new_pen_point[:], self.parent.old_pen[:])
if interpolateposs is not None:
for pos in interpolateposs:
x, y = pos
self.pixPainter.drawEllipse(x - self.parent.tool_width / 2,
y - self.parent.tool_width / 2,
self.parent.tool_width, self.parent.tool_width)
self.parent.old_pen = new_pen_point
def get_ture_pen_alpha_color():
color = QColor(self.parent.pencolor)
if color.alpha() != 255:
al = self.parent.pencolor.alpha() / (self.parent.tool_width / 2)
if al > 1:
color.setAlpha(al)
else:
color.setAlpha(1)
return color
while len(self.parent.pen_pointlist): # 画笔工具
color = get_ture_pen_alpha_color()
self.pixPainter.setBrush(color)
self.pixPainter.setPen(Qt.NoPen)
# self.pixPainter.setPen(QPen(self.parent.pencolor, self.parent.tool_width, Qt.SolidLine))
self.pixPainter.setRenderHint(QPainter.Antialiasing)
new_pen_point = self.parent.pen_pointlist.pop(0)
if self.parent.old_pen is None:
self.parent.old_pen = new_pen_point
continue
if self.parent.old_pen[0] != -2 and new_pen_point[0] != -2:
self.pixPainter.drawEllipse(new_pen_point[0] - self.parent.tool_width / 2,
new_pen_point[1] - self.parent.tool_width / 2,
self.parent.tool_width, self.parent.tool_width)
if abs(new_pen_point[0] - self.parent.old_pen[0]) > 1 or abs(
new_pen_point[1] - self.parent.old_pen[1]) > 1:
interpolateposs = get_line_interpolation(new_pen_point[:], self.parent.old_pen[:])
if interpolateposs is not None:
for pos in interpolateposs:
x, y = pos
self.pixPainter.drawEllipse(x - self.parent.tool_width / 2,
y - self.parent.tool_width / 2,
self.parent.tool_width, self.parent.tool_width)
self.parent.old_pen = new_pen_point
while len(self.parent.drawpix_pointlist): # 贴图工具
brush = QBrush(self.parent.pencolor)
tpix = QPixmap(self.parent.tool_width, self.parent.tool_width)
tpix.fill(Qt.transparent)
tpixpainter = QPainter(tpix)
tpixpainter.setCompositionMode(QPainter.CompositionMode_Source)
tpixpainter.drawPixmap(0, 0, self.pixpng.scaled(self.parent.tool_width, self.parent.tool_width))
tpixpainter.setCompositionMode(QPainter.CompositionMode_DestinationIn)
if self.parent.pencolor.alpha() != 255:
al = self.parent.pencolor.alpha() / (self.parent.tool_width / 2)
else:
al = 255
tpixpainter.fillRect(tpix.rect(), QColor(0, 0, 0, al))
tpixpainter.end()
brush.setTexture(tpix)
self.pixPainter.setBrush(brush)
self.pixPainter.setPen(Qt.NoPen)
new_pen_point = self.parent.drawpix_pointlist.pop(0)
if self.parent.old_pen is None:
self.parent.old_pen = new_pen_point
continue
if self.parent.old_pen[0] != -2 and new_pen_point[0] != -2:
self.pixPainter.drawEllipse(new_pen_point[0] - self.parent.tool_width / 2,
new_pen_point[1] - self.parent.tool_width / 2,
self.parent.tool_width, self.parent.tool_width)
if abs(new_pen_point[0] - self.parent.old_pen[0]) > 1 or abs(
new_pen_point[1] - self.parent.old_pen[1]) > 1:
interpolateposs = get_line_interpolation(new_pen_point[:], self.parent.old_pen[:])
if interpolateposs is not None:
for pos in interpolateposs:
x, y = pos
self.pixPainter.drawEllipse(x - self.parent.tool_width / 2,
y - self.parent.tool_width / 2,
self.parent.tool_width, self.parent.tool_width)
self.parent.old_pen = new_pen_point
if self.parent.drawrect_pointlist[0][0] != -2 and self.parent.drawrect_pointlist[1][0] != -2: # 画矩形工具
# print(self.parent.drawrect_pointlist)
temppainter = QPainter(self)
temppainter.setPen(QPen(self.parent.pencolor, self.parent.tool_width, Qt.SolidLine))
poitlist = self.parent.drawrect_pointlist
temppainter.drawRect(min(poitlist[0][0], poitlist[1][0]), min(poitlist[0][1], poitlist[1][1]),
abs(poitlist[0][0] - poitlist[1][0]), abs(poitlist[0][1] - poitlist[1][1]))
temppainter.end()
if self.parent.drawrect_pointlist[2] == 1:
self.pixPainter.setPen(QPen(self.parent.pencolor, self.parent.tool_width, Qt.SolidLine))
self.pixPainter.drawRect(min(poitlist[0][0], poitlist[1][0]), min(poitlist[0][1], poitlist[1][1]),
abs(poitlist[0][0] - poitlist[1][0]), abs(poitlist[0][1] - poitlist[1][1]))
self.parent.drawrect_pointlist = [[-2, -2], [-2, -2], 0]
# print("panit",self.parent.drawrect_pointlist)
# self.parent.drawrect_pointlist[0] = [-2, -2]
if self.parent.drawcircle_pointlist[0][0] != -2 and self.parent.drawcircle_pointlist[1][0] != -2: # 画圆工具
temppainter = QPainter(self)
temppainter.setPen(QPen(self.parent.pencolor, self.parent.tool_width, Qt.SolidLine))
poitlist = self.parent.drawcircle_pointlist
temppainter.drawEllipse(min(poitlist[0][0], poitlist[1][0]), min(poitlist[0][1], poitlist[1][1]),
abs(poitlist[0][0] - poitlist[1][0]), abs(poitlist[0][1] - poitlist[1][1]))
temppainter.end()
if self.parent.drawcircle_pointlist[2] == 1:
self.pixPainter.setPen(QPen(self.parent.pencolor, self.parent.tool_width, Qt.SolidLine))
self.pixPainter.drawEllipse(min(poitlist[0][0], poitlist[1][0]), min(poitlist[0][1], poitlist[1][1]),
abs(poitlist[0][0] - poitlist[1][0]), abs(poitlist[0][1] - poitlist[1][1]))
self.parent.drawcircle_pointlist = [[-2, -2], [-2, -2], 0]
# self.parent.drawcircle_pointlist[0] = [-2, -2]
if self.parent.drawarrow_pointlist[0][0] != -2 and self.parent.drawarrow_pointlist[1][0] != -2: # 画箭头
# print(self.parent.drawarrow_pointlist)
# self.pixPainter = QPainter(self.pixmap())
temppainter = QPainter(self)
# temppainter.setPen(QPen(self.parent.pencolor, 3, Qt.SolidLine))
# brush = QBrush(self.parent.pencolor)
# brush.setTexture(QPixmap(":/msk.jpg").scaled(225, 225))
# temppainter.setBrush(brush)
poitlist = self.parent.drawarrow_pointlist
temppainter.translate(poitlist[0][0], poitlist[0][1])
degree = math.degrees(math.atan2(poitlist[1][1] - poitlist[0][1], poitlist[1][0] - poitlist[0][0]))
temppainter.rotate(degree)
dx = math.sqrt((poitlist[1][1] - poitlist[0][1]) ** 2 + (poitlist[1][0] - poitlist[0][0]) ** 2)
dy = 30
temppainter.drawPixmap(0, -dy / 2, QPixmap(':/arrow.png').scaled(dx, dy))
temppainter.end()
if self.parent.drawarrow_pointlist[2] == 1:
self.pixPainter.translate(poitlist[0][0], poitlist[0][1])
degree = math.degrees(math.atan2(poitlist[1][1] - poitlist[0][1], poitlist[1][0] - poitlist[0][0]))
self.pixPainter.rotate(degree)
dx = math.sqrt((poitlist[1][1] - poitlist[0][1]) ** 2 + (poitlist[1][0] - poitlist[0][0]) ** 2)
dy = 30
self.pixPainter.drawPixmap(0, -dy / 2, QPixmap(':/arrow.png').scaled(dx, dy))
self.parent.drawarrow_pointlist = [[-2, -2], [-2, -2], 0]
# self.parent.drawarrow_pointlist[0] = [-2, -2]
if len(self.parent.drawtext_pointlist) > 1 or self.parent.text_box.paint: # 绘制文字
self.parent.text_box.paint = False
# print(self.parent.drawtext_pointlist)
text = self.parent.text_box.toPlainText()
self.parent.text_box.clear()
pos = self.parent.drawtext_pointlist.pop(0)
if text:
self.pixPainter.setFont(QFont('黑体', self.parent.tool_width))
self.pixPainter.setPen(QPen(self.parent.pencolor, 3, Qt.SolidLine))
self.pixPainter.drawText(pos[0] + self.parent.text_box.document.size().height() / 8,
pos[1] + self.parent.text_box.document.size().height() * 32 / 41, text)
self.parent.backup_shortshot()
self.parent.setFocus()
self.update()
# self.repaint()
try:
self.pixPainter.end()
except:
print("pixpainter end fail!")
class AutotextEdit(QTextEdit):
def __init__(self, parent=None):
super().__init__(parent)
self.document = self.document()
self.document.contentsChanged.connect(self.textAreaChanged)
self.setLineWrapMode(QTextEdit.NoWrap)
self.paint = False
self.parent = parent
def textAreaChanged(self, minsize=0):
self.document.adjustSize()
newWidth = self.document.size().width() + 25
newHeight = self.document.size().height() + 15
if newWidth != self.width():
if newWidth < minsize:
self.setFixedWidth(minsize)
else:
self.setFixedWidth(newWidth)
if newHeight != self.height():
if newHeight < minsize:
self.setFixedHeight(minsize)
else:
self.setFixedHeight(newHeight)
def keyPressEvent(self, e):
if e.key() == Qt.Key_Return:
self.paint = True
self.hide()
super().keyPressEvent(e)
def keyReleaseEvent(self, e):
if e.key() == Qt.Key_Return:
self.parent.update()
super().keyReleaseEvent(e)
class Slabel(QLabel): # 区域截图功能
showm_signal = pyqtSignal(str)
recorder_recordchange_signal = pyqtSignal()
close_signal = pyqtSignal()
ocr_image_signal = pyqtSignal(str)
screen_shot_result_signal = pyqtSignal(str)
screen_shot_end_show_sinal = pyqtSignal(QPixmap)
set_area_result_signal = pyqtSignal(list)
getpix_result_signal = pyqtSignal(tuple,QPixmap)
def __init__(self, parent=None):
super().__init__()
# self.ready_flag = False
self.parent = parent
if not os.path.exists("j_temp"):
os.mkdir("j_temp")
# self.pixmap()=QPixmap()
def setup(self,mode = "screenshot"): # 初始化界面
self.on_init = True
self.mode = mode
self.paintlayer = PaintLayer(self) # 绘图层
self.mask = MaskLayer(self) # 遮罩层
self.text_box = AutotextEdit(self) # 文字工具类
self.ocr_freezer = None
self.shower = FramelessEnterSendQTextEdit(self, enter_tra=True) # 截屏时文字识别的小窗口
self.settings = QSettings('Fandes', 'jamtools')
self.setMouseTracking(True)
if PLATFORM_SYS == "darwin":
self.setWindowFlags(Qt.FramelessWindowHint)
else:
self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint) # Sheet
# self.setAttribute(Qt.WA_TransparentForMouseEvents, True)
self.botton_box = QGroupBox(self) # botton_box是截屏选框旁边那个按钮堆的box
self.save_botton = QPushButton(QIcon(":/saveicon.png"), '', self.botton_box)
self.save_botton.clicked.connect(lambda: self.cutpic(1))
self.ssrec_botton = QPushButton(QIcon(":/ssrecord.png"), '', self.botton_box)
self.ocr_botton = QPushButton(self.botton_box)
self.roll_ss_btn = QPushButton(self.botton_box)
self.sure_btn = QPushButton("确定", self.botton_box)
self.freeze_img_botton = QPushButton(self.botton_box)
self.pencolor = QColor(Qt.red)
self.painter_box = CanMoveGroupbox(self) # painter_box是绘图工具堆里的那个box,可移动
self.choice_clor_btn = HoverButton('', self.painter_box)
self.selectcolor_btn = QPushButton("", self.painter_box)
self.original_btn = QPushButton("", self.painter_box)
self.size_slider = QSlider(Qt.Vertical, self.painter_box)
self.alpha_slider = QSlider(Qt.Vertical, self.painter_box)
self.sizetextlabel = QLabel(self.painter_box)
self.alphatextlabel = QLabel(self.painter_box)
self.size_slider_label = QLabel(self.painter_box)
self.alpha_slider_label = QLabel(self.painter_box)
self.drawarrow = QPushButton('', self.painter_box)
self.msk = QPushButton('', self.painter_box)
self.choise_pix = QPushButton('', self.painter_box)
self.drawcircle = QPushButton('', self.painter_box)
self.bs = QPushButton('', self.painter_box)
self.drawtext = QPushButton('', self.painter_box)
self.pen = QPushButton('', self.painter_box)
self.eraser = QPushButton('', self.painter_box)
self.backgrounderaser = QPushButton('', self.painter_box)
self.smartcursor_btn = QPushButton('', self.painter_box)
self.bucketpainter_btn = QPushButton("", self.painter_box)
self.bucketpainter_tolerance = QSpinBox(self.painter_box)
self.backgroundrepair_btn = QPushButton("", self.painter_box)
self.perspective_cut_btn = QPushButton("", self.painter_box)
self.polygon_ss_btn = QPushButton("", self.painter_box)
self.lastbtn = QPushButton("", self.painter_box)
self.nextbtn = QPushButton("", self.painter_box)
self.finder = Finder(self) # 智能选区的寻找器
self.Tipsshower = TipsShower(" ", targetarea=(100, 70, 0, 0), parent=self) # 左上角的大字提示
self.Tipsshower.hide()
self.shower.showm_signal.connect(self.Tipsshower.setText)
if PLATFORM_SYS == "darwin":
self.init_slabel_ui()
print("init slabel ui")
else:
self.init_slabel_ui()
print("init slabel ui")
# self.init_slabel_thread = Commen_Thread(self.init_slabel_ui)
# self.init_slabel_thread.start()
if mode != "screenshot":#非截屏模式(jamtools中也会调用截屏工具进行选取录屏或者文字识别)
self.painter_box.hide()
self.save_botton.hide()
self.freeze_img_botton.hide()
self.roll_ss_btn.hide()
self.ocr_botton.hide()
elif mode != "set_area":
self.ssrec_botton.hide()
# self.setVisible(False)
# self.setWindowOpacity(0)
# self.showFullScreen()
# self.hide()
# self.setWindowOpacity(1)
self.init_parameters()
self.backup_ssid = 0 # 当前备份数组的id,用于确定回退了几步
self.backup_pic_list = [] # 备份页面的数组,用于前进/后退
self.on_init = False
def init_parameters(self): # 初始化参数
self.NpainterNmoveFlag = self.choicing = self.move_rect = self.move_y0 = self.move_x0 = self.move_x1 \
= self.change_alpha = self.move_y1 = False
self.x0 = self.y0 = self.rx0 = self.ry0 = self.x1 = self.y1 = self.mouse_posx = self.mouse_posy = -50
self.bx = self.by = 0
self.alpha = 255 # 透明度值
self.smartcursor_on = self.settings.value("screenshot/smartcursor", True, type=bool)
self.finding_rect = True # 正在自动寻找选取的控制变量,就进入截屏之后会根据鼠标移动到的位置自动选取,
self.tool_width = 5
self.roller_area = (0, 0, 1, 1)
self.backgrounderaser_pointlist = [] # 下面xxpointlist都是储存绘图数据的列表
self.eraser_pointlist = []
self.pen_pointlist = []
self.drawpix_pointlist = []
self.repairbackground_pointlist = []
self.drawtext_pointlist = []
self.perspective_cut_pointlist = []
self.polygon_ss_pointlist = []
self.drawrect_pointlist = [[-2, -2], [-2, -2], 0]
self.drawarrow_pointlist = [[-2, -2], [-2, -2], 0]
self.drawcircle_pointlist = [[-2, -2], [-2, -2], 0]
self.painter_tools = {'drawpix_bs_on': 0, 'drawarrow_on': 0, 'drawcircle_on': 0, 'drawrect_bs_on': 0,
'pen_on': 0, 'eraser_on': 0, 'drawtext_on': 0,
'backgrounderaser_on': 0, 'selectcolor_on': 0, "bucketpainter_on": 0,
"repairbackground_on": 0, "perspective_cut_on": 0, "polygon_ss_on": 0}
self.old_pen = self.old_eraser = self.old_brush = self.old_backgrounderaser = [-2, -2]
self.left_button_push = False
def init_slabel_ui(self): # 初始化界面的参数
self.shower.hide()
# self.shower.setWindowOpacity(0.8)
# if PLATFORM_SYS == "darwin":
# self.move(-QApplication.desktop().width(), -QApplication.desktop().height())
self.setToolTip("左键框选,右键返回")
self.ssrec_botton.setGeometry(0, 0, 40, 35)
self.ssrec_botton.clicked.connect(self.ssrec)
self.ssrec_botton.setToolTip('开始录屏')
self.save_botton.setGeometry(self.ssrec_botton.x() + self.ssrec_botton.width(), 0, 40, 35)
self.save_botton.setToolTip('另存为文件')
self.freeze_img_botton.setGeometry(self.save_botton.x() + self.save_botton.width(), 0, 40, 35)
self.freeze_img_botton.setIcon(QIcon(":/freeze.png"))
self.freeze_img_botton.setToolTip('固定图片于屏幕上')
self.freeze_img_botton.clicked.connect(self.freeze_img)
self.ocr_botton.setGeometry(self.freeze_img_botton.x() + self.freeze_img_botton.width(), 0, 40, 35)
self.ocr_botton.setIcon(QIcon(":/OCR.png"))
self.ocr_botton.setToolTip('文字识别')
self.ocr_botton.clicked.connect(self.ocr)
if PLATFORM_SYS == "darwin": # 不支持macos滚动截屏
self.roll_ss_btn.hide()
self.sure_btn.setGeometry(self.ocr_botton.x() + self.ocr_botton.width(), 0, 60, 35)
else:
self.roll_ss_btn.setGeometry(self.ocr_botton.x() + self.ocr_botton.width(), 0, 40, 35)
self.roll_ss_btn.clicked.connect(self.roll_shot)
self.roll_ss_btn.setToolTip('滚动截屏功能')
self.roll_ss_btn.setIcon(QIcon(":/scroll_icon.png"))
self.sure_btn.setGeometry(self.roll_ss_btn.x() + self.roll_ss_btn.width(), 0, 60, 35)
self.sure_btn.clicked.connect(self.cutpic)
a = self.roll_ss_btn.width() if PLATFORM_SYS != "darwin" else 0
if self.mode == "screenshot":
self.botton_box.resize(
self.sure_btn.width() + self.ocr_botton.width() + self.ssrec_botton.width()
+ a + self.save_botton.width() + self.freeze_img_botton.width(),
self.sure_btn.height())
elif self.mode == "set_area":
self.Tipsshower.setText("设置录屏区域...")
self.sure_btn.setGeometry(self.ssrec_botton.x() + self.ssrec_botton.width(), 0, 60, 35)
self.botton_box.resize(
self.sure_btn.width()+self.ssrec_botton.width(),
self.sure_btn.height())
else:
self.sure_btn.setGeometry(0, 0, 60, 35)
self.botton_box.resize(
self.sure_btn.width(),
self.sure_btn.height())
self.botton_box.hide()
self.painter_box.setGeometry(0, QApplication.desktop().height() // 2 - 200, 100, 400)
self.size_slider_label.setStyleSheet('background-color:rgba(0,0,0,0);color: rgb(255,255,255);')
self.size_slider_label.resize(20, 20)
self.size_slider.setGeometry(10, 20, 25, 60)
self.size_slider.setToolTip('设置画笔大小,也可用鼠标滚轮调节')
self.size_slider.valueChanged.connect(self.change_size_fun)
self.sizetextlabel.setText("size")
self.sizetextlabel.setGeometry(self.size_slider.x() - 2, self.size_slider.y() + self.size_slider.height() - 2,
35, 20)
self.sizetextlabel.setStyleSheet('background-color:rgba(0,0,0,0);color: rgb(255,255,255);')
self.size_slider.setMaximum(99)
self.size_slider.setValue(5)
self.size_slider.setMinimum(1)
self.size_slider_label.move(self.size_slider.x() + 5, 0)
self.size_slider.show()
self.alpha_slider_label.setStyleSheet('background-color:rgba(0,0,0,0);color: rgb(255,255,255);')
self.alpha_slider_label.resize(25, 20)
self.alpha_slider.setGeometry(55, 20, 25, 60)
self.alpha_slider.setToolTip('设置画笔透明度,按住Ctrl+滚轮也可以调节透明度')
self.alpha_slider.valueChanged.connect(self.change_alpha_fun)
self.alphatextlabel.setText("alpha")
self.alphatextlabel.setGeometry(self.alpha_slider.x() - 4,
self.alpha_slider.y() + self.alpha_slider.height() - 2,
40, 20)
self.alphatextlabel.setStyleSheet('background-color:rgba(0,0,0,0);color: rgb(255,255,255);')
self.alpha_slider.setMaximum(255)
self.alpha_slider.setValue(255)
self.alpha_slider.setMinimum(1)
self.alpha_slider_label.move(self.alpha_slider.x() + 2, 0)
self.alpha_slider.show()
# print(pic)
self.choice_clor_btn.setToolTip('选择画笔颜色,点击可选择更多')
self.choice_clor_btn.setIcon(QIcon(":/yst.png"))
self.choice_clor_btn.setGeometry(4, 100, 41, 28)
self.choice_clor_btn.clicked.connect(self.get_color)
self.choice_clor_btn.hoversignal.connect(self.Color_hoveraction)
self.selectcolor_btn.setIcon(QIcon(":/colorsampler.png"))
self.selectcolor_btn.setGeometry(50, self.choice_clor_btn.y(), self.choice_clor_btn.width(),
self.choice_clor_btn.height())
self.selectcolor_btn.setToolTip("取色器")
self.selectcolor_btn.clicked.connect(self.selectcolor)
self.msk.setToolTip('材质贴图工具,可以充当马赛克')
self.msk.setIcon(QIcon(":/mskicon.png"))
self.msk.setGeometry(self.choice_clor_btn.x(), self.choice_clor_btn.y() + self.choice_clor_btn.height(),
self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.msk.clicked.connect(self.change_msk_fun)
self.choise_pix.setToolTip('选择笔刷材质贴图')
self.choise_pix.setIcon(QIcon(":/msk.jpg"))
self.choise_pix.setGeometry(35, self.msk.y(), self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.choise_pix.clicked.connect(self.choise_drawpix_fun)
self.choise_pix.setStyleSheet("background-color:rgb(255,255,255);border: 3px solid #ffffff;")
self.choise_pix.hide()
self.drawarrow.setToolTip('绘制箭头')
self.drawarrow.setIcon(QIcon(":/arrowicon.png"))
self.drawarrow.setGeometry(self.selectcolor_btn.x(), self.selectcolor_btn.y() + self.selectcolor_btn.height(),
self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.drawarrow.clicked.connect(self.draw_arrow_fun)
self.drawcircle.setToolTip('绘制圆')
self.drawcircle.setIcon(QIcon(":/circle.png"))
self.drawcircle.setGeometry(self.choice_clor_btn.x(), self.msk.y() + self.msk.height(),
self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.drawcircle.clicked.connect(self.drawcircle_fun)
self.bs.setToolTip('绘制矩形')
self.bs.setIcon(QIcon(":/rect.png"))
self.bs.setGeometry(self.drawarrow.x(), self.drawarrow.y() + self.drawarrow.height(),
self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.bs.clicked.connect(self.change_bs_fun)
self.drawtext.setToolTip('绘制文字')
self.drawtext.setIcon(QIcon(":/texticon.png"))
self.drawtext.setGeometry(self.choice_clor_btn.x(), self.drawcircle.y() + self.drawcircle.height(),
self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.drawtext.clicked.connect(self.drawtext_fun)
self.pen.setToolTip('画笔工具')
self.pen.setIcon(QIcon(":/pen.png"))
self.pen.setGeometry(self.bs.x(), self.bs.y() + self.bs.height(),
self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.pen.clicked.connect(self.change_pen_fun)
self.eraser.setToolTip('橡皮擦')
self.eraser.setIcon(QIcon(":/eraser.png"))
self.eraser.setGeometry(self.choice_clor_btn.x(), self.drawtext.y() + self.drawtext.height(),
self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.eraser.clicked.connect(self.clear_paint_fun)
self.backgrounderaser.setIcon(QIcon(":/backgrounderaser.png"))
self.backgrounderaser.setToolTip('背景橡皮擦,图片包含透明通道,擦除部分图片将变透明,\n但由于win的剪切板不支持透明通道,只有另存时透明通道才有作用!')
self.backgrounderaser.setGeometry(self.pen.x(), self.pen.y() + self.pen.height(),
self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.backgrounderaser.clicked.connect(self.clear_background_fun)
self.backgroundrepair_btn.setIcon(QIcon(":/backgroundrepair.png"))
self.backgroundrepair_btn.setToolTip('背景修复画笔,用于将背景图片层复原')
self.backgroundrepair_btn.setGeometry(self.backgrounderaser.x(),
self.backgrounderaser.y() + self.backgrounderaser.height(),
self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.backgroundrepair_btn.clicked.connect(self.repair_background_fun)
self.bucketpainter_btn.setToolTip("油漆桶工具")
self.bucketpainter_btn.setIcon(QIcon(":/yqt.png"))
self.bucketpainter_btn.setGeometry(self.choice_clor_btn.x(),
self.backgrounderaser.y() + self.backgrounderaser.height(),
self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.bucketpainter_btn.clicked.connect(self.bucketpaint)
self.bucketpainter_tolerance.setToolTip('设置填充容差')
self.bucketpainter_tolerance.setGeometry(self.choice_clor_btn.x(), self.painter_box.height() - 30, 85, 25)
self.bucketpainter_tolerance.setMaximum(255)
self.bucketpainter_tolerance.setPrefix("容差")
self.bucketpainter_tolerance.setValue(self.settings.value("screenshot/tolerance", 0, int))
self.bucketpainter_tolerance.setStyleSheet(
"border: 2px solid rgb(200,200,200);color:rgb(255,255,255);background-color:rgb(110,110,120);border-radius:2px;")
self.bucketpainter_tolerance.valueChanged.connect(self.bucketpainter_tolerancechange)
self.bucketpainter_tolerance.hide()
self.polygon_ss_btn.setToolTip("多边形截图")
self.polygon_ss_btn.setIcon(QIcon(":/polygon_ss.png"))
self.polygon_ss_btn.setGeometry(self.choice_clor_btn.x(),
self.bucketpainter_btn.y() + self.bucketpainter_btn.height(),
self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.polygon_ss_btn.clicked.connect(self.polygon_ss)
self.perspective_cut_btn.setToolTip("透视裁剪工具")
self.perspective_cut_btn.setIcon(QIcon(":/perspective.png"))
self.perspective_cut_btn.setGeometry(self.backgroundrepair_btn.x(),
self.backgroundrepair_btn.y() + self.backgroundrepair_btn.height(),
self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.perspective_cut_btn.clicked.connect(self.perspective_cut)
self.smartcursor_btn.setToolTip("智能选区")
self.smartcursor_btn.setIcon(QIcon(":/smartcursor.png"))
self.smartcursor_btn.setGeometry(self.choice_clor_btn.x(),
self.polygon_ss_btn.y() + self.polygon_ss_btn.height(),
self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.smartcursor_btn.clicked.connect(self.change_smartcursor)
self.original_btn.setIcon(QIcon(":/original.png"))
self.original_btn.setGeometry(self.perspective_cut_btn.x(),
self.perspective_cut_btn.y() + self.perspective_cut_btn.height(),
self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.original_btn.setToolTip("还原所有")
self.original_btn.clicked.connect(self.setoriginalpix)
self.lastbtn.setToolTip("上一步Ctrl+Z")
self.lastbtn.setIcon(QIcon(":/last.png"))
self.lastbtn.setGeometry(self.smartcursor_btn.x(), self.smartcursor_btn.y() + self.smartcursor_btn.height(),
self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.lastbtn.clicked.connect(self.last_step)
self.nextbtn.setToolTip("下一步Ctrl+Y")
self.nextbtn.setIcon(QIcon(":/next.png"))
self.nextbtn.setGeometry(self.original_btn.x(), self.original_btn.y() + self.original_btn.height(),
self.choice_clor_btn.width(), self.choice_clor_btn.height())
self.nextbtn.clicked.connect(self.next_step)
print(1)
tipsfont = QFont("黑体", 35)
# tipsfont.setBold(True)
self.Tipsshower.setFont(tipsfont)
self.choice_clor_btn.setStyleSheet('background-color:rgb(255,0,0);')
if self.settings.value("screenshot/smartcursor", True, type=bool):
self.smartcursor_btn.setStyleSheet("background-color:rgb(50,50,50);")
def ssrec(self): # 录屏函数
self.parent.setingarea = True
self.cutpic()
self.recorder_recordchange_signal.emit()
# recorder.recordchange()
def Color_hoveraction(self, hover): # 鼠标滑过选色按钮时触发的
if hover:
try:
self.closenomalcolorboxtimer.stop()
self.nomalcolorbox.show()
print("nomalcolorbox show")
except AttributeError:
self.nomalcolorbox = HoverGroupbox(self)
self.closenomalcolorboxtimer = QTimer(self)
btnscolors = [Qt.red, Qt.darkRed, Qt.green, Qt.darkGreen, Qt.blue, Qt.darkBlue, Qt.yellow,
Qt.darkYellow,
Qt.darkCyan, Qt.darkMagenta, Qt.white, QColor(200, 200, 200), Qt.gray, Qt.darkGray,
Qt.black,
QColor(50, 50, 50)]
y1 = 0
y2 = 30
d = 30
for i in range((len(btnscolors) + 1) // 2):
btn1 = ColorButton(btnscolors[2 * i], self.nomalcolorbox)
btn1.resize(d, d)
btn1.select_color_signal.connect(self.selectnomal_color)
btn1.move(5 + i * d, y1)
if len(btnscolors) > 2 * i + 1:
btn2 = ColorButton(btnscolors[2 * i + 1], self.nomalcolorbox)
btn2.resize(d, d)
btn2.select_color_signal.connect(self.selectnomal_color)
btn2.move(5 + i * d, y2)
self.nomalcolorbox.setGeometry(
self.painter_box.x() + self.choice_clor_btn.x() + self.choice_clor_btn.width() + 1,
self.painter_box.y() + self.choice_clor_btn.y() + self.choice_clor_btn.height() - y2 * 2,
(len(btnscolors) // 2 + 1) * 50 + 10, y2 * 2)
except:
print(sys.exc_info(), 1150)
self.nomalcolorbox.hoversignal.connect(self.closenomalcolorboxsignalhandle)
self.nomalcolorbox.show()
self.nomalcolorbox.raise_()
self.closenomalcolorboxtimer.timeout.connect(self.closenomalcolorbox)
self.closenomalcolorboxtimer.start(2000)
# self.refresh_hideclosenomalsignal()
# else:
def closenomalcolorboxsignalhandle(self, s): # 关闭常见颜色浮窗的函数
if s:
try:
self.closenomalcolorboxtimer.stop()
except:
print(sys.exc_info(), 1162)
else:
print("离开box信号", s)
self.closenomalcolorboxtimer.start(1000)
def closenomalcolorbox(self):
try:
self.nomalcolorbox.hide()
self.closenomalcolorboxtimer.stop()
self.nomalcolorbox = None
except:
print(sys.exc_info())
def selectnomal_color(self, color):
# print(color)
self.get_color(QColor(color))
# self.nomalcolorbox = None
def get_color(self, color: QColor = None): # 选择颜色
if type(color) is not QColor:
self.Tipsshower.setText("选择颜色")
try:
self.nomalcolorbox.hide()
except:
print(sys.exc_info())
colordialog = QColorDialog(self)
colordialog.setCurrentColor(self.pencolor)
colordialog.setOption(QColorDialog.ShowAlphaChannel)
colordialog.exec()
self.pencolor = colordialog.currentColor()
else:
self.pencolor = color
self.alpha_slider.setValue(self.pencolor.alpha())
self.text_box.setTextColor(self.pencolor)
self.choice_clor_btn.setStyleSheet('background-color:{0};'.format(self.pencolor.name()))
def bucketpainter_tolerancechange(self, value):
self.settings.setValue("screenshot/tolerance", value)
def bucketpaint(self): # 油漆桶工具
if self.painter_tools['bucketpainter_on']:
self.painter_tools['bucketpainter_on'] = 0
self.bucketpainter_btn.setStyleSheet('')
self.bucketpainter_tolerance.hide()
else:
self.change_tools_fun('bucketpainter_on')
self.bucketpainter_btn.setStyleSheet('background-color:rgb(50,50,50)')
self.Tipsshower.setText("油漆桶工具")
self.bucketpainter_tolerance.show()
self.setCursor(QCursor(QPixmap(":/yqt.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
def polygon_ss(self): # 透视裁剪工具
if self.painter_tools['polygon_ss_on']:
self.painter_tools['polygon_ss_on'] = 0
self.polygon_ss_btn.setStyleSheet('')
self.polygon_ss_pointlist = []
self.update()
else:
self.change_tools_fun('polygon_ss_on')
self.polygon_ss_btn.setStyleSheet('background-color:rgb(50,50,50)')
self.Tipsshower.setText("多边形截图工具")
self.botton_box.hide()
self.setCursor(QCursor(QPixmap(":/polygon_ss.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
self.polygon_ss_pointlist = []
QApplication.processEvents()
def perspective_cut(self):
if self.painter_tools['perspective_cut_on']:
self.painter_tools['perspective_cut_on'] = 0
self.perspective_cut_btn.setStyleSheet('')
self.perspective_cut_pointlist = []
else:
self.change_tools_fun('perspective_cut_on')
self.perspective_cut_btn.setStyleSheet('background-color:rgb(50,50,50)')
self.Tipsshower.setText("透视裁剪工具")
self.botton_box.hide()
self.setCursor(QCursor(QPixmap(":/perspective.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
self.perspective_cut_pointlist = []
def change_smartcursor(self):
self.settings.setValue("screenshot/smartcursor",
not self.settings.value("screenshot/smartcursor", True, type=bool))
if self.settings.value("screenshot/smartcursor", True, type=bool):
self.smartcursor_btn.setStyleSheet("background-color:rgb(50,50,50);")
self.smartcursor_on = True
self.Tipsshower.setText("智能选区:开")
else:
self.smartcursor_on = False
self.smartcursor_btn.setStyleSheet("")
self.Tipsshower.setText("智能选区:关")
def selectcolor(self):
if self.painter_tools['selectcolor_on']:
self.painter_tools['selectcolor_on'] = 0
self.selectcolor_btn.setStyleSheet('')
else:
self.change_tools_fun('selectcolor_on')
self.selectcolor_btn.setStyleSheet('background-color:rgb(50,50,50)')
self.Tipsshower.setText("取色器")
self.setCursor(QCursor(QPixmap(":/colorsampler.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
allpix = self.cutpic(save_as=3)
self.qimg = allpix.toImage()
def setoriginalpix(self):
self.change_tools_fun("")
self.setCursor(Qt.ArrowCursor)
self.screen_shot(self.originalPix)
self.Tipsshower.setText("已清除所有修改!")
def drawcircle_fun(self):
if self.painter_tools['drawcircle_on']:
self.painter_tools['drawcircle_on'] = 0
self.drawcircle.setStyleSheet('')
else:
self.change_tools_fun('drawcircle_on')
self.drawcircle.setStyleSheet('background-color:rgb(50,50,50)')
self.setCursor(QCursor(QPixmap(":/circle.png").scaled(32, 32, Qt.KeepAspectRatio), 16, 16))
if self.tool_width > 6:
self.size_slider.setValue(6)
if self.alpha < 200:
self.alpha_slider.setValue(255)
self.Tipsshower.setText("圆形框工具")
def draw_arrow_fun(self):
if self.painter_tools['drawarrow_on']:
self.painter_tools['drawarrow_on'] = 0
self.drawarrow.setStyleSheet('')
else:
self.change_tools_fun('drawarrow_on')
self.drawarrow.setStyleSheet('background-color:rgb(50,50,50)')
self.setCursor(QCursor(QPixmap(":/arrowicon.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
self.Tipsshower.setText("箭头工具")
def drawtext_fun(self):
if self.painter_tools['drawtext_on']:
self.painter_tools['drawtext_on'] = 0
self.drawtext.setStyleSheet('')
else:
self.change_tools_fun('drawtext_on')
self.drawtext.setStyleSheet('background-color:rgb(50,50,50)')
self.setCursor(QCursor(QPixmap(":/texticon.png").scaled(16, 16, Qt.KeepAspectRatio), 0, 0))
self.Tipsshower.setText("绘制文本")
def change_pen_fun(self):
if self.painter_tools['pen_on']:
self.painter_tools['pen_on'] = 0
self.pen.setStyleSheet('')
else:
self.change_tools_fun('pen_on')
self.pen.setStyleSheet('background-color:rgb(50,50,50)')
self.Tipsshower.setText("画笔")
self.setCursor(QCursor(QPixmap(":/pen.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
def clear_paint_fun(self):
if self.painter_tools['eraser_on']:
self.painter_tools['eraser_on'] = 0
self.eraser.setStyleSheet('')
else:
self.change_tools_fun('eraser_on')
self.eraser.setStyleSheet('background-color:rgb(50,50,50)')
self.setCursor(QCursor(QPixmap(":/eraser.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
self.Tipsshower.setText("画笔橡皮擦")
def repair_background_fun(self):
if self.painter_tools['repairbackground_on']:
self.painter_tools['repairbackground_on'] = 0
self.backgroundrepair_btn.setStyleSheet('')
else:
self.change_tools_fun('repairbackground_on')
self.backgroundrepair_btn.setStyleSheet('background-color:rgb(50,50,50)')
self.Tipsshower.setText("背景还原画笔")
self.setCursor(QCursor(QPixmap(":/backgroundrepair.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 26))
def clear_background_fun(self):
if self.painter_tools['backgrounderaser_on']:
self.painter_tools['backgrounderaser_on'] = 0
self.backgrounderaser.setStyleSheet('')
else:
self.change_tools_fun('backgrounderaser_on')
self.backgrounderaser.setStyleSheet('background-color:rgb(50,50,50)')
self.Tipsshower.setText("背景橡皮擦")
self.setCursor(QCursor(QPixmap(":/backgrounderaser.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
def change_size_fun(self):
self.size_slider_label.setText(str(self.size_slider.value()))
self.tool_width = self.size_slider.value()
def change_alpha_fun(self):
self.alpha_slider_label.setText(str(self.alpha_slider.value()))
self.alpha = self.alpha_slider.value()
self.pencolor.setAlpha(self.alpha)
def change_tools_fun(self, r): # 更改工具时统一调用的函数,用于重置所有样式
self.pen.setStyleSheet('')
self.bs.setStyleSheet('')
self.eraser.setStyleSheet('')
self.backgrounderaser.setStyleSheet('')
self.msk.setStyleSheet('')
self.drawarrow.setStyleSheet('')
self.drawcircle.setStyleSheet('')
self.drawtext.setStyleSheet('')
self.selectcolor_btn.setStyleSheet("")
self.bucketpainter_btn.setStyleSheet("")
self.backgroundrepair_btn.setStyleSheet("")
self.perspective_cut_btn.setStyleSheet('')
self.polygon_ss_btn.setStyleSheet('')
self.text_box.clear()
self.text_box.hide()
self.choise_pix.hide()
self.bucketpainter_tolerance.hide()
for tool in self.painter_tools:
if tool == r:
self.painter_tools[tool] = 1
else:
self.painter_tools[tool] = 0
self.update()
def change_msk_fun(self):
if self.painter_tools['drawpix_bs_on']:
self.painter_tools['drawpix_bs_on'] = 0
self.msk.setStyleSheet('')
self.choise_pix.hide()
else:
self.change_tools_fun('drawpix_bs_on')
self.msk.setStyleSheet('background-color:rgb(50,50,50)')
self.choise_pix.show()
self.Tipsshower.setText("材质画笔工具")
self.setCursor(QCursor(self.paintlayer.pixpng.scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
def change_bs_fun(self):
# print('cahngegbs')
if self.painter_tools['drawrect_bs_on']:
self.painter_tools['drawrect_bs_on'] = 0
self.bs.setStyleSheet('')
else:
self.change_tools_fun('drawrect_bs_on')
self.bs.setStyleSheet('background-color:rgb(50,50,50)')
if self.tool_width > 6:
self.size_slider.setValue(6)
if self.alpha < 200:
self.alpha_slider.setValue(255)
self.Tipsshower.setText("矩形框工具")
self.setCursor(QCursor(QPixmap(":/rect.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 30))
def choise_drawpix_fun(self):
self.Tipsshower.setText("设置材质")
pic, l = QFileDialog.getOpenFileName(self, "选择图片", QStandardPaths.writableLocation(
QStandardPaths.PicturesLocation), "img Files (*.PNG *.jpg *.JPG *.JPEG *.BMP *.ICO)"
";;all files(*.*)")
if pic:
self.paintlayer.pixpng = QPixmap(pic)
self.choise_pix.setIcon(QIcon(pic))
def search_in_which_screen(self):
mousepos=Controller().position
screens = QApplication.screens()
secondscreen = QApplication.primaryScreen()
for i in screens:
rect=i.geometry().getRect()
if mousepos[0]in range(rect[0],rect[0]+rect[2]) and mousepos[1]in range(rect[1],rect[1]+rect[3]):
secondscreen = i
break
print("t", self.x(), QApplication.desktop().width(),QApplication.primaryScreen().geometry(),secondscreen.geometry(),mousepos)
return secondscreen
def screen_shot(self, pix=None,mode = "screenshot"):
"""mode: screenshot 、orc、set_area、getpix。screenshot普通截屏;非截屏模式:orc获取ocr源图片; set_area用于设置区域、getpix提取区域"""
# 截屏函数,功能有二:当有传入pix时直接显示pix中的图片作为截屏背景,否则截取当前屏幕作为背景;前者用于重置所有修改
# if PLATFORM_SYS=="darwin":
self.sshoting = True
t1 = time.process_time()
pixRat = QWindow().devicePixelRatio()
if type(pix) is QPixmap:
get_pix = pix
self.init_parameters()
else:
self.setup(mode) # 初始化截屏
if QApplication.desktop().screenCount()>1:
sscreen=self.search_in_which_screen()
else:
sscreen=QApplication.primaryScreen()
get_pix = sscreen.grabWindow(0) # 截取屏幕
get_pix.setDevicePixelRatio(pixRat)
pixmap = QPixmap(get_pix.width(), get_pix.height())
pixmap.setDevicePixelRatio(pixRat)
pixmap.fill(Qt.transparent) # 填充透明色,不然没有透明通道
painter = QPainter(pixmap)
# painter.setRenderHint(QPainter.Antialiasing)
painter.drawPixmap(0, 0, get_pix)
painter.end() # 一定要end
self.originalPix = pixmap.copy()
self.setPixmap(pixmap)
self.mask.setGeometry(0, 0, get_pix.width(), get_pix.height())
self.mask.show()
# self.paintlayer.__init__(self)
# self.paintlayer.pixpng = ":/msk.jpg"
self.paintlayer.setGeometry(0, 0, get_pix.width(), get_pix.height())
self.paintlayer.setPixmap(QPixmap(get_pix.width(), get_pix.height()))
self.paintlayer.pixmap().fill(Qt.transparent) # 重点,不然不透明
self.paintlayer.show()
self.text_box.hide()
self.botton_box.hide()
# self.setGeometry(0, 0, pix.width(), pix.height()) # 全屏必须在所有控件画完再进行
self.setWindowOpacity(1)
# self.showNormal()
self.showFullScreen()
if type(pix) is not QPixmap:
self.backup_ssid = 0
self.backup_pic_list = [self.originalPix.copy()]
self.init_ss_thread_fun(get_pix)
self.paintlayer.pixpng = QPixmap(":/msk.jpg")
self.text_box.setTextColor(self.pencolor)
# 以下设置样式
self.text_box.setStyleSheet("background-color: rgba(0, 0, 0, 10);")
self.setStyleSheet("QPushButton{color:black;background-color:rgb(239,239,239);padding:1px 4px;}"
"QPushButton:hover{color:green;background-color:rgb(200,200,100);}"
"QGroupBox{border:none;}")
self.painter_box.setStyleSheet("QPushButton{color:black;background-color:rgb(100,100,100);padding:-1px -1px;}"
"QPushButton:hover{color:green;background-color:rgb(200,200,200);padding:1px 1px;}"
"QGroupBox{border: 2px solid rgb(200,200,200);background-color:rgba(110,110,120,222);border-radius:6px;}"
"""QSlider{background-color: rgba(0,0,0,0);
border-style: outset;
border-radius: 2px;}
QSlider::handle
{background: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 white, stop:1 green);
width: 16px;
height: 5px;
margin: -5px 5px -5px 5px;
border-radius:5px;
border: 3px solid #ffffff;
}"""
)
print('sstime:', time.process_time() - t1)
self.setFocus()
self.setMouseTracking(True)
self.activateWindow()
self.raise_()
self.update()
QApplication.processEvents()
def init_ss_thread_fun(self, get_pix): # 后台初始化截屏线程,用于寻找所有智能选区
self.x0 = self.y0 = 0
self.x1 = QApplication.desktop().width()
self.y1 = QApplication.desktop().height()
self.mouse_posx = self.mouse_posy = -150
self.qimg = get_pix.toImage()
temp_shape = (self.qimg.height(), self.qimg.width(), 4)
ptr = self.qimg.bits()
ptr.setsize(self.qimg.byteCount())
result = array(ptr, dtype=uint8).reshape(temp_shape)[..., :3]
self.finder.img = result
self.finder.find_contours_setup()
QApplication.processEvents()
def backup_shortshot(self):
if self.backup_ssid != len(self.backup_pic_list) - 1:
self.backup_pic_list = self.backup_pic_list[:self.backup_ssid + 1]
while len(self.backup_pic_list) >= 10:
self.backup_pic_list.pop(0)
allpix = self.cutpic(save_as=3)
self.backup_pic_list.append(QPixmap(allpix))
self.backup_ssid = len(self.backup_pic_list) - 1
print("备份动作", self.backup_ssid, len(self.backup_pic_list))
# self.update()
def last_step(self):
if self.backup_ssid > 0:
self.Tipsshower.setText("上一步")
self.backup_ssid -= 1
self.return_shortshot()
else:
self.Tipsshower.setText("没有上一步了")
def next_step(self):
if self.backup_ssid < len(self.backup_pic_list) - 1:
self.Tipsshower.setText("下一步")
self.backup_ssid += 1
self.return_shortshot()
else:
self.Tipsshower.setText("没有下一步了")
def return_shortshot(self):
print("还原", self.backup_ssid, len(self.backup_pic_list))
pix = self.backup_pic_list[self.backup_ssid]
self.setPixmap(pix)
self.paintlayer.pixmap().fill(Qt.transparent)
self.paintlayer.update()
self.update()
def freeze_img(self):
self.cutpic(save_as=2)
self.parent.freeze_imgs.append(Freezer(None, self.final_get_img,
min(self.x0, self.x1), min(self.y0, self.y1),
len(self.parent.freeze_imgs)))
if not QSettings('Fandes', 'jamtools').value("S_SIMPLE_MODE", False, bool):
self.parent.show()
self.clear_and_hide()
def ocr(self):
self.Tipsshower.setText("正在识别...")
# self.shower.setPlaceholderText("正在识别,请耐心等待...")
# self.shower.move(self.x1, self.y1)
# self.shower.show()
# self.shower.clear()
self.cutpic(save_as=2)
# ocrimg_temp_path = 'j_temp/{}.png'.format("ocrtemp")
# self.final_get_img.save(ocrimg_temp_path)
# # with open(ocrimg_temp_path, 'rb') as i:
# # img = i.read()
# img = cv2.imread(ocrimg_temp_path)
# self.ocrthread = OcrimgThread(img)
# self.ocrthread.result_show_signal.connect(self.ocr_res_signalhandle)
# self.ocrthread.start()
self.ocr_freezer = Freezer(None, self.final_get_img, min(self.x0, self.x1), min(self.y0, self.y1),
len(self.parent.freeze_imgs))
self.ocr_freezer.ocr()
QApplication.processEvents()
def ocr_res_signalhandle(self, text):
self.shower.setPlaceholderText("")
self.shower.insertPlainText(text)
# jt = re.sub(r'[^\w]', '', text).replace('_', '')
# n = 0
# for i in text:
# if self.is_alphabet(i):
# n += 1
# if n / len(jt) > 0.4:
# print("is en")
# self.shower.tra()
def is_alphabet(self, uchar):
"""判断一个unicode是否是英文字母"""
if (u'\u0041' <= uchar <= u'\u005a') or (u'\u0061' <= uchar <= u'\u007a'):
return True
else:
return False
def choice(self): # 选区完毕后显示选择按钮的函数
self.choicing = True
botton_boxw = self.x1 + 5
botton_boxh = self.y1 + 5
dx = abs(self.x1 - self.x0)
dy = abs(self.y1 - self.y0)
x = QApplication.desktop().width()
y = QApplication.desktop().height()
if dx < self.botton_box.width() + 10:
if max(self.x1, self.x0) + self.botton_box.width() > x:
botton_boxw = min(self.x0, self.x1) - self.botton_box.width() - 5
else:
botton_boxw = max(self.x1, self.x0) + 5
else:
if self.x1 > self.x0:
botton_boxw = self.x1 - self.botton_box.width() - 5
if dy < self.botton_box.height() + 105:
if max(self.y1, self.y0) + self.botton_box.height() + 20 > y:
botton_boxh = min(self.y0, self.y1) - self.botton_box.height() - 5
else:
botton_boxh = max(self.y0, self.y1) + 5
else:
if self.y1 > self.y0:
botton_boxh = self.y1 - self.botton_box.height() - 5
self.botton_box.move(botton_boxw, botton_boxh)
self.botton_box.show()
def roll_shot(self): # 滚动截屏
x0 = min(self.x0, self.x1)
y0 = min(self.y0, self.y1)
x1 = max(self.x0, self.x1)
y1 = max(self.y0, self.y1)
self.roller = Splicing_shots()
area = (x0, y0, x1 - x0, y1 - y0)
if (x1 - x0) < 50 or (y1 - y0) < 50:
self.showm_signal.emit('过小!')
self.Tipsshower.setText("滚动面积过小!")
return
self.hide()
self.roller.setup()
try:
if not self.parent.ssview:
self.parent.init_ssview()
except:
print(sys.exc_info())
self.roller.exit_roll_signal.connect(self.roll_exit_callback)
exi = self.roller.roll_manager(area)
print('roller end')
if exi:
print("未完成滚动截屏,用户退出")
self.clear_and_hide()
return
def roll_exit_callback(self):
self.final_get_img = QPixmap('j_temp/{}.png'.format(CONFIG_DICT["last_pic_save_name"]))
if __name__ == '__main__': # 当直接运行本文件时直接保存,测试用
QApplication.clipboard().setPixmap(self.final_get_img)
self.clear_and_hide()
print("已复制到剪切板")
return # 直接运行本文件时到此结束
self.manage_data()
self.clear_and_hide()
def cutpic(self, save_as=0): # 裁剪图片
"""裁剪图片,0:正常截图保存模式, 1:另存为模式, 2:内部调用保存图片, 3:内部调用,直接返回图片"""
self.sshoting = False
transparentpix = self.pixmap().copy()
paintlayer = self.paintlayer.pixmap()
painter = QPainter(transparentpix)
painter.setRenderHint(QPainter.Antialiasing)
painter.drawPixmap(0, 0, paintlayer)
painter.end() # 一定要end
if save_as == 3: # 油漆桶工具
return transparentpix
pix = QPixmap(transparentpix.width(), transparentpix.height())
p = QPainter(pix)
p.setRenderHint(QPainter.Antialiasing)
p.drawPixmap(0, 0, transparentpix)
p.end()
x0 = min(self.x0, self.x1)
y0 = min(self.y0, self.y1)
x1 = max(self.x0, self.x1)
y1 = max(self.y0, self.y1)
w = x1 - x0
h = y1 - y0
# print(x0, y0, x1, y1)
if (x1 - x0) < 1 or (y1 - y0) < 1:
self.Tipsshower.setText("范围过小<1")
return
self.final_get_img = pix.copy(x0, y0, w, h)
if save_as:
if save_as == 1:
path, l = QFileDialog.getSaveFileName(self, "保存为", QStandardPaths.writableLocation(
QStandardPaths.PicturesLocation), "img Files (*.PNG *.jpg *.JPG *.JPEG *.BMP *.ICO)"
";;all files(*.*)")
if path:
print(path)
transparentpix.save(path)
self.clear_and_hide()
else:
return
elif save_as == 2:
return
if __name__ == '__main__': # 当直接运行本文件时直接保存,测试用
self.final_get_img.save('j_temp/{}.png'.format(CONFIG_DICT["last_pic_save_name"]))
QApplication.clipboard().setPixmap(self.final_get_img)
print("已复制到剪切板")
self.clear_and_hide()
return
# 以下为作者软件的保存操作,懒得删了...
if self.mode == "set_area":
area = [x0,y0,(x1 - x0 + 1) // 2 * 2,(y1 - y0 + 1) // 2 * 2]
if area[2] == 0 or area[3] == 0:
self.showm_signal.emit('选择范围过小,请重新选择!')
else:
self.set_area_result_signal.emit(area)
if not QSettings('Fandes', 'jamtools').value("S_SIMPLE_MODE", False, bool):
self.parent.show()
elif self.mode == "getpix":
self.getpix_result_signal.emit((x0, y0, w, h),self.final_get_img)
if not QSettings('Fandes', 'jamtools').value("S_SIMPLE_MODE", False, bool):
self.parent.show()
else:
def save():
CONFIG_DICT["last_pic_save_name"]="{}".format( str(time.strftime("%Y-%m-%d_%H.%M.%S", time.localtime())))
filepath = 'j_temp/{}.png'.format(CONFIG_DICT["last_pic_save_name"])
self.final_get_img.save(filepath)
if self.mode == "screenshot":
self.screen_shot_result_signal.emit(filepath)
print('saved')
self.save_data_thread = Commen_Thread(save)
self.save_data_thread.start()
st = time.process_time()
self.manage_data()
print('managetime:', time.process_time() - st)
self.clear_and_hide()
def manage_data(self):
"""截屏完之后数据处理,不用可自己写"""
if self.mode == "screenshot":
if not QSettings('Fandes', 'jamtools').value("S_SIMPLE_MODE", False, bool):
self.screen_shot_end_show_sinal.emit(self.final_get_img)
clipboard = QApplication.clipboard()
try:
if self.parent.settings.value('screenshot/copy_type_ss', '图像数据', type=str) == '图像数据':
clipboard.setPixmap(self.final_get_img)
print('sava 图像数据')
self.showm_signal.emit('图像数据已复制到剪切板!')
elif self.parent.settings.value('screenshot/copy_type_ss', '图像数据', type=str) == '图像文件':
self.save_data_thread.wait()
data = QMimeData()
url = QUrl.fromLocalFile(os.getcwd()+'/j_temp/{}.png'.format(CONFIG_DICT["last_pic_save_name"]))
data.setUrls([url])
clipboard.setMimeData(data)
print('save url {}'.format(url))
self.showm_signal.emit('图像文件已复制到剪切板!')
except:
clipboard.setPixmap(self.final_get_img)
self.showm_signal.emit('图像数据已复制到剪切板!')
elif self.mode == "ocr":
try:
self.save_data_thread.wait()
self.ocr_image_signal.emit('j_temp/{}.png'.format(CONFIG_DICT["last_pic_save_name"]))
except:
print(sys.exc_info(), 1822)
# self.save_data_thread.wait()
# self.clear()
# self.close()
def cut_polygonpng(self):
allpix = self.cutpic(save_as=3)
self.qimg = allpix.toImage()
temp_shape = (self.qimg.height(), self.qimg.width(), 4)
ptr = self.qimg.bits()
ptr.setsize(self.qimg.byteCount())
cv2img = array(ptr, dtype=uint8).reshape(temp_shape)[..., :3]
polygoncv2pic = cut_polypng(cv2img, self.polygon_ss_pointlist)
cv2.imwrite('j_temp/{}.png'.format(CONFIG_DICT["last_pic_save_name"]), polygoncv2pic)
self.polygon_ss_pointlist = []
QApplication.clipboard().setImage(QImage('j_temp/{}.png'.format(CONFIG_DICT["last_pic_save_name"])))
self.showm_signal.emit("已复制到剪切板")
self.polygon_ss_btn.setStyleSheet('')
self.clear_and_hide()
def mouseDoubleClickEvent(self, e): # 双击
if e.button() == Qt.LeftButton:
if self.painter_tools["polygon_ss_on"]:
self.change_tools_fun("")
print("裁剪点", self.polygon_ss_pointlist)
self.cut_polygonpng()
print("左键双击")
# 鼠标点击事件
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton: # 按下了左键
self.left_button_push = True
if 1 in self.painter_tools.values(): # 如果有绘图工具打开了,说明正在绘图
if self.painter_tools['drawrect_bs_on']:
# print("ch",self.drawrect_pointlist)
self.drawrect_pointlist = [[event.x(), event.y()], [-2, -2], 0]
elif self.painter_tools['drawarrow_on']:
self.drawarrow_pointlist = [[event.x(), event.y()], [-2, -2], 0]
# self.drawarrow_pointlist[0] = [event.x(), event.y()]
elif self.painter_tools['drawcircle_on']:
self.drawcircle_pointlist = [[event.x(), event.y()], [-2, -2], 0]
# self.drawcircle_pointlist[0] = [event.x(), event.y()]
elif self.painter_tools['drawtext_on']:
self.text_box.move(event.x(), event.y())
self.drawtext_pointlist.append([event.x(), event.y()])
self.text_box.setFont(QFont('黑体', self.tool_width))
self.text_box.setTextColor(self.pencolor)
self.text_box.textAreaChanged()
self.text_box.show()
self.text_box.setFocus()
elif self.painter_tools['selectcolor_on']:
allpix = self.cutpic(save_as=3)
self.qimg = allpix.toImage()
color = self.qimg.pixelColor(event.x(), event.y())
self.pencolor = color
self.alpha_slider.setValue(255)
self.change_tools_fun("")
elif self.painter_tools['bucketpainter_on']: # 油漆桶工具
allpix = self.cutpic(save_as=3)
self.qimg = allpix.toImage()
temp_shape = (self.qimg.height(), self.qimg.width(), 4)
ptr = self.qimg.bits()
ptr.setsize(self.qimg.byteCount())
ci = array(ptr, dtype=uint8).reshape(temp_shape)[..., :3]
cv2img = image_fill(cv2.cvtColor(ci, cv2.COLOR_RGB2BGR), event.x(), event.y(),
(self.pencolor.red(), self.pencolor.green(), self.pencolor.blue()),
self.bucketpainter_tolerance.value())
height, width, depth = cv2img.shape
pix = QPixmap.fromImage(QImage(cv2img.data, width, height, width * depth, QImage.Format_RGB888))
tpix = QPixmap(pix.width(), pix.height())
tpix.fill(Qt.transparent)
p = QPainter(tpix)
p.drawPixmap(0, 0, pix)
p.end()
self.setPixmap(tpix)
self.paintlayer.pixmap().fill(Qt.transparent)
self.Tipsshower.setText("已填充并合并图层!", color=QColor(Qt.green))
allpix = self.cutpic(save_as=3)
self.qimg = allpix.toImage()
elif self.painter_tools["polygon_ss_on"]:
if len(self.polygon_ss_pointlist) and self.polygon_ss_pointlist[0][0] - 10 < event.x() < \
self.polygon_ss_pointlist[0][0] + 10 and self.polygon_ss_pointlist[0][
1] - 10 < event.y() < self.polygon_ss_pointlist[0][1] + 10:
print("相同点结束")
self.setCursor(QCursor(QPixmap(":/smartcursor.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
self.cut_polygonpng()
else:
self.setCursor(QCursor(QPixmap(":/polygon_ss.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
self.polygon_ss_pointlist.append([event.x(), event.y()])
elif self.painter_tools["perspective_cut_on"]:
self.setCursor(QCursor(QPixmap(":/perspective.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
self.perspective_cut_pointlist.append([event.x(), event.y()])
if len(self.perspective_cut_pointlist) >= 4:
allpix = self.cutpic(save_as=3)
self.qimg = allpix.toImage()
temp_shape = (self.qimg.height(), self.qimg.width(), 4)
ptr = self.qimg.bits()
ptr.setsize(self.qimg.byteCount())
cv2img = array(ptr, dtype=uint8).reshape(temp_shape)[..., :3]
res = cut_mutipic(cv2img, self.perspective_cut_pointlist)
cv2.imwrite("perspective_cut.jpg", res)
QApplication.clipboard().setImage(QImage("perspective_cut.jpg"))
# cv2.imwrite("respng.png",res)
self.Tipsshower.setText("已复制到剪切板!")
print("四个点", self.perspective_cut_pointlist)
self.setCursor(Qt.ArrowCursor)
self.perspective_cut_pointlist = []
self.change_tools_fun("")
self.choicing = False
self.finding_rect = True
else: # 否则说明正在选区或移动选区
r = 0
x0 = min(self.x0, self.x1)
x1 = max(self.x0, self.x1)
y0 = min(self.y0, self.y1)
y1 = max(self.y0, self.y1)
my = (y1 + y0) // 2
mx = (x1 + x0) // 2
# print(x0, x1, y0, y1, mx, my, event.x(), event.y())
# 以下为判断点击在哪里
if not self.finding_rect and (self.x0 - 8 < event.x() < self.x0 + 8) and (
my - 8 < event.y() < my + 8 or y0 - 8 < event.y() < y0 + 8 or y1 - 8 < event.y() < y1 + 8):
self.move_x0 = True
r = 1
elif not self.finding_rect and (self.x1 - 8 < event.x() < self.x1 + 8) and (
my - 8 < event.y() < my + 8 or y0 - 8 < event.y() < y0 + 8 or y1 - 8 < event.y() < y1 + 8):
self.move_x1 = True
r = 1
# print('x1')
elif not self.finding_rect and (self.y0 - 8 < event.y() < self.y0 + 8) and (
mx - 8 < event.x() < mx + 8 or x0 - 8 < event.x() < x0 + 8 or x1 - 8 < event.x() < x1 + 8):
self.move_y0 = True
print('y0')
elif not self.finding_rect and self.y1 - 8 < event.y() < self.y1 + 8 and (
mx - 8 < event.x() < mx + 8 or x0 - 8 < event.x() < x0 + 8 or x1 - 8 < event.x() < x1 + 8):
self.move_y1 = True
elif (x0 + 8 < event.x() < x1 - 8) and (
y0 + 8 < event.y() < y1 - 8) and not self.finding_rect:
# if not self.finding_rect:
self.move_rect = True
self.setCursor(Qt.SizeAllCursor)
self.bx = abs(max(self.x1, self.x0) - event.x())
self.by = abs(max(self.y1, self.y0) - event.y())
else:
self.NpainterNmoveFlag = True # 没有绘图没有移动还按下了左键,说明正在选区,标志变量
# if self.finding_rect:
# self.rx0 = event.x()
# self.ry0 = event.y()
# else:
self.rx0 = event.x() # 记录下点击位置
self.ry0 = event.y()
if self.x1 == -50:
self.x1 = event.x()
self.y1 = event.y()
# print('re')
if r: # 判断是否点击在了对角线上
if (self.y0 - 8 < event.y() < self.y0 + 8) and (
x0 - 8 < event.x() < x1 + 8):
self.move_y0 = True
# print('y0')
elif self.y1 - 8 < event.y() < self.y1 + 8 and (
x0 - 8 < event.x() < x1 + 8):
self.move_y1 = True
# print('y1')
if self.finding_rect:
self.finding_rect = False
# self.finding_rectde = True
self.botton_box.hide()
self.update()
# elif event.button() == Qt.RightButton: # 右键
# self.setCursor(Qt.ArrowCursor)
# if 1 in self.painter_tools.values(): # 退出绘图工具
# if self.painter_tools["selectcolor_on"]:
# self.Tipsshower.setText("取消取色器")
# self.choice_clor_btn.setStyleSheet(
# 'background-color:{0};'.format(self.pencolor.name())) # 还原choiceclor显示的颜色
# if self.painter_tools["perspective_cut_on"] and len(self.perspective_cut_pointlist) > 0:
# self.setCursor(QCursor(QPixmap(":/perspective.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
# self.perspective_cut_pointlist.pop()
# # if not len(self.perspective_cut_pointlist):
# # self.choicing = False
# # self.finding_rect = True
# elif self.painter_tools["polygon_ss_on"] and len(self.polygon_ss_pointlist) > 0:
# self.setCursor(QCursor(QPixmap(":/polygon_ss.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
# self.polygon_ss_pointlist.pop()
# # if not len(self.polygon_ss_pointlist):
# # self.choicing = False
# # self.finding_rect = True
# else:
# self.choicing = False
# self.finding_rect = True
# self.shower.hide()
# self.change_tools_fun("")
# elif self.choicing: # 退出选定的选区
# self.botton_box.hide()
# self.choicing = False
# self.finding_rect = True
# self.shower.hide()
# self.x0 = self.y0 = self.x1 = self.y1 = -50
# else: # 退出截屏
# try:
# if not QSettings('Fandes', 'jamtools').value("S_SIMPLE_MODE", False, bool):
# self.parent.show()
# self.parent.bdocr = False
# except:
# print(sys.exc_info(), 2051)
# self.clear_and_hide()
self.update()
# 鼠标释放事件
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton:
self.left_button_push = False
if 1 in self.painter_tools.values(): # 绘图工具松开
if self.painter_tools['pen_on']:
self.pen_pointlist.append([-2, -2])
elif self.painter_tools['drawpix_bs_on']:
self.drawpix_pointlist.append([-2, -2])
elif self.painter_tools['repairbackground_on']:
self.repairbackground_pointlist.append([-2, -2])
elif self.painter_tools['drawrect_bs_on']:
self.drawrect_pointlist[1] = [event.x(), event.y()]
self.drawrect_pointlist[2] = 1
elif self.painter_tools['drawarrow_on']:
self.drawarrow_pointlist[1] = [event.x(), event.y()]
self.drawarrow_pointlist[2] = 1
elif self.painter_tools['drawcircle_on']:
self.drawcircle_pointlist[1] = [event.x(), event.y()]
self.drawcircle_pointlist[2] = 1
elif self.painter_tools['eraser_on']:
self.eraser_pointlist.append([-2, -2])
elif self.painter_tools['backgrounderaser_on']:
self.backgrounderaser_pointlist.append([-2, -2])
if not self.painter_tools["perspective_cut_on"] and not self.painter_tools["polygon_ss_on"]:
self.backup_shortshot()
else: # 调整选区松开
self.setCursor(Qt.ArrowCursor)
self.NpainterNmoveFlag = False # 选区结束标志置零
self.move_rect = self.move_y0 = self.move_x0 = self.move_x1 = self.move_y1 = False
if not self.painter_tools["perspective_cut_on"] and not self.painter_tools["polygon_ss_on"]:
self.choice()
# self.sure_btn.show()
elif event.button() == Qt.RightButton: # 右键
self.setCursor(Qt.ArrowCursor)
if 1 in self.painter_tools.values(): # 退出绘图工具
if self.painter_tools["selectcolor_on"]:
self.Tipsshower.setText("取消取色器")
self.choice_clor_btn.setStyleSheet(
'background-color:{0};'.format(self.pencolor.name())) # 还原choiceclor显示的颜色
if self.painter_tools["perspective_cut_on"] and len(self.perspective_cut_pointlist) > 0:
self.setCursor(QCursor(QPixmap(":/perspective.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
self.perspective_cut_pointlist.pop()
# if not len(self.perspective_cut_pointlist):
# self.choicing = False
# self.finding_rect = True
elif self.painter_tools["polygon_ss_on"] and len(self.polygon_ss_pointlist) > 0:
self.setCursor(QCursor(QPixmap(":/polygon_ss.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
self.polygon_ss_pointlist.pop()
# if not len(self.polygon_ss_pointlist):
# self.choicing = False
# self.finding_rect = True
else:
self.choicing = False
self.finding_rect = True
self.shower.hide()
self.change_tools_fun("")
elif self.choicing: # 退出选定的选区
self.botton_box.hide()
self.choicing = False
self.finding_rect = True
self.shower.hide()
self.x0 = self.y0 = self.x1 = self.y1 = -50
else: # 退出截屏
try:
if not QSettings('Fandes', 'jamtools').value("S_SIMPLE_MODE", False, bool):
self.parent.show()
self.parent.bdocr = False
except:
print(sys.exc_info(), 2051)
self.clear_and_hide()
self.update()
# 鼠标滑轮事件
def wheelEvent(self, event):
if self.isVisible():
angleDelta = event.angleDelta() / 8
dy = angleDelta.y()
# print(dy)
if self.change_alpha: # 正在调整透明度
if dy > 0 and self.alpha < 254:
self.alpha_slider.setValue(self.alpha_slider.value() + 2)
elif dy < 0 and self.alpha > 2:
self.alpha_slider.setValue(self.alpha_slider.value() - 2)
self.Tipsshower.setText("透明度值{}".format(self.alpha))
else: # 否则是调节画笔大小
# angleDelta = event.angleDelta() / 8
# dy = angleDelta.y()
# print(dy)
if dy > 0:
self.tool_width += 1
elif self.tool_width > 1:
self.tool_width -= 1
self.size_slider.setValue(self.tool_width)
self.Tipsshower.setText("大小{}px".format(self.tool_width))
# if 1 in self.painter_tools.values():
if self.painter_tools['drawtext_on']:
# self.text_box.move(event.x(), event.y())
# self.drawtext_pointlist.append([event.x(), event.y()])
self.text_box.setFont(QFont('黑体', self.tool_width))
# self.text_box.setTextColor(self.pencolor)
self.text_box.textAreaChanged()
self.update()
# 鼠标移动事件
def mouseMoveEvent(self, event):
# print(self.isVisible(), 12121, self.finding_rect, self.smartcursor_on, self.isActiveWindow(), self.isHidden())
if self.isVisible():
self.mouse_posx = event.x() # 先储存起鼠标位置,用于画笔等的绘图计算
self.mouse_posy = event.y()
if self.finding_rect and self.smartcursor_on: # 如果允许智能选取并且在选选区步骤
self.x0, self.y0, self.x1, self.y1 = self.finder.find_targetrect((self.mouse_posx, self.mouse_posy))
self.setCursor(QCursor(QPixmap(":/smartcursor.png").scaled(32, 32, Qt.KeepAspectRatio), 16, 16))
# print(self.x0, self.y0, self.x1, self.y1 )
# print("findtime {}".format(time.process_time()-st))
elif 1 in self.painter_tools.values(): # 如果有绘图工具已经被选择,说明正在绘图
self.paintlayer.px = event.x()
self.paintlayer.py = event.y()
if self.left_button_push:
if self.painter_tools['pen_on']:
self.pen_pointlist.append([event.x(), event.y()])
elif self.painter_tools['drawpix_bs_on']:
self.drawpix_pointlist.append([event.x(), event.y()])
elif self.painter_tools['repairbackground_on']:
self.repairbackground_pointlist.append([event.x(), event.y()])
elif self.painter_tools['drawrect_bs_on']:
self.drawrect_pointlist[1] = [event.x(), event.y()]
elif self.painter_tools['drawarrow_on']:
self.drawarrow_pointlist[1] = [event.x(), event.y()]
elif self.painter_tools['drawcircle_on']:
self.drawcircle_pointlist[1] = [event.x(), event.y()]
elif self.painter_tools['eraser_on']:
self.eraser_pointlist.append([event.x(), event.y()])
elif self.painter_tools['backgrounderaser_on']:
# print('bakpoint')
self.backgrounderaser_pointlist.append([event.x(), event.y()])
elif self.painter_tools["polygon_ss_on"]:
self.polygon_ss_pointlist.append([event.x(), event.y()])
# self.update()
if self.painter_tools['pen_on']:
self.setCursor(QCursor(QPixmap(":/pen.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
elif self.painter_tools['drawpix_bs_on']:
self.setCursor(QCursor(self.paintlayer.pixpng.scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
elif self.painter_tools['repairbackground_on']:
self.setCursor(QCursor(QPixmap(":/backgroundrepair.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 26))
elif self.painter_tools['drawrect_bs_on']:
self.setCursor(QCursor(QPixmap(":/rect.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 30))
elif self.painter_tools['drawarrow_on']:
self.setCursor(QCursor(QPixmap(":/arrowicon.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
elif self.painter_tools['drawcircle_on']:
self.setCursor(QCursor(QPixmap(":/circle.png").scaled(32, 32, Qt.KeepAspectRatio), 16, 16))
elif self.painter_tools['drawtext_on']:
self.setCursor(QCursor(QPixmap(":/texticon.png").scaled(16, 16, Qt.KeepAspectRatio), 0, 0))
elif self.painter_tools['eraser_on']:
self.setCursor(QCursor(QPixmap(":/eraser.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
elif self.painter_tools['backgrounderaser_on']:
self.setCursor(QCursor(QPixmap(":/backgrounderaser.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
elif self.painter_tools['selectcolor_on']:
color = self.qimg.pixelColor(event.x(), event.y())
self.choice_clor_btn.setStyleSheet('background-color:{0};'.format(color.name()))
self.setCursor(QCursor(QPixmap(":/colorsampler.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 31))
elif self.painter_tools['bucketpainter_on']:
self.setCursor(QCursor(QPixmap(":/yqt.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
elif self.painter_tools['perspective_cut_on']:
self.setCursor(QCursor(QPixmap(":/perspective.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
elif self.painter_tools['polygon_ss_on']:
if len(self.polygon_ss_pointlist) and self.polygon_ss_pointlist[0][0] - 10 < event.x() < \
self.polygon_ss_pointlist[0][0] + 10 and self.polygon_ss_pointlist[0][
1] - 10 < event.y() < self.polygon_ss_pointlist[0][1] + 10:
self.setCursor(QCursor(QPixmap(":/smartcursor.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
else:
self.setCursor(QCursor(QPixmap(":/polygon_ss.png").scaled(32, 32, Qt.KeepAspectRatio), 0, 32))
else: # 不在绘画
minx = min(self.x0, self.x1)
maxx = max(self.x0, self.x1)
miny = min(self.y0, self.y1)
maxy = max(self.y0, self.y1) # 以上取选区的最小值和最大值
my = (maxy + miny) // 2
mx = (maxx + minx) // 2 # 取中间值
if ((minx - 8 < event.x() < minx + 8) and (miny - 8 < event.y() < miny + 8)) or \
((maxx - 8 < event.x() < maxx + 8) and (maxy - 8 < event.y() < maxy + 8)):
self.setCursor(Qt.SizeFDiagCursor)
elif ((minx - 8 < event.x() < minx + 8) and (maxy - 8 < event.y() < maxy + 8)) or \
((maxx - 8 < event.x() < maxx + 8) and (miny - 8 < event.y() < miny + 8)):
self.setCursor(Qt.SizeBDiagCursor)
elif (self.x0 - 8 < event.x() < self.x0 + 8) and (
my - 8 < event.y() < my + 8 or miny - 8 < event.y() < miny + 8 or maxy - 8 < event.y() < maxy + 8):
self.setCursor(Qt.SizeHorCursor)
elif (self.x1 - 8 < event.x() < self.x1 + 8) and (
my - 8 < event.y() < my + 8 or miny - 8 < event.y() < miny + 8 or maxy - 8 < event.y() < maxy + 8):
self.setCursor(Qt.SizeHorCursor)
elif (self.y0 - 8 < event.y() < self.y0 + 8) and (
mx - 8 < event.x() < mx + 8 or minx - 8 < event.x() < minx + 8 or maxx - 8 < event.x() < maxx + 8):
self.setCursor(Qt.SizeVerCursor)
elif (self.y1 - 8 < event.y() < self.y1 + 8) and (
mx - 8 < event.x() < mx + 8 or minx - 8 < event.x() < minx + 8 or maxx - 8 < event.x() < maxx + 8):
self.setCursor(Qt.SizeVerCursor)
elif (minx + 8 < event.x() < maxx - 8) and (
miny + 8 < event.y() < maxy - 8):
if self.move_rect:
self.setCursor(Qt.SizeAllCursor)
# self.setCursor(Qt.SizeAllCursor)
elif self.move_x1 or self.move_x0 or self.move_y1 or self.move_y0: # 再次判断防止光标抖动
b = (self.x1 - self.x0) * (self.y1 - self.y0) > 0
if (self.move_x0 and self.move_y0) or (self.move_x1 and self.move_y1):
if b:
self.setCursor(Qt.SizeFDiagCursor)
else:
self.setCursor(Qt.SizeBDiagCursor)
elif (self.move_x1 and self.move_y0) or (self.move_x0 and self.move_y1):
if b:
self.setCursor(Qt.SizeBDiagCursor)
else:
self.setCursor(Qt.SizeFDiagCursor)
elif (self.move_x0 or self.move_x1) and not (self.move_y0 or self.move_y1):
self.setCursor(Qt.SizeHorCursor)
elif not (self.move_x0 or self.move_x1) and (self.move_y0 or self.move_y1):
self.setCursor(Qt.SizeVerCursor)
# elif self.move_rect:
# self.setCursor(Qt.SizeAllCursor)
else:
self.setCursor(Qt.ArrowCursor)
# 以上几个ifelse都是判断鼠标移动的位置和选框的关系然后设定光标形状
# print(11)
if self.NpainterNmoveFlag: # 如果没有在绘图也没在移动(调整)选区,在选区,则不断更新选区的数值
# self.sure_btn.hide()
# self.roll_ss_btn.hide()
self.x1 = event.x() # 储存当前位置到self.x1下同
self.y1 = event.y()
self.x0 = self.rx0 # 鼠标按下时记录的坐标,下同
self.y0 = self.ry0
if self.y1 > self.y0: # 下面是边界修正,由于选框占用了一个像素,否则有误差
self.y1 += 1
else:
self.y0 += 1
if self.x1 > self.x0:
self.x1 += 1
else:
self.x0 += 1
else: # 说明在移动或者绘图,不过绘图没有什么处理的,下面是处理移动/拖动选区
if self.move_x0: # 判断拖动标志位,下同
self.x0 = event.x()
elif self.move_x1:
self.x1 = event.x()
if self.move_y0:
self.y0 = event.y()
elif self.move_y1:
self.y1 = event.y()
elif self.move_rect: # 拖动选框
dx = abs(self.x1 - self.x0)
dy = abs(self.y1 - self.y0)
if self.x1 > self.x0:
self.x1 = event.x() + self.bx
self.x0 = self.x1 - dx
else:
self.x0 = event.x() + self.bx
self.x1 = self.x0 - dx
if self.y1 > self.y0:
self.y1 = event.y() + self.by
self.y0 = self.y1 - dy
else:
self.y0 = event.y() + self.by
self.y1 = self.y0 - dy
# print("movetime{}".format(time.process_time()-st))
self.update() # 更新界面
# QApplication.processEvents()
def keyPressEvent(self, e): # 按键按下,没按一个键触发一次
super(Slabel, self).keyPressEvent(e)
# self.pixmap().save(temp_path + '/aslfdhds.png')
if e.key() == Qt.Key_Escape: # 退出
self.clear_and_hide()
elif e.key() == Qt.Key_Control: # 按住ctrl,更改透明度标志位置一
print("cahnge")
self.change_alpha = True
elif self.change_alpha: # 如果已经按下了ctrl
if e.key() == Qt.Key_S: # 还按下了s,说明是保存,ctrl+s
self.cutpic(1)
elif not self.painter_tools["polygon_ss_on"] and not self.painter_tools["perspective_cut_on"]:
if e.key() == Qt.Key_Z: # 前一步
self.last_step()
elif e.key() == Qt.Key_Y: # 后一步
self.next_step()
def keyReleaseEvent(self, e) -> None: # 按键松开
super(Slabel, self).keyReleaseEvent(e)
if e.key() == Qt.Key_Control:
self.change_alpha = False
def clear_and_hide(self): # 清理退出
print("clear and hide")
if self.ocr_freezer is not None:
self.ocr_freezer.clear()
if PLATFORM_SYS == "darwin": # 如果系统为macos
print("drawin hide")
self.setWindowOpacity(0)
self.showNormal()
self.hide()
self.clearotherthread = Commen_Thread(self.clear_and_hide_thread)
self.clearotherthread.start()
def clear_and_hide_thread(self): # 后台等待线程
self.close_signal.emit()
try:
self.save_data_thread.wait()
except:
print(sys.exc_info(), 2300)
# 绘制事件
def paintEvent(self, event): # 绘图函数,每次调用self.update时触发
super().paintEvent(event)
if self.on_init:
print('oninit return')
return
pixPainter = QPainter(self.pixmap()) # 画笔
while len(self.backgrounderaser_pointlist): # 背景橡皮擦工具有值,则说明正在使用背景橡皮擦
# print(self.backgrounderaser_pointlist)
pixPainter.setRenderHint(QPainter.Antialiasing)
pixPainter.setBrush(QColor(0, 0, 0, 0))
pixPainter.setPen(Qt.NoPen)
# pixPainter.setPen(Qt.NoPen)
pixPainter.setCompositionMode(QPainter.CompositionMode_Clear)
new_pen_point = self.backgrounderaser_pointlist.pop(0)
if self.old_pen is None:
self.old_pen = new_pen_point
continue
if self.old_pen[0] != -2 and new_pen_point[0] != -2:
pixPainter.drawEllipse(new_pen_point[0] - self.tool_width / 2,
new_pen_point[1] - self.tool_width / 2,
self.tool_width, self.tool_width)
if abs(new_pen_point[0] - self.old_pen[0]) > 3 or abs(
new_pen_point[1] - self.old_pen[1]) > 3:
interpolateposs = get_line_interpolation(new_pen_point[:], self.old_pen[:])
if interpolateposs is not None:
for pos in interpolateposs:
x, y = pos
pixPainter.drawEllipse(x - self.tool_width / 2,
y - self.tool_width / 2,
self.tool_width, self.tool_width)
self.old_pen = new_pen_point
while len(self.repairbackground_pointlist): # 背景修复画笔有值
brush = QBrush(self.pencolor)
brush.setTexture(self.originalPix)
pixPainter.setBrush(brush)
pixPainter.setPen(Qt.NoPen)
new_pen_point = self.repairbackground_pointlist.pop(0)
if self.old_pen is None:
self.old_pen = new_pen_point
continue
if self.old_pen[0] != -2 and new_pen_point[0] != -2:
pixPainter.drawEllipse(new_pen_point[0] - self.tool_width / 2,
new_pen_point[1] - self.tool_width / 2,
self.tool_width, self.tool_width)
if abs(new_pen_point[0] - self.old_pen[0]) > 1 or abs(
new_pen_point[1] - self.old_pen[1]) > 1:
interpolateposs = get_line_interpolation(new_pen_point[:], self.old_pen[:])
if interpolateposs is not None:
for pos in interpolateposs:
x, y = pos
pixPainter.drawEllipse(x - self.tool_width / 2,
y - self.tool_width / 2,
self.tool_width, self.tool_width)
self.old_pen = new_pen_point
pixPainter.end()
if __name__ == '__main__':
class testwin(QWidget): # 随便设置的一个ui,
def __init__(self):
super(testwin, self).__init__()
self.freeze_imgs = [] # 储存固定截屏在屏幕上的数组
btn = QPushButton("截屏", self)
btn.setGeometry(20, 20, 60, 30)
btn.setShortcut("Alt+Z")
btn.clicked.connect(self.ss)
self.temppos = [500, 100]
self.s = Slabel(self)
self.s.close_signal.connect(self.ss_end) # 截屏结束信号连接
self.resize(300, 200)
def ss(self): # 截屏开始
self.setWindowOpacity(0) # 设置透明度而不是hide是因为透明度更快
self.temppos = [self.x(), self.y()]
self.move(QApplication.desktop().width(), QApplication.desktop().height())
self.s.screen_shot()
# self.hide()
def ss_end(self):
del self.s
self.move(self.temppos[0], self.temppos[1])
self.show()
self.setWindowOpacity(1)
self.raise_()
gc.collect()
print(gc.isenabled(), gc.get_count(), gc.get_freeze_count())
print('cleard')
self.s = Slabel(self)
self.s.close_signal.connect(self.ss_end)
def show(self) -> None:
super(testwin, self).show()
print("ss show")
app = QApplication(sys.argv)
s = testwin()
s.show()
sys.exit(app.exec_())
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/levis1228/JamTools.git
git@gitee.com:levis1228/JamTools.git
levis1228
JamTools
JamTools
main

搜索帮助

23e8dbc6 1850385 7e0993f3 1850385