利用python实现类似QQ、微信的截图功能,可自由选择截图区域并保存图片

背景介绍

  • 当时是跟着老师做一个文字识别的项目,需要实现一个自由截图的功能,自行选择文字识别的区域,将该区域保存为图片,然后借助魔塔的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更不易,如果对您有帮助并且您方便的话,还请不要吝啬点赞啦,如果转载,请务必注明出处!
  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不吃香菜的小趴菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值