Minor style changes
This commit is contained in:
70
owocr/ocr.py
70
owocr/ocr.py
@@ -72,9 +72,9 @@ def post_process(text):
|
|||||||
|
|
||||||
|
|
||||||
class MangaOcr:
|
class MangaOcr:
|
||||||
name = "mangaocr"
|
name = 'mangaocr'
|
||||||
readable_name = "Manga OCR"
|
readable_name = 'Manga OCR'
|
||||||
key = "m"
|
key = 'm'
|
||||||
available = False
|
available = False
|
||||||
|
|
||||||
def __init__(self, config={'pretrained_model_name_or_path':'kha-white/manga-ocr-base','force_cpu':'False'}, pretrained_model_name_or_path='', force_cpu=False):
|
def __init__(self, config={'pretrained_model_name_or_path':'kha-white/manga-ocr-base','force_cpu':'False'}, pretrained_model_name_or_path='', force_cpu=False):
|
||||||
@@ -86,7 +86,7 @@ class MangaOcr:
|
|||||||
if config['force_cpu'] == 'True':
|
if config['force_cpu'] == 'True':
|
||||||
force_cpu = True
|
force_cpu = True
|
||||||
|
|
||||||
logger.disable("manga_ocr")
|
logger.disable('manga_ocr')
|
||||||
logger.info(f'Loading Manga OCR model')
|
logger.info(f'Loading Manga OCR model')
|
||||||
self.model = MOCR(pretrained_model_name_or_path, force_cpu)
|
self.model = MOCR(pretrained_model_name_or_path, force_cpu)
|
||||||
self.available = True
|
self.available = True
|
||||||
@@ -104,9 +104,9 @@ class MangaOcr:
|
|||||||
return x
|
return x
|
||||||
|
|
||||||
class GoogleVision:
|
class GoogleVision:
|
||||||
name = "gvision"
|
name = 'gvision'
|
||||||
readable_name = "Google Vision"
|
readable_name = 'Google Vision'
|
||||||
key = "g"
|
key = 'g'
|
||||||
available = False
|
available = False
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -144,9 +144,9 @@ class GoogleVision:
|
|||||||
return image_bytes.getvalue()
|
return image_bytes.getvalue()
|
||||||
|
|
||||||
class GoogleLens:
|
class GoogleLens:
|
||||||
name = "glens"
|
name = 'glens'
|
||||||
readable_name = "Google Lens"
|
readable_name = 'Google Lens'
|
||||||
key = "l"
|
key = 'l'
|
||||||
available = False
|
available = False
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -167,12 +167,12 @@ class GoogleLens:
|
|||||||
raise ValueError(f'img_or_path must be a path or PIL.Image, instead got: {img_or_path}')
|
raise ValueError(f'img_or_path must be a path or PIL.Image, instead got: {img_or_path}')
|
||||||
|
|
||||||
timestamp = int(time.time() * 1000)
|
timestamp = int(time.time() * 1000)
|
||||||
url = f"https://lens.google.com/v3/upload?stcs={timestamp}"
|
url = f'https://lens.google.com/v3/upload?stcs={timestamp}'
|
||||||
files = {"encoded_image": ('owo' + str(timestamp) + '.png', self._preprocess(img), 'image/png')}
|
files = {'encoded_image': ('owo' + str(timestamp) + '.png', self._preprocess(img), 'image/png')}
|
||||||
try:
|
try:
|
||||||
res = requests.post(url, files=files, timeout=(3, 10))
|
res = requests.post(url, files=files, timeout=(3, 10))
|
||||||
except requests.exceptions.Timeout:
|
except requests.exceptions.Timeout:
|
||||||
return "Request timeout!"
|
return 'Request timeout!'
|
||||||
|
|
||||||
x = ''
|
x = ''
|
||||||
if res.status_code == 200:
|
if res.status_code == 200:
|
||||||
@@ -192,17 +192,17 @@ class GoogleLens:
|
|||||||
|
|
||||||
def _preprocess(self, img):
|
def _preprocess(self, img):
|
||||||
image_bytes = io.BytesIO()
|
image_bytes = io.BytesIO()
|
||||||
img.save(image_bytes, format="png")
|
img.save(image_bytes, format='png')
|
||||||
return image_bytes.getvalue()
|
return image_bytes.getvalue()
|
||||||
|
|
||||||
class AppleVision:
|
class AppleVision:
|
||||||
name = "avision"
|
name = 'avision'
|
||||||
readable_name = "Apple Vision"
|
readable_name = 'Apple Vision'
|
||||||
key = "a"
|
key = 'a'
|
||||||
available = False
|
available = False
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
if sys.platform != "darwin":
|
if sys.platform != 'darwin':
|
||||||
logger.warning('Apple Vision is not supported on non-macOS platforms!')
|
logger.warning('Apple Vision is not supported on non-macOS platforms!')
|
||||||
elif int(platform.mac_ver()[0].split('.')[0]) < 13:
|
elif int(platform.mac_ver()[0].split('.')[0]) < 13:
|
||||||
logger.warning('Apple Vision is not supported on macOS older than Ventura/13.0!')
|
logger.warning('Apple Vision is not supported on macOS older than Ventura/13.0!')
|
||||||
@@ -249,13 +249,13 @@ class AppleVision:
|
|||||||
return image_bytes.getvalue()
|
return image_bytes.getvalue()
|
||||||
|
|
||||||
class WinRTOCR:
|
class WinRTOCR:
|
||||||
name = "winrtocr"
|
name = 'winrtocr'
|
||||||
readable_name = "WinRT OCR"
|
readable_name = 'WinRT OCR'
|
||||||
key = "w"
|
key = 'w'
|
||||||
available = False
|
available = False
|
||||||
|
|
||||||
def __init__(self, config={}):
|
def __init__(self, config={}):
|
||||||
if sys.platform == "win32":
|
if sys.platform == 'win32':
|
||||||
if int(platform.release()) < 10:
|
if int(platform.release()) < 10:
|
||||||
logger.warning('WinRT OCR is not supported on Windows older than 10!')
|
logger.warning('WinRT OCR is not supported on Windows older than 10!')
|
||||||
elif 'winocr' not in sys.modules:
|
elif 'winocr' not in sys.modules:
|
||||||
@@ -282,14 +282,14 @@ class WinRTOCR:
|
|||||||
else:
|
else:
|
||||||
raise ValueError(f'img_or_path must be a path or PIL.Image, instead got: {img_or_path}')
|
raise ValueError(f'img_or_path must be a path or PIL.Image, instead got: {img_or_path}')
|
||||||
|
|
||||||
if sys.platform == "win32":
|
if sys.platform == 'win32':
|
||||||
res = winocr.recognize_pil_sync(img, lang='ja')['text']
|
res = winocr.recognize_pil_sync(img, lang='ja')['text']
|
||||||
else:
|
else:
|
||||||
params = {'lang': 'ja'}
|
params = {'lang': 'ja'}
|
||||||
try:
|
try:
|
||||||
res = requests.post(self.url, params=params, data=self._preprocess(img), timeout=3)
|
res = requests.post(self.url, params=params, data=self._preprocess(img), timeout=3)
|
||||||
except requests.exceptions.Timeout:
|
except requests.exceptions.Timeout:
|
||||||
return "Request timeout!"
|
return 'Request timeout!'
|
||||||
|
|
||||||
res = json.loads(res.text)['text']
|
res = json.loads(res.text)['text']
|
||||||
|
|
||||||
@@ -302,9 +302,9 @@ class WinRTOCR:
|
|||||||
return image_bytes.getvalue()
|
return image_bytes.getvalue()
|
||||||
|
|
||||||
class AzureComputerVision:
|
class AzureComputerVision:
|
||||||
name = "azure"
|
name = 'azure'
|
||||||
readable_name = "Azure Computer Vision"
|
readable_name = 'Azure Computer Vision'
|
||||||
key = "v"
|
key = 'v'
|
||||||
available = False
|
available = False
|
||||||
|
|
||||||
def __init__(self, config={}):
|
def __init__(self, config={}):
|
||||||
@@ -330,8 +330,8 @@ class AzureComputerVision:
|
|||||||
image_io = self._preprocess(img)
|
image_io = self._preprocess(img)
|
||||||
read_response = self.client.read_in_stream(image_io, raw=True)
|
read_response = self.client.read_in_stream(image_io, raw=True)
|
||||||
|
|
||||||
read_operation_location = read_response.headers["Operation-Location"]
|
read_operation_location = read_response.headers['Operation-Location']
|
||||||
operation_id = read_operation_location.split("/")[-1]
|
operation_id = read_operation_location.split('/')[-1]
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
read_result = self.client.get_read_result(operation_id)
|
read_result = self.client.get_read_result(operation_id)
|
||||||
@@ -355,9 +355,9 @@ class AzureComputerVision:
|
|||||||
return image_io
|
return image_io
|
||||||
|
|
||||||
class EasyOCR:
|
class EasyOCR:
|
||||||
name = "easyocr"
|
name = 'easyocr'
|
||||||
readable_name = "EasyOCR"
|
readable_name = 'EasyOCR'
|
||||||
key = "e"
|
key = 'e'
|
||||||
available = False
|
available = False
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -391,9 +391,9 @@ class EasyOCR:
|
|||||||
return image_bytes.getvalue()
|
return image_bytes.getvalue()
|
||||||
|
|
||||||
class PaddleOCR:
|
class PaddleOCR:
|
||||||
name = "paddleocr"
|
name = 'paddleocr'
|
||||||
readable_name = "PaddleOCR"
|
readable_name = 'PaddleOCR'
|
||||||
key = "o"
|
key = 'o'
|
||||||
available = False
|
available = False
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|||||||
32
owocr/run.py
32
owocr/run.py
@@ -45,7 +45,7 @@ class WindowsClipboardThread(threading.Thread):
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
def create_window(self):
|
def create_window(self):
|
||||||
className = "ClipboardHook"
|
className = 'ClipboardHook'
|
||||||
wc = win32gui.WNDCLASS()
|
wc = win32gui.WNDCLASS()
|
||||||
wc.lpfnWndProc = self.process_message
|
wc.lpfnWndProc = self.process_message
|
||||||
wc.lpszClassName = className
|
wc.lpszClassName = className
|
||||||
@@ -80,12 +80,12 @@ class WebsocketServerThread(threading.Thread):
|
|||||||
if self.read and not (paused or tmp_paused):
|
if self.read and not (paused or tmp_paused):
|
||||||
websocket_queue.put(message)
|
websocket_queue.put(message)
|
||||||
try:
|
try:
|
||||||
await websocket.send("True")
|
await websocket.send('True')
|
||||||
except websockets.exceptions.ConnectionClosedOK:
|
except websockets.exceptions.ConnectionClosedOK:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
await websocket.send("False")
|
await websocket.send('False')
|
||||||
except websockets.exceptions.ConnectionClosedOK:
|
except websockets.exceptions.ConnectionClosedOK:
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
@@ -112,7 +112,7 @@ class WebsocketServerThread(threading.Thread):
|
|||||||
|
|
||||||
def getchar_thread():
|
def getchar_thread():
|
||||||
global user_input
|
global user_input
|
||||||
if sys.platform == "win32":
|
if sys.platform == 'win32':
|
||||||
import msvcrt
|
import msvcrt
|
||||||
while True:
|
while True:
|
||||||
user_input = msvcrt.getch()
|
user_input = msvcrt.getch()
|
||||||
@@ -169,7 +169,7 @@ def process_and_write_results(engine_instance, engine_color, img_or_path, write_
|
|||||||
text = engine_instance(img_or_path)
|
text = engine_instance(img_or_path)
|
||||||
t1 = time.time()
|
t1 = time.time()
|
||||||
|
|
||||||
logger.opt(ansi=True).info(f"Text recognized in {t1 - t0:0.03f}s using <{engine_color}>{engine_instance.readable_name}</{engine_color}>: {text}")
|
logger.opt(ansi=True).info(f'Text recognized in {t1 - t0:0.03f}s using <{engine_color}>{engine_instance.readable_name}</{engine_color}>: {text}')
|
||||||
if notifications == True:
|
if notifications == True:
|
||||||
notification = Notify()
|
notification = Notify()
|
||||||
notification.application_name = 'owocr'
|
notification.application_name = 'owocr'
|
||||||
@@ -186,7 +186,7 @@ def process_and_write_results(engine_instance, engine_color, img_or_path, write_
|
|||||||
if write_to.suffix != '.txt':
|
if write_to.suffix != '.txt':
|
||||||
raise ValueError('write_to must be either "clipboard" or a path to a text file')
|
raise ValueError('write_to must be either "clipboard" or a path to a text file')
|
||||||
|
|
||||||
with write_to.open('a', encoding="utf-8") as f:
|
with write_to.open('a', encoding='utf-8') as f:
|
||||||
f.write(text + '\n')
|
f.write(text + '\n')
|
||||||
|
|
||||||
|
|
||||||
@@ -220,8 +220,8 @@ def run(read_from='clipboard',
|
|||||||
# Check if the system is using Wayland
|
# Check if the system is using Wayland
|
||||||
if os.environ.get('WAYLAND_DISPLAY'):
|
if os.environ.get('WAYLAND_DISPLAY'):
|
||||||
# Check if the wl-clipboard package is installed
|
# Check if the wl-clipboard package is installed
|
||||||
if os.system("which wl-copy > /dev/null") == 0:
|
if os.system('which wl-copy > /dev/null') == 0:
|
||||||
pyperclip.set_clipboard("wl-clipboard")
|
pyperclip.set_clipboard('wl-clipboard')
|
||||||
else:
|
else:
|
||||||
msg = 'Your session uses wayland and does not have wl-clipboard installed. ' \
|
msg = 'Your session uses wayland and does not have wl-clipboard installed. ' \
|
||||||
'Install wl-clipboard for write in clipboard to work.'
|
'Install wl-clipboard for write in clipboard to work.'
|
||||||
@@ -274,14 +274,14 @@ def run(read_from='clipboard',
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
logger.configure(handlers=[{"sink": sys.stderr, "format": logger_format}])
|
logger.configure(handlers=[{'sink': sys.stderr, 'format': logger_format}])
|
||||||
|
|
||||||
if len(res) != 0:
|
if len(res) != 0:
|
||||||
logger.info('Parsed config file')
|
logger.info('Parsed config file')
|
||||||
else:
|
else:
|
||||||
logger.warning('No config file, defaults will be used')
|
logger.warning('No config file, defaults will be used')
|
||||||
|
|
||||||
for _,engine_class in sorted(inspect.getmembers(sys.modules[__name__], lambda x: hasattr(x, '__module__') and __package__ + ".ocr" in x.__module__ and inspect.isclass(x))):
|
for _,engine_class in sorted(inspect.getmembers(sys.modules[__name__], lambda x: hasattr(x, '__module__') and __package__ + '.ocr' in x.__module__ and inspect.isclass(x))):
|
||||||
if len(config_engines) == 0 or engine_class.name in config_engines:
|
if len(config_engines) == 0 or engine_class.name in config_engines:
|
||||||
try:
|
try:
|
||||||
engine_instance = engine_class(config[engine_class.name])
|
engine_instance = engine_class(config[engine_class.name])
|
||||||
@@ -348,7 +348,7 @@ def run(read_from='clipboard',
|
|||||||
windows_clipboard_thread.start()
|
windows_clipboard_thread.start()
|
||||||
windows_clipboard_polling = True
|
windows_clipboard_polling = True
|
||||||
else:
|
else:
|
||||||
allowed_extensions = (".png", ".jpg", ".jpeg", ".bmp", ".gif", ".webp")
|
allowed_extensions = ('.png', '.jpg', '.jpeg', '.bmp', '.gif', '.webp')
|
||||||
read_from = Path(read_from)
|
read_from = Path(read_from)
|
||||||
if not read_from.is_dir():
|
if not read_from.is_dir():
|
||||||
raise ValueError('read_from must be either "clipboard" or a path to a directory')
|
raise ValueError('read_from must be either "clipboard" or a path to a directory')
|
||||||
@@ -393,7 +393,7 @@ def run(read_from='clipboard',
|
|||||||
|
|
||||||
if engine_index != new_engine_index:
|
if engine_index != new_engine_index:
|
||||||
engine_index = new_engine_index
|
engine_index = new_engine_index
|
||||||
logger.opt(ansi=True).info(f"Switched to <{engine_color}>{engine_instances[engine_index].readable_name}</{engine_color}>!")
|
logger.opt(ansi=True).info(f'Switched to <{engine_color}>{engine_instances[engine_index].readable_name}</{engine_color}>!')
|
||||||
|
|
||||||
user_input = ''
|
user_input = ''
|
||||||
|
|
||||||
@@ -408,11 +408,13 @@ def run(read_from='clipboard',
|
|||||||
img = Image.open(io.BytesIO(item))
|
img = Image.open(io.BytesIO(item))
|
||||||
process_and_write_results(engine_instances[engine_index], engine_color, img, write_to, notifications)
|
process_and_write_results(engine_instances[engine_index], engine_color, img, write_to, notifications)
|
||||||
elif read_from == 'clipboard':
|
elif read_from == 'clipboard':
|
||||||
|
changed = False
|
||||||
if windows_clipboard_polling:
|
if windows_clipboard_polling:
|
||||||
changed = clipboard_event.wait(delay_secs)
|
changed = clipboard_event.wait(delay_secs)
|
||||||
if changed:
|
if changed:
|
||||||
clipboard_event.clear()
|
clipboard_event.clear()
|
||||||
elif mac_clipboard_polling and not (paused or tmp_paused):
|
elif mac_clipboard_polling:
|
||||||
|
if not (paused or tmp_paused):
|
||||||
old_count = count
|
old_count = count
|
||||||
count = pasteboard.changeCount()
|
count = pasteboard.changeCount()
|
||||||
changed = not just_unpaused and count != old_count and any(x in pasteboard.types() for x in [NSPasteboardTypePNG, NSPasteboardTypeTIFF])
|
changed = not just_unpaused and count != old_count and any(x in pasteboard.types() for x in [NSPasteboardTypePNG, NSPasteboardTypeTIFF])
|
||||||
@@ -425,10 +427,10 @@ def run(read_from='clipboard',
|
|||||||
try:
|
try:
|
||||||
img = ImageGrab.grabclipboard()
|
img = ImageGrab.grabclipboard()
|
||||||
except OSError as error:
|
except OSError as error:
|
||||||
if not verbose and "cannot identify image file" in str(error):
|
if not verbose and 'cannot identify image file' in str(error):
|
||||||
# Pillow error when clipboard hasn't changed since last grab (Linux)
|
# Pillow error when clipboard hasn't changed since last grab (Linux)
|
||||||
pass
|
pass
|
||||||
elif not verbose and "target image/png not available" in str(error):
|
elif not verbose and 'target image/png not available' in str(error):
|
||||||
# Pillow error when clipboard contains text (Linux, X11)
|
# Pillow error when clipboard contains text (Linux, X11)
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user