背景介绍
-
当时是跟着老师做一个文字识别的项目,需要实现一个自由截图的功能,自行选择文字识别的区域,将该区域保存为图片,然后借助魔塔的OCR模型识别图片中的文字并输出。
功能介绍
- 本代码用python实现了类似QQ、微信自带的截图功能,运行后可以自由选择截图区域并将该区域保存为图片
代码
- 代码在vscode和pycharm下均已测试过,没有问题
- 家人们可以直接复制到vscode中跑一下试试,看一下具体实现的功能,并根据自己的实际需求再修改
from PIL import ImageGrab
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QPainter, QPen
from PyQt5.QtWidgets import QApplication, QLabel, QWidget
# 获取屏幕的缩放比
def get_screen_scaling():
return ctypes.windll.shcore.GetScaleFactorForDevice(0) / 100
class ScreenshotWidget(QWidget):
def __init__(self):
super().__init__()
self.begin = None
self.end = None
# Qt.WindowStaysOnTopHint 置顶窗口
# Qt.FramelessWindowHint 产生一个无窗口边框的窗口,此时用户无法移动该窗口和改变它的大小
self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
# setWindowOpacity() 只能作用于顶级窗口,取值为0.0~1.0,0.0为完全透明,1.0为完全不透明
self.setWindowOpacity(0.5) # 设置窗口透明度为 0.5,如果不加这行代码的话,运行代码后屏幕会被不透明白屏铺满
self.setWindowState(Qt.WindowFullScreen) # 铺满全屏幕
self.screen_scaling = get_screen_scaling()
def mousePressEvent(self, event):
self.begin = event.pos()
self.end = event.pos()
def mouseMoveEvent(self, event):
self.end = event.pos()
self.update()
# 根据坐标进行截图保存
def mouseReleaseEvent(self, event):
self.close()
# 坐标乘以缩放比后再进行抓取
x1, y1 = self.begin.x() * self.screen_scaling, self.begin.y() * self.screen_scaling
x2, y2 = self.end.x() * self.screen_scaling, self.end.y() * self.screen_scaling
if x1 > x2:
x1, x2 = x2, x1
if y1 > y2:
y1, y2 = y2, y1
im = ImageGrab.grab(bbox=(x1, y1, x2, y2))
# im.show()
im.save("jietu.jpg")
# 在截图时绘制矩形,目的是为了清楚看到自己所选的区域
def paintEvent(self, event):
if not self.begin:
return
painter = QPainter(self) # 创建QPainter对象
# painter.setPen(Qt.green)
# painter.setPen(Qt.red) #设置画笔的颜色
pen = QPen(Qt.red)
pen.setWidth(2) # 设置画笔的宽度
painter.setPen(pen)
# drawRect来绘制矩形,四个参数分别是x,y,w,h
painter.drawRect(self.begin.x(), self.begin.y(),
self.end.x() - self.begin.x(), self.end.y() - self.begin.y())
def main():
app = QApplication([])
widget = ScreenshotWidget()
widget.show()
# app.exec_()是PyQt中的一个方法,用于启动应用程序的事件循环。它会在调用之后开始监视事件,并根据事件的发生自动执行相应的函数。
app.exec_()
if __name__ == '__main__':
main()
ps:关于屏幕缩放比这个细节,我刚开始也没注意到,就导致代码在其他同学和老师电脑上测试时,由于缩放比的不同,使得保存的截图与所选区域有一个偏移量。当时我电脑的缩放比是125%,所以会向左上偏移(后续分析应该是因为捕获鼠标坐标时是在125%缩放比下,而借助ImageGrab抓取截图时是在100%缩放比下,这句话可以看下图中画红线的句子,就好理解了)。这一个bug耗了好几天,最后借助ps去分析像素时发现x,y坐标的值基本呈一个线性函数缩小,才想到缩放比的问题,并最终在chatgpt的帮助下debug成功。大家也可以修改自己电脑屏幕的缩放比,然后分别在加/不加缩放比的代码下运行分别看一下结果。
- 码字不易,debug更不易,如果对您有帮助并且您方便的话,还请不要吝啬点赞啦,如果转载,请务必注明出处!