Pythonで画面上の文字をリアルタイムで翻訳してみた②

# 1. はじめに

3年目に突入したエンジニアをしているものです。

**ARIのアドベンドカレンダ10日目の記事となります！**

https://qiita.com/advent-calendar/2024/ari-group

:::note warn
ちなみにタイトルの「リアルタイム」は過言なのでそのあたりはお目溢しいただければと思います。
:::


# 背景と概要

https://qiita.com/ys_kmr/items/17490e40450b8c73a2a5

前回、海外ゲームのメッセージを翻訳したいということで画面の一部を監視して、
文字列に変化があれば英語から日本語に翻訳して出力するという物ができました。

とはいえいろいろ問題があったので、今回はそのあたりの改善バージョンになります。

# 問題点
## ①翻訳結果がコンソールに出力されているだけで可読性が低い
下図の通りです。
出力日時を翻訳結果を標準出力に出しているだけなので、たいへん見づらいですね。

仕切りの線を入れるなど標準出力のまま可読性を上げる方法はありますが、
やはりコンソールで見るのはいけてない。。

別Windowで見えるようにしたいですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2660549/a42a6c57-85c4-1116-71f9-574fd1fc6dfd.png)
## ②元の文章の改行で別の文として翻訳されている
これが一番の問題かもしれないです。
ちゃんと文が翻訳されていないですね
|元画像|翻訳結果|
|-|-|
|![sample_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2660549/5c7c23c8-bee0-28a4-9045-10a6dade4d72.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2660549/89864233-a538-7ef7-4e62-9b9756d8a749.png)|

翻訳前の文字列を出力してみてみると、
文字自体は取得できていることがわかったので改行が悪さをしている気がします。

これはGoogle翻訳を使っているせいな気もしますね。
他の翻訳機能なら違ったりするんでしょうか。

## ③プログラムの終了方法が強制終了(Ctrl+C)のみ
今回はスキップします。使いやすさには直接かかわらないので。

# 実行環境・ライブラリ
変更なし（前回の記事を参照）

# ソースコード（更新部分だけ）
```python:追加部分
import tkinter as tk

# ②改行の調整関数
def replace_newlines(text):
    # 単一の改行 (\n) をスペースに置き換え
    text = text.replace("\n", " ")

    # ピリオドで改行する
    text = text.replace(".", ".\n")
    
    return text

# ①ウィンドウ内の翻訳結果を更新する関数
def update_translation(text):
    translation_label.config(text=text)
    root.update_idletasks()  # ウィンドウを即時更新
```

コメントは更新部分のみ残しています。
```python:更新部分
def monitor_screen(bbox, interval=5):
    last_text = ""
    while True:
        screenshot = ImageGrab.grab(bbox=bbox)
        # ②：不要な改行コードを削除する関数を噛ませる
        current_text = replace_newlines(pytesseract.image_to_string(screenshot))

        if current_text != last_text and current_text.strip():
            translated_text = translate_text(current_text)
            
            # ①：標準出力へのprintからウィンドウへの出力へ
            update_translation(translated_text)
            last_text = current_text
        
        # インターバルを待つ
        cv2.waitKey(interval * 100)

if __name__ == "__main__":
    bbox = list(select_region())
    bbox[2] += bbox[0]
    bbox[3] += bbox[1]
    bbox = tuple(bbox)
    print(bbox,type(bbox))
    
    screen_width, screen_height = ImageGrab.grab().size
    print("Screen size:", screen_width, screen_height)

    if bbox[0] < 0 or bbox[1] < 0 or bbox[2] > screen_width or bbox[3] > screen_height:
        raise ValueError("bbox is out of screen bounds")

    if bbox[2] > 0 and bbox[3] > 0:        
        # ①Tkinterでウィンドウを設定
        root = tk.Tk()
        root.title("翻訳結果")
        root.geometry(f"{screen_width//3}x{screen_height//3}")
        # 翻訳結果を表示するラベル
        translation_label = tk.Label(
            root,
            text="ここに翻訳結果が表示されます",  # 初期メッセージ
            wraplength=screen_width//3 - 20,    # テキストをウィンドウ幅に収まるよう自動改行
            font=("Yu Gothic", 14),             # フォントサイズ指定
            justify="left",                     # 左揃え（複数行テキストの整列）
            anchor="nw",                        # テキストの左上揃え（northwest）
        )
        translation_label.pack(padx=10, pady=10, expand=True, fill=tk.BOTH)

        monitor_screen(bbox)
        
        # ウィンドウを閉じる処理
        root.mainloop()
```

# デモ
前回と同じくChatGPTに出力してもらった文字列をデモに使用しています。

![Code_PWYDTikESV.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2660549/8f3196d9-343c-f498-3fac-c8bdc83aa175.gif)

# 終わりに
無事当初の目的の①、②の問題については改善することができました。
とはいえ③は放置ですし、使ってみると不満点は多々出てくるクオリティです。
※その他の要改善点
- ウィンドウサイズを変更しても改行位置は固定
- 最初はウィンドウを動かさないと文字が出ない
- 例文のようなタイトル⇒内容のような場合に対応できていない
- etc..

ただまぁこの辺りは脳内で補完できるレベルではあるので、一旦は完成にしようかと思います。
気が向けば改修してまた投稿しようと思います。

最後までお読みいただきありがとうございました。

https://qiita.com/advent-calendar/2024/ari-group

前回記事：

https://qiita.com/ys_kmr/items/17490e40450b8c73a2a5