Skip to content

Instantly share code, notes, and snippets.

@duangsuse
Last active May 25, 2023 03:58
Show Gist options
  • Save duangsuse/2354cc37ac4a2ead9305f08cdb81c273 to your computer and use it in GitHub Desktop.
Save duangsuse/2354cc37ac4a2ead9305f08cdb81c273 to your computer and use it in GitHub Desktop.
pyQt 框选获取屏幕截图
# 用 pyQt 框选获取屏幕截图,PIL.ImageGrab.grab() 可以获取全屏图,继续,继续capture和鼠标
#xy可以换成两个QPoint
#请用PyGTK兼容 linux 上的 PIL grabclipboard()
import gi; gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk
gi.overrides.GdkPixbuf.Pixbuf.toPIL=lambda g: PIL.Image.frombuffer("RGBA",(g.get_width(),g.get_height()),g.get_pixels() )
cc=Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel
from PyQt5.QtGui import QPixmap, QPainter, QPen
from PyQt5.QtCore import Qt, QRect
import PIL.ImageGrab
# 定义一个类,继承自 QWidget
class ScreenShot(QWidget):
# 初始化方法
def __init__(self):
# 调用父类的初始化方法
super().__init__()
# 设置窗口的标题、大小和背景颜色
self.setWindowTitle("Screen Shot")
self.resize(800, 600)
self.setStyleSheet("background-color: black")
# 创建一个标签,用于显示全屏截图
self.label = QLabel(self)
self.label.resize(self.width(), self.height())
# 创建一个按钮,用于保存截图
self.button = QPushButton("Save", self)
self.button.move(10, 10)
# 绑定按钮的点击事件,调用 save 方法
self.button.clicked.connect(self.save)
# 初始化一些属性,用于记录鼠标的位置和绘制的矩形区域
self.start_x = 0
self.start_y = 0
self.end_x = 0
self.end_y = 0
self.rect = QRect()
# 调用 capture 方法,获取全屏截图并显示在标签上
self.capture()
# 定义一个方法,用于获取全屏截图并显示在标签上
def capture(self):
# 使用 PIL.ImageGrab.grab() 获取全屏截图,并保存为 temp.png 文件
PIL.ImageGrab.grab().save("temp.png")
# 使用 QPixmap 加载 temp.png 文件,并设置为标签的图片
pixmap = QPixmap("temp.png")
self.label.setPixmap(pixmap)
# 定义一个方法,用于保存截图
def save(self):
# 如果矩形区域不为空,就对图片进行裁剪,并保存为 result.png 文件
if not self.rect.isNull():
pixmap = self.label.pixmap()
pixmap.copy(self.rect).save("result.png")
# 打印提示信息,方便查看
print("Screen shot saved as result.png")
# 重写鼠标按下事件的处理方法
def mousePressEvent(self, event):
# 如果鼠标左键被按下,就记录鼠标的位置,并更新矩形区域
if event.button() == Qt.LeftButton:
self.start_x = event.x()
self.start_y = event.y()
self.rect = QRect(self.start_x, self.start_y, 0, 0)
# 调用 update 方法,触发 paintEvent 方法
self.update()
# 重写鼠标移动事件的处理方法
def mouseMoveEvent(self, event):
# 如果鼠标左键被按下,就记录鼠标的位置,并更新矩形区域
if event.buttons() == Qt.LeftButton:
self.end_x = event.x()
self.end_y = event.y()
self.rect = QRect(self.start_x, self.start_y, self.end_x - self.start_x, self.end_y - self.start_y)
# 调用 update 方法,触发 paintEvent 方法
self.update()
# 重写绘制事件的处理方法
def paintEvent(self, event):
# 调用父类的绘制方法,绘制背景和标签
super().paintEvent(event)
# 创建一个画笔对象,设置颜色和宽度
painter = QPainter(self)
painter.setPen(QPen(Qt.red, 2))
# 使用画笔对象,在矩形区域内绘制一个红色的框
painter.drawRect(self.rect)
import pyperclip, paddleocr, time
import PIL.ImageGrab
async def changes(f):
v0=f()
while True:
if (v:=f())!=v0: yield v; v0=v; time.sleep(.1)
def clip():
global cc
try:return PIL.ImageGrab.grabclipboard()
except:
if not cc:
import gi; gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk
gi.overrides.GdkPixbuf.Pixbuf.toPIL=lambda g: PIL.Image.frombuffer("RGBA",(g.get_width(),g.get_height()),g.get_pixels() )
cc=Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
b=cc.wait_for_image()
return b.toPIL()if b else None
use=paddleocr.PaddleOCR(lang="ch"); cc=None
async for x in changes(pyperclip.paste):
if not (img:=clip()):continue
img.save('scr.png')
s='\n'.join(x[1][0] for x in use.ocr('scr.png')[0])
pyperclip.copy(s); print(s)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment