概要
Windowsのデスクトップを範囲指定し、リアルタイム翻訳するアプリです。
作成を始めたばかりのベータ版状態で、OCR、翻訳ともにいまいちです。
精度が発展途上のため、デザインフォントやドットの粗いフォントのスキャン品質が良くないですが、内よりまり、英語でしかゲームが出ていない時などのプレイを助けてくれるかと思います。
操作動画
アプリ構成
Pythonで作っています。
一部OCRはGoogleのTesseract OCRを別にインストールして使います。
■ Tesseract OCR について
本ツールで Tesseract OCR モードを使用する場合は、
別途 Tesseract OCR をインストールしてください。公式サイト:
https://github.com/tesseract-ocr/tesseract
インストール後、アプリ内の
「tesseract.exe パス」に実行ファイルの場所を指定してください。
ライブラリ
# requirements.txt (v0.5.3)
mss>=9.0.1
pytesseract>=0.3.10
Pillow>=10.0.0
PySide6>=6.6.0
deep-translator>=1.11.4
# EasyOCRを使う場合(任意)
easyocr>=1.7.1
torch>=2.0.0
torchvision>=0.15.0
# EasyOCR内部で使用(環境によっては依存で入るが明示)
numpy>=1.26.0コード
import os
import sys
from dataclasses import dataclass
from datetime import datetime
import mss
import pytesseract
from PIL import Image, ImageOps
from deep_translator import GoogleTranslator
from PySide6 import QtCore, QtGui, QtWidgets
# ---- DPI Aware(ある程度効くが、座標変換で吸収)----
def enable_dpi_awareness_windows():
if sys.platform != "win32":
return
try:
import ctypes
user32 = ctypes.windll.user32
# DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = -4
user32.SetProcessDpiAwarenessContext(ctypes.c_void_p(-4))
except Exception:
try:
import ctypes
ctypes.windll.user32.SetProcessDPIAware()
except Exception:
pass
# ---- 設定 ----
APP_VERSION = "0.5.3"
DEFAULT_TESSERACT_PATH = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
OCR_INTERVAL_MS = 800
MAX_TEXT_LEN = 1500
OVERLAY_BG_ALPHA = 220
DEBUG_DIR = "debug"
DEBUG_LATEST_PATH = os.path.join(DEBUG_DIR, "latest.png")
DEBUG_LOG_PATH = os.path.join(DEBUG_DIR, "debug_log.txt")
# ---- EasyOCR(オプション)----
try:
import easyocr # type: ignore
EASYOCR_AVAILABLE = True
except Exception:
EASYOCR_AVAILABLE = False
@dataclass
class CaptureRect:
left: int
top: int
width: int
height: int
def is_valid(self) -> bool:
return self.width > 5 and self.height > 5
class RegionSelector(QtWidgets.QWidget):
rectSelected = QtCore.Signal(QtCore.QRect)
def __init__(self):
super().__init__()
self.setWindowTitle("Select Region")
self.setWindowFlag(QtCore.Qt.WindowType.FramelessWindowHint, True)
self.setWindowFlag(QtCore.Qt.WindowType.WindowStaysOnTopHint, True)
self.setAttribute(QtCore.Qt.WidgetAttribute.WA_TranslucentBackground, True)
self.setCursor(QtCore.Qt.CursorShape.CrossCursor)
vg = QtGui.QGuiApplication.primaryScreen().virtualGeometry()
self.setGeometry(vg)
self.showFullScreen()
self._origin_local: QtCore.QPoint | None = None
self._current_local: QtCore.QPoint | None = None
def paintEvent(self, event: QtGui.QPaintEvent) -> None:
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.RenderHint.Antialiasing)
painter.fillRect(self.rect(), QtGui.QColor(0, 0, 0, 60))
if self._origin_local and self._current_local:
r_local = QtCore.QRect(self._origin_local, self._current_local).normalized()
painter.fillRect(r_local, QtGui.QColor(0, 0, 0, 0))
pen = QtGui.QPen(QtGui.QColor(0, 180, 255, 220), 2)
painter.setPen(pen)
painter.drawRect(r_local)
text = f"{r_local.width()} x {r_local.height()}"
painter.setPen(QtGui.QColor(255, 255, 255, 240))
painter.drawText(r_local.topLeft() + QtCore.QPoint(6, -6), text)
def mousePressEvent(self, event: QtGui.QMouseEvent) -> None:
if event.button() == QtCore.Qt.MouseButton.LeftButton:
self._origin_local = event.position().toPoint()
self._current_local = self._origin_local
self.update()
def mouseMoveEvent(self, event: QtGui.QMouseEvent) -> None:
if self._origin_local:
self._current_local = event.position().toPoint()
self.update()
def mouseReleaseEvent(self, event: QtGui.QMouseEvent) -> None:
if event.button() == QtCore.Qt.MouseButton.LeftButton and self._origin_local:
self._current_local = event.position().toPoint()
r_local = QtCore.QRect(self._origin_local, self._current_local).normalized()
tl_global = self.mapToGlobal(r_local.topLeft())
br_global = self.mapToGlobal(r_local.bottomRight())
r_global = QtCore.QRect(tl_global, br_global).normalized()
self._origin_local = None
self._current_local = None
self.update()
self.rectSelected.emit(r_global)
self.close()
def keyPressEvent(self, event: QtGui.QKeyEvent) -> None:
if event.key() == QtCore.Qt.Key.Key_Escape:
self.close()
def preprocess_pixel_pil(img: Image.Image, scale: int = 4, threshold: int = 185) -> Image.Image:
g = img.convert("L")
g = g.resize((g.width * scale, g.height * scale), resample=Image.Resampling.NEAREST)
g = ImageOps.autocontrast(g)
bw = g.point(lambda p: 255 if p > threshold else 0, mode="1")
return bw.convert("L")
def tess_ocr(img: Image.Image, lang: str, psm: int, disable_dawg: bool = False, whitelist: str | None = None) -> str:
cfg = [f"--oem 3 --psm {psm}"]
if disable_dawg:
cfg.append("-c load_system_dawg=0")
cfg.append("-c load_freq_dawg=0")
if whitelist:
cfg.append(f"-c tessedit_char_whitelist={whitelist}")
config = " ".join(cfg)
return pytesseract.image_to_string(img, lang=lang, config=config)
class OverlayWindow(QtWidgets.QWidget):
"""
- ドラッグ移動可能
- 折りたたみ(本文だけ隠す)
- 隠す(タスクバーから消す / show()で復帰)
"""
def __init__(self):
super().__init__()
self.setWindowTitle("Translation Overlay")
# フレームレス + 常に最前面 + タスクバーに出さない(Tool)
self.setWindowFlag(QtCore.Qt.WindowType.FramelessWindowHint, True)
self.setWindowFlag(QtCore.Qt.WindowType.WindowStaysOnTopHint, True)
self.setWindowFlag(QtCore.Qt.WindowType.Tool, True)
self.setAttribute(QtCore.Qt.WidgetAttribute.WA_TranslucentBackground, True)
self._dragging = False
self._drag_offset = QtCore.QPoint(0, 0)
self._collapsed = False
self._expanded_size = QtCore.QSize(520, 240)
# --- タイトルバー ---
self.title = QtWidgets.QLabel("Translation")
self.title.setStyleSheet("QLabel { color: white; font-weight: 600; }")
self.btn_collapse = QtWidgets.QToolButton()
self.btn_collapse.setText("_") # 折りたたみ
self.btn_collapse.setToolTip("折りたたみ / 展開")
self.btn_hide = QtWidgets.QToolButton()
self.btn_hide.setText("×") # 隠す
self.btn_hide.setToolTip("隠す(非表示)")
self.btn_collapse.clicked.connect(self.toggle_collapse)
self.btn_hide.clicked.connect(self.hide_overlay)
bar = QtWidgets.QHBoxLayout()
bar.setContentsMargins(10, 8, 10, 0)
bar.addWidget(self.title)
bar.addStretch(1)
bar.addWidget(self.btn_collapse)
bar.addWidget(self.btn_hide)
# --- 本文 ---
self._label = QtWidgets.QLabel("")
self._label.setWordWrap(True)
self._label.setTextInteractionFlags(QtCore.Qt.TextInteractionFlag.TextSelectableByMouse)
# “背景の濃いパネル”を丸ごと一枚にして、バー+本文を載せる
self.panel = QtWidgets.QFrame()
self.panel.setStyleSheet(f"""
QFrame {{
background: rgba(0, 0, 0, {OVERLAY_BG_ALPHA});
border: 1px solid rgba(255, 255, 255, 100);
border-radius: 10px;
}}
QLabel {{
background: transparent;
color: white;
font-size: 16px;
}}
QToolButton {{
background: rgba(255,255,255,30);
color: white;
border: 1px solid rgba(255,255,255,60);
border-radius: 6px;
padding: 2px 6px;
}}
QToolButton:hover {{
background: rgba(255,255,255,60);
}}
""")
panel_layout = QtWidgets.QVBoxLayout(self.panel)
panel_layout.setContentsMargins(0, 0, 0, 10)
panel_layout.addLayout(bar)
panel_layout.addWidget(self._label, 1)
panel_layout.setSpacing(6)
outer = QtWidgets.QVBoxLayout(self)
outer.setContentsMargins(0, 0, 0, 0)
outer.addWidget(self.panel)
self.resize(self._expanded_size)
self._label.setText("(翻訳結果がここに表示されます)")
def set_text(self, text: str):
if not self._collapsed:
self._label.setText(text if text.strip() else "(文字が検出されません)")
def set_text_cache(self, text: str):
# 折りたたみ中でも内部更新しておく(展開したら見える)
self._label.setText(text if text.strip() else "(文字が検出されません)")
def toggle_collapse(self):
if not self._collapsed:
self._expanded_size = self.size()
self._label.setVisible(False)
self._collapsed = True
self.btn_collapse.setText("▢") # 展開アイコンっぽく
# 高さを小さく
self.resize(self._expanded_size.width(), 44)
else:
self._label.setVisible(True)
self._collapsed = False
self.btn_collapse.setText("_")
self.resize(self._expanded_size)
def hide_overlay(self):
self.hide()
# --- ドラッグ移動(どこ掴んでもOK)---
def mousePressEvent(self, event: QtGui.QMouseEvent) -> None:
if event.button() == QtCore.Qt.MouseButton.LeftButton:
self._dragging = True
self._drag_offset = event.globalPosition().toPoint() - self.frameGeometry().topLeft()
event.accept()
def mouseMoveEvent(self, event: QtGui.QMouseEvent) -> None:
if self._dragging:
self.move(event.globalPosition().toPoint() - self._drag_offset)
event.accept()
def mouseReleaseEvent(self, event: QtGui.QMouseEvent) -> None:
if event.button() == QtCore.Qt.MouseButton.LeftButton:
self._dragging = False
event.accept()
class MainWindow(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle(f"OCR → Translate Prototype v{APP_VERSION}")
self.setMinimumWidth(820)
self.tess_path = QtWidgets.QLineEdit(DEFAULT_TESSERACT_PATH)
self.btn_pick = QtWidgets.QPushButton("処理範囲を選択(ドラッグ)")
self.btn_start = QtWidgets.QPushButton("開始")
self.btn_stop = QtWidgets.QPushButton("停止")
self.btn_stop.setEnabled(False)
# オーバーレイ表示/復帰
self.btn_overlay_show = QtWidgets.QPushButton("翻訳ウィンドウを表示")
self.btn_overlay_show.clicked.connect(self.show_overlay)
self.chk_debug = QtWidgets.QCheckBox("デバッグ: debug/ にキャプチャ画像・ログを保存")
self.chk_debug.setChecked(True)
# 翻訳方向
self.tr_mode = QtWidgets.QComboBox()
self.tr_mode.addItem("English → Japanese", ("en", "ja"))
self.tr_mode.addItem("Japanese → English", ("ja", "en"))
# OCRモード
self.ocr_mode = QtWidgets.QComboBox()
self.ocr_mode.addItem("Tesseract: v0.5互換 (psm6)", "tess_psm6")
self.ocr_mode.addItem("Tesseract: 字幕1行向け (psm7)", "tess_psm7")
self.ocr_mode.addItem("Tesseract: ドット向けPIL前処理 + psm7 + 辞書OFF", "tess_pixel")
if EASYOCR_AVAILABLE:
self.ocr_mode.addItem("EasyOCR: フォント耐性強め(初回重い)", "easyocr")
else:
self.ocr_mode.addItem("EasyOCR: 未導入(無効)", "easyocr_unavailable")
self.ocr_mode.model().item(self.ocr_mode.count() - 1).setEnabled(False)
self.rect_label = QtWidgets.QLabel("未選択")
self.status = QtWidgets.QLabel("待機中")
self.raw_text = QtWidgets.QPlainTextEdit()
self.raw_text.setReadOnly(True)
form = QtWidgets.QFormLayout()
form.addRow("tesseract.exe パス", self.tess_path)
form.addRow("翻訳方向", self.tr_mode)
form.addRow("OCRモード", self.ocr_mode)
form.addRow("現在の範囲", self.rect_label)
btn_row = QtWidgets.QHBoxLayout()
btn_row.addWidget(self.btn_pick)
btn_row.addStretch(1)
btn_row.addWidget(self.btn_start)
btn_row.addWidget(self.btn_stop)
overlay_row = QtWidgets.QHBoxLayout()
overlay_row.addWidget(self.btn_overlay_show)
overlay_row.addStretch(1)
layout = QtWidgets.QVBoxLayout(self)
layout.addLayout(form)
layout.addWidget(self.chk_debug)
layout.addLayout(btn_row)
layout.addLayout(overlay_row)
layout.addWidget(QtWidgets.QLabel("ステータス"))
layout.addWidget(self.status)
layout.addWidget(QtWidgets.QLabel("OCR原文"))
layout.addWidget(self.raw_text)
self.overlay = OverlayWindow()
self.overlay.show() # 既定で表示
self.timer = QtCore.QTimer(self)
self.timer.setInterval(OCR_INTERVAL_MS)
self.timer.timeout.connect(self.tick)
self._busy = False
self._last_ocr = ""
self._last_translated = ""
self._last_overlay_text = ""
self.selector: RegionSelector | None = None
self.selected_qt_global: QtCore.QRect | None = None
self.mss_virtual = None # dict
self._easy_readers = {}
self.btn_pick.clicked.connect(self.pick_region)
self.btn_start.clicked.connect(self.start)
self.btn_stop.clicked.connect(self.stop)
def show_overlay(self):
self.overlay.show()
self.overlay.raise_()
self.overlay.activateWindow()
# 折りたたみ中でも表示内容を復元できるように
self.overlay.set_text_cache(self._last_overlay_text or "(翻訳結果がここに表示されます)")
def ensure_debug_dir(self):
if self.chk_debug.isChecked():
os.makedirs(DEBUG_DIR, exist_ok=True)
def log_debug(self, msg: str):
if not self.chk_debug.isChecked():
return
self.ensure_debug_dir()
line = f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {msg}\n"
try:
with open(DEBUG_LOG_PATH, "a", encoding="utf-8") as f:
f.write(line)
except Exception:
pass
def pick_region(self):
self.status.setText("範囲選択中(ドラッグ / ESCでキャンセル)")
self.selector = RegionSelector()
self.selector.rectSelected.connect(self.on_region_selected)
self.selector.destroyed.connect(lambda: setattr(self, "selector", None))
self.selector.show()
def on_region_selected(self, r_qt_global: QtCore.QRect):
self.selected_qt_global = r_qt_global
qt_vg = QtGui.QGuiApplication.primaryScreen().virtualGeometry()
self.rect_label.setText(
f"QtRect=({r_qt_global.left()},{r_qt_global.top()},{r_qt_global.width()},{r_qt_global.height()})"
)
self.status.setText("範囲が選択されました。開始できます。")
self.log_debug(
f"Qt virtualGeometry: left={qt_vg.left()} top={qt_vg.top()} w={qt_vg.width()} h={qt_vg.height()}"
)
# 初回だけ “近くに置く” くらい(以後はユーザーが動かす前提)
if not self.overlay.isVisible():
self.overlay.move(r_qt_global.right() + 12, r_qt_global.top())
self.overlay.show()
def start(self):
tp = self.tess_path.text().strip()
if tp and os.path.exists(tp):
pytesseract.pytesseract.tesseract_cmd = tp
else:
self.status.setText("tesseract.exe のパスが見つかりません。")
return
if not self.selected_qt_global or self.selected_qt_global.width() < 6 or self.selected_qt_global.height() < 6:
self.status.setText("処理範囲が未選択です。")
return
with mss.mss() as sct:
self.mss_virtual = sct.monitors[0]
self.log_debug(f"mss monitors[0] (virtual): {self.mss_virtual}")
self.ensure_debug_dir()
self._last_ocr = ""
self._last_translated = ""
self.btn_start.setEnabled(False)
self.btn_stop.setEnabled(True)
self.btn_pick.setEnabled(False)
src, tgt = self.tr_mode.currentData()
mode = self.ocr_mode.currentData()
self.status.setText(f"実行中…(OCR: {mode}, 翻訳: {src}->{tgt})")
self.timer.start()
def stop(self):
self.timer.stop()
self.btn_start.setEnabled(True)
self.btn_stop.setEnabled(False)
self.btn_pick.setEnabled(True)
self.status.setText("停止しました。")
def qt_rect_to_mss_rect(self, r_qt_global: QtCore.QRect) -> CaptureRect:
assert self.mss_virtual is not None
qt_vg = QtGui.QGuiApplication.primaryScreen().virtualGeometry()
mv = self.mss_virtual
scale_x = mv["width"] / qt_vg.width()
scale_y = mv["height"] / qt_vg.height()
left = int((r_qt_global.left() - qt_vg.left()) * scale_x + mv["left"])
top = int((r_qt_global.top() - qt_vg.top()) * scale_y + mv["top"])
width = int(r_qt_global.width() * scale_x)
height = int(r_qt_global.height() * scale_y)
return CaptureRect(left, top, width, height)
def get_translator(self):
src, tgt = self.tr_mode.currentData()
return GoogleTranslator(source=src, target=tgt)
def get_easy_reader(self, src_lang: str):
if src_lang not in self._easy_readers:
self.status.setText("EasyOCR初期化中(初回だけ少し時間がかかります)")
QtWidgets.QApplication.processEvents()
self._easy_readers[src_lang] = easyocr.Reader([src_lang], gpu=False)
return self._easy_readers[src_lang]
def tick(self):
if self._busy:
return
self._busy = True
try:
if not self.selected_qt_global or not self.mss_virtual:
return
cap = self.qt_rect_to_mss_rect(self.selected_qt_global)
if not cap.is_valid():
return
img = self.capture_region(cap)
if self.chk_debug.isChecked():
self.ensure_debug_dir()
try:
img.save(DEBUG_LATEST_PATH)
except Exception:
pass
src, tgt = self.tr_mode.currentData()
mode = self.ocr_mode.currentData()
tess_lang = "eng" if src == "en" else "jpn"
if mode == "tess_psm6":
text = tess_ocr(img.convert("L"), lang=tess_lang, psm=6)
elif mode == "tess_psm7":
text = tess_ocr(img.convert("L"), lang=tess_lang, psm=7)
elif mode == "tess_pixel":
pre = preprocess_pixel_pil(img, scale=4, threshold=185)
if src == "en":
whitelist = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,!?;:'\"-()[] "
text = tess_ocr(pre, lang="eng", psm=7, disable_dawg=True, whitelist=whitelist)
else:
text = tess_ocr(pre, lang="jpn", psm=7, disable_dawg=True)
elif mode == "easyocr":
reader = self.get_easy_reader(src)
import numpy as _np
arr = _np.array(img.convert("RGB"))
results = reader.readtext(arr, detail=0, paragraph=True)
text = "\n".join(results)
else:
text = ""
text = (text or "").strip()
text = text[:MAX_TEXT_LEN].strip()
if text and text != self._last_ocr:
self._last_ocr = text
self.raw_text.setPlainText(text)
try:
translated = self.get_translator().translate(text)
except Exception as e:
translated = f"翻訳エラー: {e}"
if translated != self._last_translated:
self._last_translated = translated
self._last_overlay_text = translated
# 折りたたみ中も内部更新
self.overlay.set_text_cache(translated)
self.overlay.set_text(translated)
elif not text:
self.raw_text.setPlainText("")
self._last_overlay_text = "(文字が検出されません)"
self.overlay.set_text_cache(self._last_overlay_text)
self.overlay.set_text(self._last_overlay_text)
finally:
self._busy = False
@staticmethod
def capture_region(rect: CaptureRect) -> Image.Image:
with mss.mss() as sct:
monitor = {"left": rect.left, "top": rect.top, "width": rect.width, "height": rect.height}
shot = sct.grab(monitor)
return Image.frombytes("RGB", shot.size, shot.rgb)
def main():
enable_dpi_awareness_windows()
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()
ダウンロード
レンタルサーバだとウイルス検出等不安があるため、Googleドライブで配布します。
次のリンク先からzipをダウンロードし、zip回答して app.exeを起動してください。
ocr_translate_overlay
https://drive.google.com/drive/folders/1OUL66DKSsvZVrW8y-2aVFLTl2zpiQUjf?usp=drive_link
追加インストールが必要なTesseract OCR について
本ツールで Tesseract OCR モードを使用する場合は、
別途 Tesseract OCR をインストールしてください。
公式サイト:
https://github.com/tesseract-ocr/tesseract
インストール後、アプリ内の
「tesseract.exe パス」に実行ファイルの場所を指定してください。
使い方
OCR Translate Overlay v0.5.3
画面OCR+翻訳 オーバーレイツール(Windows)
翻訳中、少し画面操作の反応が悪くなります。その時は、停止ボタンを押してください。リアルタイム翻訳が停止します。
■ このツールについて
本ツールは、画面上の文字(英語・日本語)をOCRで読み取り、
翻訳結果をデスクトップ上にフローティング表示する
Windows向けのオーバーレイ翻訳アプリです。
・ゲーム画面の字幕
・海外アプリや英語UI
・動画再生中のテキスト
などを、アプリを切り替えずに翻訳できます。
Pythonや仮想環境の構築は不要です。
exeを起動するだけで利用できます。
■ 動作環境
・Windows 10 / Windows 11(64bit)
・インターネット接続(翻訳に使用)
※ EasyOCRモードを使用する場合、初回起動時は
少し時間がかかることがあります。
■ フォルダ構成(重要)
以下の構成を保ったまま使用してください。
OCRTranslateOverlay/
├─ app.exe
├─ debug(debug機能をオンにしたときにスキャン範囲を画像化します、スキャン座標確認用)
├─ LICENSE.txt
└─ readme.txt
※ フォルダごと移動しても動作します
※ Program Files 配下でも、ユーザーフォルダでも使用可能です
■ 起動方法
※ 初回起動時、Windowsの警告が出る場合がありますが
「詳細情報」→「実行」で起動できます
■ 基本的な使い方
停止したい場合は「停止」をクリックしてください。

■ 翻訳方向の切り替え
画面上部の「翻訳方向」プルダウンから選択できます。
・English → Japanese(英語 → 日本語)
・Japanese → English(日本語 → 英語)
※ 翻訳方向に応じてOCR言語も自動で切り替わります
■ OCRモードについて
用途に応じてOCR方式を切り替えできます。
・Tesseract (psm6)
標準的なOCR。安定重視。
・Tesseract (psm7)
1行字幕向け。ゲーム字幕に向いています。
・Tesseract(ドット文字向け)
ドットフォントや荒い文字向け。
・EasyOCR(高精度)
デザインフォントやドット文字に強い。
初回起動時は少し時間がかかります。
※ 認識精度は画面やフォントによって異なります。
まず EasyOCR を試すのがおすすめです。
■ 翻訳オーバーレイの操作
翻訳結果が表示されるウィンドウは以下の操作が可能です。
・ドラッグ:ウィンドウを自由に移動
・「_」ボタン:折りたたみ(本文を一時的に非表示)
・「×」ボタン:オーバーレイを非表示
非表示にした場合は、
メインウィンドウの「翻訳ウィンドウを表示」で再表示できます。

■ デバッグ機能
「デバッグ」にチェックを入れると、
以下の情報が debug フォルダに保存されます。
・OCR対象のキャプチャ画像
・動作ログ(debug_log.txt)
OCR精度の確認やトラブルシュートに使用できます。
■ 注意事項
・本ツールはオンライン翻訳を使用します
・翻訳結果の正確性は保証されません
・ゲームやアプリの利用規約に注意してください
・本ツールの使用による不具合・損害について
作者は責任を負いません
■ クレジット
・Tesseract OCR
・EasyOCR
・PySide6 (Qt)
・deep-translator
本ツールは個人制作の実験的ツールです。
■ 作者・配布元
IT Libero
https://it-libero.com/
License: MIT




