Как сделать распознавание текста со скриншота и вывод этого текста в QTextEdit?
Я написал приложение и использую OCR для распознавания текста со скриншота.
Я выделяю область и у меня сохраняется скриншот, но после его сохранения программа завершает работу.
Код:
import sys
import keyboard
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QPushButton, QVBoxLayout, QLabel, QTextEdit, QDialog
from PyQt5.QtCore import Qt, QRect, QPoint
from PyQt5 import QtCore, QtGui, QtWidgets
import pytesseract
from PIL import Image
class SnippingWidget(QDialog):
selection_finished = QtCore.pyqtSignal(QtCore.QRect)
text_selected = QtCore.pyqtSignal(str)
def __init__(self):
super(SnippingWidget, self).__init__()
self.setAttribute(QtCore.Qt.WA_NoSystemBackground, True)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
self.setStyleSheet("background:transparent;")
self.setWindowFlags(Qt.FramelessWindowHint)
self.outsideSquareColor = "red"
self.squareThickness = 2
self.start_point = QtCore.QPoint()
self.end_point = QtCore.QPoint()
self.selected_area = None
screen_geometry = QtWidgets.QApplication.desktop().screenGeometry()
self.setGeometry(screen_geometry)
def mousePressEvent(self, event):
self.start_point = event.pos()
self.end_point = event.pos()
QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.CrossCursor)
self.update()
def mouseMoveEvent(self, event):
self.end_point = event.pos()
self.update()
def mouseReleaseEvent(self, QMouseEvent):
try:
r = QtCore.QRect(self.start_point, self.end_point).normalized()
self.close()
self.selected_area = r
QtWidgets.QApplication.restoreOverrideCursor()
self.selection_finished.emit(r)
# Извлечение изображения из выделенной области
screenshot = QtWidgets.QApplication.primaryScreen().grabWindow(0, r.x(), r.y(), r.width(), r.height())
screenshot.save("screenshot.png", "png")
# Распознавание текста с помощью Tesseract OCR
text = pytesseract.image_to_string(Image.open("screenshot.png"), lang='eng')
# Передача распознанного текста в главное окно
self.text_selected.emit(text)
self.start_point = QtCore.QPoint()
self.end_point = QtCore.QPoint()
except Exception as e:
pass
def paintEvent(self, event):
trans = QtGui.QColor(22, 100, 233)
r = QtCore.QRectF(self.start_point, self.end_point).normalized()
qp = QtGui.QPainter(self)
trans.setAlphaF(0.2)
qp.setBrush(trans)
outer = QtGui.QPainterPath()
outer.addRect(QtCore.QRectF(self.rect()))
inner = QtGui.QPainterPath()
inner.addRect(r)
r_path = outer - inner
qp.drawPath(r_path)
qp.setPen(
QtGui.QPen(QtGui.QColor(self.outsideSquareColor), self.squareThickness)
)
trans.setAlphaF(0)
qp.setBrush(trans)
qp.drawRect(r)
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.FramelessWindowHint)
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
self.draggable = False
self.offset = None
# set the title
self.setWindowTitle("")
# Удаление иконки окна
self.setWindowIconText("")
#Размеры окна
self.setGeometry(300, 300, 500, 300)
# Установка фона и темы
self.setStyleSheet("themes/rose.json")
# Окно работы
self.osnovnoe_frame = QWidget(self)
self.osnovnoe_frame.setGeometry(QRect(300, 0, 700, 600))
# Боковой фрейм для меню
self.lev_frame = QWidget(self)
self.lev_frame.setGeometry(QRect(0, 0, 300, 600))
self.text_edit = QTextEdit(self)
self.text_edit.setGeometry(QRect(200, 50, 290, 200))
# Текст логотип
self.label = QLabel("TransScreen", self.lev_frame)
self.label.setGeometry(QRect(20, 30, 260, 50))
self.label.setStyleSheet("font: bold 25px;")
# Старт
self.button_start = QPushButton("Выделение области", self.lev_frame)
self.button_start.setGeometry(QRect(20, 100, 170, 40))
self.button_start.clicked.connect(self.start_app)
# Настройки
self.button_settings = QPushButton("Настройки", self.lev_frame)
self.button_settings.setGeometry(QRect(20, 150, 170, 40))
# Выход
self.button_exit = QPushButton("Выход", self.lev_frame)
self.button_exit.setGeometry(QRect(20, 200, 170, 40))
self.button_exit.clicked.connect(self.exit_app)
self.snipper = None
# Бинды
keyboard.on_press_key('ctrl', self.toggle_window)
# функции
def start_app(self):
self.is_selecting = True
self.hide()
self.snipper = SnippingWidget()
self.snipper.selection_finished.connect(self.handle_text_selected)
self.snipper.text_selected.connect(self.handle_text_display) # Connect the text_selected signal
self.snipper.exec_()
def handle_text_selected(self, selected_area):
# Вывод распознанного текста в QTextEdit виджет
screenshot = QtWidgets.QApplication.primaryScreen().grabWindow(0, selected_area.x(), selected_area.y(), selected_area.width(), selected_area.height())
screenshot.save("screenshot.png", "png")
text = pytesseract.image_to_string(Image.open("screenshot.png"), lang='eng')
self.text_edit.setText(text)
# Другие действия с текстом...
def handle_text_display(self, text):
self.text_edit.setText(text) # Отображение распознанного текста в QTextEdit
def exit_app(self):
self.close()
def toggle_window(self, e):
if self.isVisible():
self.hide()
else:
self.show()
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.draggable = True
self.offset = event.pos()
def mouseMoveEvent(self, event):
if self.draggable:
self.move(event.globalPos() - self.offset)
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton:
self.draggable = False
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Он должен распознавать текст с сохранённого скрина и выводить его в QTextEdit
.
Ошибок никаких не вылезает, просто завершение работы происходит.
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Некоторые косметические исправления смотрите по тексту кода:
import sys
import keyboard
from PyQt5.QtWidgets import QApplication, QMainWindow, \
QWidget, QPushButton, QVBoxLayout, QLabel, \
QTextEdit, QDialog
from PyQt5.QtCore import Qt, QRect, QPoint
from PyQt5 import QtCore, QtGui, QtWidgets
import pytesseract
from PIL import Image
class SnippingWidget(QDialog):
selection_finished = QtCore.pyqtSignal(QtCore.QRect)
text_selected = QtCore.pyqtSignal(str)
def __init__(self):
super(SnippingWidget, self).__init__()
# +++
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setAttribute(Qt.WA_TranslucentBackground)
'''
self.setAttribute(QtCore.Qt.WA_NoSystemBackground, True)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
self.setStyleSheet("background: transparent;")
self.setWindowFlags(Qt.FramelessWindowHint)
'''
self.outsideSquareColor = "red"
self.squareThickness = 2
self.start_point = QtCore.QPoint()
self.end_point = QtCore.QPoint()
self.selected_area = None
screen_geometry = QtWidgets.QApplication.desktop().screenGeometry()
self.setGeometry(screen_geometry)
def mousePressEvent(self, event):
self.start_point = event.pos()
self.end_point = event.pos()
QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.CrossCursor)
self.update()
def mouseMoveEvent(self, event):
self.end_point = event.pos()
self.update()
def mouseReleaseEvent(self, QMouseEvent):
try:
r = QtCore.QRect(self.start_point, self.end_point).normalized()
self.close()
self.selected_area = r
QtWidgets.QApplication.restoreOverrideCursor()
self.selection_finished.emit(r)
# Извлечение изображения из выделенной области
screenshot = QtWidgets.QApplication.primaryScreen().grabWindow(0, r.x(), r.y(), r.width(), r.height())
screenshot.save("screenshot.png", "png")
# Распознавание текста с помощью Tesseract OCR
text = pytesseract.image_to_string(Image.open("screenshot.png"), lang='eng')
# Передача распознанного текста в главное окно
self.text_selected.emit(text)
self.start_point = QtCore.QPoint()
self.end_point = QtCore.QPoint()
except Exception as e:
print(f'Exception as e: {e} ???????????????') # +
def paintEvent(self, event):
# ---------------------------------------> vv <----------------------------
trans = QtGui.QColor(22, 100, 233, 77)
r = QtCore.QRectF(self.start_point, self.end_point).normalized()
qp = QtGui.QPainter(self)
# trans.setAlphaF(0.2)
qp.setBrush(trans)
outer = QtGui.QPainterPath()
outer.addRect(QtCore.QRectF(self.rect()))
inner = QtGui.QPainterPath()
inner.addRect(r)
r_path = outer - inner
qp.drawPath(r_path)
qp.setPen(
QtGui.QPen(QtGui.QColor(self.outsideSquareColor), self.squareThickness)
)
# trans.setAlphaF(0)
qp.setBrush(trans)
qp.drawRect(r)
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.FramelessWindowHint)
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
self.draggable = False
self.offset = None
# set the title
self.setWindowTitle("WindowTitle")
# Удаление иконки окна
self.setWindowIconText("Ok.png")
#Размеры окна
self.setGeometry(300, 300, 500, 300)
# Установка фона и темы
# ? self.setStyleSheet("themes/rose.json")
# Окно работы # ??? это что self.osnovnoe_frame # ???
# вам надо почитать что такое setCentralWidget <--------------------
self.osnovnoe_frame = QWidget(self)
self.osnovnoe_frame.setGeometry(QRect(300, 0, 700, 600))
# Боковой фрейм для меню
self.lev_frame = QWidget(self)
self.lev_frame.setGeometry(QRect(0, 0, 300, 600))
self.text_edit = QTextEdit(self)
self.text_edit.setGeometry(QRect(200, 50, 290, 200))
# Текст логотип
self.label = QLabel("TransScreen", self.lev_frame)
self.label.setGeometry(QRect(20, 30, 260, 50))
self.label.setStyleSheet("font: bold 25px;")
# Старт
self.button_start = QPushButton("Выделение области", self.lev_frame)
self.button_start.setGeometry(QRect(20, 100, 170, 40))
self.button_start.clicked.connect(self.start_app)
# Настройки
self.button_settings = QPushButton("Настройки", self.lev_frame)
self.button_settings.setGeometry(QRect(20, 150, 170, 40))
# Выход
self.button_exit = QPushButton("Выход", self.lev_frame)
self.button_exit.setGeometry(QRect(20, 200, 170, 40))
self.button_exit.clicked.connect(self.exit_app)
self.snipper = None
# Бинды # ???
keyboard.on_press_key('ctrl', self.toggle_window)
# функции
def start_app(self):
self.is_selecting = True
# Внимание вы скрыли главное окно
# и забыли его показать чтобы увидеть вывод распознанного текста в QTextEdit
self.hide()
self.snipper = SnippingWidget()
self.snipper.selection_finished.connect(self.handle_text_selected)
self.snipper.text_selected.connect(self.handle_text_display) # Connect the text_selected signal
self.snipper.exec_()
def handle_text_selected(self, selected_area):
# Вывод распознанного текста в QTextEdit виджет
screenshot = QtWidgets.QApplication.primaryScreen().grabWindow(0, selected_area.x(), selected_area.y(), selected_area.width(), selected_area.height())
screenshot.save("screenshot.png", "png")
text = pytesseract.image_to_string(Image.open("screenshot.png"), lang='eng')
# !! ++ vvvvvvvvvvv <----------------------------------------------------
self.show()
self.text_edit.setText(text)
# Другие действия с текстом...
def handle_text_display(self, text):
self.text_edit.setText(text) # Отображение распознанного текста в QTextEdit
def exit_app(self):
self.close()
def toggle_window(self, e):
if self.isVisible():
self.hide()
else:
self.show()
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.draggable = True
self.offset = event.pos()
def mouseMoveEvent(self, event):
if self.draggable:
self.move(event.globalPos() - self.offset)
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton:
self.draggable = False
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())