[Python]剪貼簿 OCR 工具使用教學

這是一個簡單易用的剪貼簿 OCR 工具,可以自動識別從 Snipaste 等截圖工具複製到剪貼簿的圖片內容,並轉換為文字。

必要安裝項目

在開始使用前,您需要安裝以下項目:

1. 安裝 Python

  • Python 官網 下載並安裝 Python 3.7 或更高版本
  • 安裝時勾選「Add Python to PATH」選項

2. 安裝 Tesseract OCR

  • Tesseract 官方 下載並安裝 Tesseract OCR
  • 建議選擇帶有中文和英文語言包的安裝選項
  • 記住安裝路徑,預設為 C:\Program Files\Tesseract-OCR

3. 安裝必要的 Python 套件

打開命令提示字元(CMD)或 PowerShell,執行以下命令:

pip install pyperclip pillow pytesseract

4. 安裝 Snipaste

  • Snipaste 官網 下載並安裝 Snipaste
  • 設定截圖快捷鍵,方便使用

工具設置與使用

步驟一:下載 OCR 工具程式碼

  1. 建立一個新資料夾用於存放 OCR 工具
  2. 在資料夾中創建一個名為 ocr_tool.py 的檔案
  3. 將以下程式碼複製到檔案中:
import tkinter as tk
from tkinter import scrolledtext, messagebox, ttk
import pyperclip
from PIL import ImageGrab, Image
import pytesseract
import threading
import os
import sys

def get_tesseract_path():
    """獲取 Tesseract 可執行檔的路徑"""
    # 首先檢查標準安裝路徑
    standard_paths = [
        r'C:\Program Files\Tesseract-OCR\tesseract.exe',
        r'C:\Program Files (x86)\Tesseract-OCR\tesseract.exe'
    ]

    # 檢查相對路徑
    script_dir = os.path.dirname(os.path.abspath(__file__))
    relative_path = os.path.join(script_dir, 'Tesseract-OCR', 'tesseract.exe')

    # 檢查所有可能的路徑
    for path in standard_paths + [relative_path]:
        if os.path.exists(path):
            return path

    # 返回預設路徑
    return r'C:\Program Files\Tesseract-OCR\tesseract.exe'

class OCRApp:
    def __init__(self, root):
        self.root = root
        self.root.title("剪貼簿OCR工具")
        self.root.geometry("600x400")

        # 設定 Tesseract 路徑
        self.tesseract_path = get_tesseract_path()

        # 檢查 Tesseract 是否可用
        if not os.path.exists(self.tesseract_path):
            messagebox.showwarning(
                "找不到Tesseract", 
                f"找不到Tesseract OCR程式於: {self.tesseract_path}\n"
                "請確認已正確安裝Tesseract OCR。"
            )
        else:
            pytesseract.pytesseract.tesseract_cmd = self.tesseract_path

        # 可用語言(需要確保語言文件在 Tesseract 路徑內)
        self.languages = {
            "繁體中文+英文": "chi_tra+eng",
            "簡體中文+英文": "chi_sim+eng",
            "英文": "eng",
            "日文+英文": "jpn+eng",
            "韓文+英文": "kor+eng"
        }

        # 創建GUI元素
        self.create_widgets()

        # 開始持續檢查剪貼簿
        self.check_clipboard()

    def create_widgets(self):
        # 頂部按鈕框架
        button_frame = tk.Frame(self.root)
        button_frame.pack(fill=tk.X, padx=10, pady=5)

        # 貼上按鈕
        self.paste_btn = tk.Button(button_frame, text="從剪貼簿讀取圖片", command=self.process_clipboard)
        self.paste_btn.pack(side=tk.LEFT, padx=5)

        # 複製按鈕
        self.copy_btn = tk.Button(button_frame, text="複製文字到剪貼簿", command=self.copy_to_clipboard)
        self.copy_btn.pack(side=tk.LEFT, padx=5)

        # 語言選擇
        lang_frame = tk.Frame(self.root)
        lang_frame.pack(fill=tk.X, padx=10, pady=5)

        tk.Label(lang_frame, text="OCR語言:").pack(side=tk.LEFT, padx=5)
        self.lang_var = tk.StringVar()
        self.lang_var.set("繁體中文+英文")  # 預設

        lang_dropdown = ttk.Combobox(lang_frame, textvariable=self.lang_var)
        lang_dropdown['values'] = list(self.languages.keys())
        lang_dropdown['state'] = 'readonly'
        lang_dropdown.pack(side=tk.LEFT, padx=5)

        # 狀態標籤
        self.status_var = tk.StringVar()
        self.status_var.set("就緒")
        self.status_label = tk.Label(lang_frame, textvariable=self.status_var)
        self.status_label.pack(side=tk.RIGHT, padx=5)

        # 文字區域
        text_frame = tk.Frame(self.root)
        text_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

        self.text_area = scrolledtext.ScrolledText(text_frame, wrap=tk.WORD)
        self.text_area.pack(fill=tk.BOTH, expand=True)

    def check_clipboard(self):
        """持續檢查剪貼簿中的圖片"""
        try:
            # 檢查剪貼簿是否包含圖片
            img = ImageGrab.grabclipboard()
            if isinstance(img, Image.Image) and not hasattr(self, 'last_image'):
                # 有新圖片
                self.last_image = img
                # 自動處理圖片
                self.process_clipboard()
            elif isinstance(img, Image.Image) and hasattr(self, 'last_image'):
                # 與上一張圖片比較(簡化檢查)
                if img.size != self.last_image.size:
                    self.last_image = img
                    self.process_clipboard()
            elif not isinstance(img, Image.Image) and hasattr(self, 'last_image'):
                # 剪貼簿不再包含圖片
                delattr(self, 'last_image')

        except Exception as e:
            print(f"檢查剪貼簿時出錯: {e}")

        # 1秒後安排下一次檢查
        self.root.after(1000, self.check_clipboard)

    def process_clipboard(self):
        """使用OCR處理剪貼簿中的圖片"""
        try:
            self.status_var.set("處理中...")
            self.root.update()

            # 從剪貼簿獲取圖片
            img = ImageGrab.grabclipboard()

            if img is None or not isinstance(img, Image.Image):
                self.status_var.set("剪貼簿中沒有圖片")
                return

            # 在單獨的線程中運行OCR,避免GUI凍結
            threading.Thread(target=self.perform_ocr, args=(img,), daemon=True).start()

        except Exception as e:
            self.status_var.set(f"錯誤: {str(e)}")

    def perform_ocr(self, img):
        """對圖片執行OCR"""
        try:
            # 獲取選定的語言
            lang_key = self.lang_var.get()
            lang_code = self.languages.get(lang_key, "chi_tra+eng")

            # 確保圖片是 RGB 模式
            if img.mode != 'RGB':
                img = img.convert('RGB')

            # 創建臨時目錄(如果不存在)
            temp_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'temp')
            os.makedirs(temp_dir, exist_ok=True)

            # 保存為臨時文件
            temp_path = os.path.join(temp_dir, 'temp_ocr_image.png')
            img.save(temp_path, format='PNG')

            # 從文件讀取並執行 OCR
            text = pytesseract.image_to_string(Image.open(temp_path), lang=lang_code)

            # 刪除臨時文件
            try:
                os.remove(temp_path)
            except:
                pass

            # 在主線程中更新文字區域
            self.root.after(0, self.update_text_area, text)

        except Exception as e:
            self.root.after(0, self.update_status, f"OCR錯誤: {str(e)}")

    def update_text_area(self, text):
        """使用OCR結果更新文字區域"""
        self.text_area.delete(1.0, tk.END)
        self.text_area.insert(tk.INSERT, text)
        self.status_var.set("OCR完成")

    def update_status(self, message):
        """更新狀態標籤"""
        self.status_var.set(message)

    def copy_to_clipboard(self):
        """將文字複製到剪貼簿"""
        text = self.text_area.get(1.0, tk.END).strip()
        if text:
            pyperclip.copy(text)
            self.status_var.set("已複製到剪貼簿")
        else:
            self.status_var.set("沒有文字可複製")

if __name__ == "__main__":
    root = tk.Tk()
    app = OCRApp(root)
    root.mainloop()

步驟二:運行 OCR 工具

  1. 打開命令提示字元或 PowerShell
  2. 導航到包含 ocr_tool.py 的資料夾
  3. 執行以下命令:
python ocr_tool.py
  1. OCR 工具視窗將會啟動

如何使用 OCR 工具

基本功能

  1. 自動識別:工具會自動監視剪貼簿,當有新圖片複製到剪貼簿時自動執行 OCR
  2. 手動觸發:點擊「從剪貼簿讀取圖片」按鈕可手動觸發識別
  3. 複製結果:點擊「複製文字到剪貼簿」按鈕可複製識別結果到剪貼簿
  4. 多語言支援:可從下拉選單選擇識別語言(需要安裝對應的語言包)

結合 Snipaste 使用的流程

  1. 按下 Snipaste 設定的截圖快捷鍵(預設為 F1)
  2. 截取包含文字的區域
  3. 按下 F3 自動複製截圖到剪貼簿
  4. OCR 工具將自動檢測到新圖片並執行文字識別
  5. 識別完成後,可以點擊「複製文字到剪貼簿」按鈕將結果複製出來

提高識別准確率的技巧

  1. 保持文字清晰:截圖時確保文字清晰可見
  2. 裁剪精準:只截取包含文字的區域,減少背景干擾
  3. 選擇正確語言:根據圖片中的文字選擇適當的識別語言
  4. 調整對比度:如果文字與背景對比度不高,可以使用 Snipaste 的標記工具調整

常見問題解決

如何更新 OCR 語言支持?

如需添加更多語言支持,請在 Tesseract 安裝目錄的 tessdata 文件夾中添加對應的語言文件(.traineddata)。語言文件可從 Tesseract GitHub 下載。

如何創建桌面捷徑?

  1. 創建一個新的文本文件,命名為 啟動OCR工具.bat
  2. 編輯文件,添加以下內容:
@echo off
cd /d "完整路徑到您的OCR工具資料夾"
python ocr_tool.py
  1. 將此批處理文件保存在桌面或其他方便訪問的位置

結語

這個簡單的 OCR 工具可以幫助您快速識別剪貼簿中的圖片文字。結合 Snipaste 使用,能顯著提高文字採集和處理的效率。只要按照上述步驟設置,您就可以享受便捷的文字識別體驗。

希望這個工具能幫助到您的日常工作!

發佈留言