easyocr + pyqt, 模拟微信图片查看器,提取图片上的文字

打造一个图片文字选择工具

先看效果:
easyocr + pyqt, 模拟微信图片查看器,提取图片上的文字_第1张图片

对比微信的效果:
easyocr + pyqt, 模拟微信图片查看器,提取图片上的文字_第2张图片

1. 起因,目的,来源
  • 起因:平时我都是,用微信图片查看器,提取手机截图上的文字(主要是电子书读书笔记),但它老忽略标点符号,得手动断句,太烦了。
  • 目的:想自己搞一个工具,支持精准识别,还能像文本编辑器那样拖拽选择文字。
  • 来源:从 GitHub 上找了简单的 OCR 项目,选了 EasyOCR 开始折腾。
2. 功能,与 Grok AI 的聊天,调试过程
  • 基础功能:先用 EasyOCR 提取图片文字,能整块提取,但没法精细选择。
  • 加界面:找 Grok AI 帮忙,用 PyQt5 搭了个窗口,显示图片,鼠标能拖拽,但一开始没法选中文字。
  • 实现选择:Grok 加了鼠标事件,实现了拖拽选择,选中文字还能复制到剪贴板。
  • 蓝色背景:想要视觉提示,Grok 用 QPainter 加了浅蓝色背景,拖拽时显示,松开后保持,除非点空白处清空。
  • 优化体验:Grok 改了光标,在文字上变成“工”形,拖拽时才显示蓝色背景,还加了换行符,让复制的文字能换行。
  • 右键菜单:加了右键菜单,支持“复制”和“打印”(控制台输出),去掉自动复制,改成手动 Ctrl+C。
  • 字符级选择:想精确到字符,Grok 估算字符位置,支持选一行里的部分字符或跨行选部分,但效果不稳定,有时候选不中,就先用前一个版本。
  • 调试过程:Grok 一步步改代码,基本 1-2 小时搞定一个功能,用我的图片(img1.jpg)测试,建议很实用。

过程:

1. pyqt + easyocr, 用来演示效果
  • 此代码,至少是有个界面,能让用户看到效果。
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget, QMenu
from PyQt5.QtGui import QPixmap, QPainter, QColor, QBrush, QCursor
from PyQt5.QtCore import Qt
import easyocr
import pyperclip

# OCR 提取文字和边界框
def extract_text_with_bbox(image_path):
    reader = easyocr.Reader(['ch_sim', 'en'])
    result = reader.readtext(image_path)
    return [(text, bbox) for (bbox, text, prob) in result]

# 自定义 QLabel 类,支持绘制选中区域和右键菜单
class ImageLabel(QLabel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.selected_regions = []  # 存储选中文字的边界框
        self.parent_window = parent  # 引用父窗口以访问选中文本

    def set_selected_regions(self, regions):
        self.selected_regions = regions
        self.update()  # 触发重绘

    def paintEvent(self, event):
        super().paintEvent(event)
        painter = QPainter(self)
        painter.setBrush(QBrush(QColor(135, 206, 250, 128)))  # 浅蓝色,半透明
        painter.setPen(Qt.NoPen)
        for region in self.selected_regions:
            x1, y1 = region[0][0], region[0][1]
            x2, y2 = region[2][0], region[2][1]
            painter.drawRect(x1, y1, x2 - x1, y2 - y1)
        painter.end()

    def contextMenuEvent(self, event):
        selected_text = self.parent_window.get_selected_text()
        if not selected_text:
            return

        menu = QMenu(self)
        copy_action = menu.addAction("复制")
        print_action = menu.addAction("打印")

        action = menu.exec_(self.mapToGlobal(event.pos()))

        if action == copy_action:
            pyperclip.copy(selected_text)
            print(f"Copied to clipboard: {
     selected_text}")
        elif action == print_action:
            print(f"Printed text: {
     selected_text}"

你可能感兴趣的:(pyqt,微信,ocr,python)