GameSentenceMiner 2.8.17__py3-none-any.whl → 2.8.18__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- GameSentenceMiner/owocr/owocr/__main__.py +1 -1
- GameSentenceMiner/owocr/owocr/ocr.py +76 -0
- GameSentenceMiner/owocr/owocr/run.py +2 -1
- {gamesentenceminer-2.8.17.dist-info → gamesentenceminer-2.8.18.dist-info}/METADATA +1 -1
- {gamesentenceminer-2.8.17.dist-info → gamesentenceminer-2.8.18.dist-info}/RECORD +9 -9
- {gamesentenceminer-2.8.17.dist-info → gamesentenceminer-2.8.18.dist-info}/WHEEL +0 -0
- {gamesentenceminer-2.8.17.dist-info → gamesentenceminer-2.8.18.dist-info}/entry_points.txt +0 -0
- {gamesentenceminer-2.8.17.dist-info → gamesentenceminer-2.8.18.dist-info}/licenses/LICENSE +0 -0
- {gamesentenceminer-2.8.17.dist-info → gamesentenceminer-2.8.18.dist-info}/top_level.txt +0 -0
@@ -1048,3 +1048,79 @@ class GeminiOCR:
|
|
1048
1048
|
|
1049
1049
|
def _preprocess(self, img):
|
1050
1050
|
return pil_image_to_bytes(img, png_compression=1)
|
1051
|
+
|
1052
|
+
|
1053
|
+
class GroqOCR:
|
1054
|
+
name = 'groq'
|
1055
|
+
readable_name = 'Groq OCR'
|
1056
|
+
key = 'j'
|
1057
|
+
available = False
|
1058
|
+
|
1059
|
+
def __init__(self, config={'api_key': None}):
|
1060
|
+
try:
|
1061
|
+
import groq
|
1062
|
+
self.api_key = config['api_key']
|
1063
|
+
if not self.api_key:
|
1064
|
+
logger.warning('Groq API key not provided, GroqOCR will not work!')
|
1065
|
+
else:
|
1066
|
+
self.client = groq.Groq(api_key=self.api_key)
|
1067
|
+
self.available = True
|
1068
|
+
logger.info('Groq OCR ready')
|
1069
|
+
except ImportError:
|
1070
|
+
logger.warning('groq module not available, GroqOCR will not work!')
|
1071
|
+
except Exception as e:
|
1072
|
+
logger.error(f'Error initializing Groq client: {e}')
|
1073
|
+
|
1074
|
+
def __call__(self, img_or_path):
|
1075
|
+
if not self.available:
|
1076
|
+
return (False, 'GroqOCR is not available due to missing API key or configuration error.')
|
1077
|
+
|
1078
|
+
try:
|
1079
|
+
if isinstance(img_or_path, str) or isinstance(img_or_path, Path):
|
1080
|
+
img = Image.open(img_or_path).convert("RGB")
|
1081
|
+
elif isinstance(img_or_path, Image.Image):
|
1082
|
+
img = img_or_path.convert("RGB")
|
1083
|
+
else:
|
1084
|
+
raise ValueError(f'img_or_path must be a path or PIL.Image, instead got: {img_or_path}')
|
1085
|
+
|
1086
|
+
img_base64 = self._preprocess(img)
|
1087
|
+
if not img_base64:
|
1088
|
+
return (False, 'Error processing image for Groq.')
|
1089
|
+
|
1090
|
+
prompt = (
|
1091
|
+
"Analyze this image and extract text from it"
|
1092
|
+
# "(speech bubbles or panels containing character dialogue). From the extracted dialogue text, "
|
1093
|
+
# "filter out any furigana. Ignore and do not include any text found outside of dialogue boxes, "
|
1094
|
+
# "including character names, speaker labels, or sound effects. Return *only* the filtered dialogue text. "
|
1095
|
+
# "If no text is found within dialogue boxes after applying filters, return an empty string. "
|
1096
|
+
# "OR, if there are no text bubbles or dialogue boxes found, return everything."
|
1097
|
+
"Do not include any other output, formatting markers, or commentary, only the text from the image."
|
1098
|
+
)
|
1099
|
+
|
1100
|
+
response = self.client.chat.completions.create(
|
1101
|
+
model="meta-llama/llama-4-scout-17b-16e-instruct",
|
1102
|
+
messages=[
|
1103
|
+
{
|
1104
|
+
"role": "user",
|
1105
|
+
"content": [
|
1106
|
+
{"type": "text", "text": prompt},
|
1107
|
+
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{img_base64}"}},
|
1108
|
+
],
|
1109
|
+
}
|
1110
|
+
],
|
1111
|
+
max_tokens=300
|
1112
|
+
)
|
1113
|
+
|
1114
|
+
if response.choices and response.choices[0].message.content:
|
1115
|
+
text_output = response.choices[0].message.content.strip()
|
1116
|
+
return (True, text_output)
|
1117
|
+
else:
|
1118
|
+
return (True, "")
|
1119
|
+
|
1120
|
+
except FileNotFoundError:
|
1121
|
+
return (False, f'File not found: {img_or_path}')
|
1122
|
+
except Exception as e:
|
1123
|
+
return (False, f'Groq API request failed: {e}')
|
1124
|
+
|
1125
|
+
def _preprocess(self, img):
|
1126
|
+
return base64.b64encode(pil_image_to_bytes(img, png_compression=1)).decode('utf-8')
|
@@ -585,7 +585,8 @@ def process_and_write_results(img_or_path, write_to, notifications, last_result,
|
|
585
585
|
for i, instance in enumerate(engine_instances):
|
586
586
|
if instance.name.lower() in engine.lower():
|
587
587
|
engine_instance = instance
|
588
|
-
|
588
|
+
if last_result:
|
589
|
+
last_result = (last_result[0], i)
|
589
590
|
break
|
590
591
|
else:
|
591
592
|
engine_instance = engine_instances[engine_index]
|
@@ -27,11 +27,11 @@ GameSentenceMiner/ocr/ocrconfig.py,sha256=_tY8mjnzHMJrLS8E5pHqYXZjMuLoGKYgJwdhYg
|
|
27
27
|
GameSentenceMiner/ocr/owocr_area_selector.py,sha256=QF45kfvG46RbVW6LbheVIw3S3q6LSCSP8nWRH2XRQPo,46927
|
28
28
|
GameSentenceMiner/ocr/owocr_helper.py,sha256=ehQvhq_YjyR8PJYMhvz7M_BuwGAAUujfXgEpBNnAopA,17365
|
29
29
|
GameSentenceMiner/owocr/owocr/__init__.py,sha256=opjBOyGGyEqZCE6YdZPnyt7nVfiwyELHsXA0jAsjm14,25
|
30
|
-
GameSentenceMiner/owocr/owocr/__main__.py,sha256=
|
30
|
+
GameSentenceMiner/owocr/owocr/__main__.py,sha256=XQaqZY99EKoCpU-gWQjNbTs7Kg17HvBVE7JY8LqIE0o,157
|
31
31
|
GameSentenceMiner/owocr/owocr/config.py,sha256=n-xtVylb2Q_H84jb1ZsIGxPQjTNnyvnRny1RhtaLJM8,7550
|
32
32
|
GameSentenceMiner/owocr/owocr/lens_betterproto.py,sha256=oNoISsPilVVRBBPVDtb4-roJtAhp8ZAuFTci3TGXtMc,39141
|
33
|
-
GameSentenceMiner/owocr/owocr/ocr.py,sha256=
|
34
|
-
GameSentenceMiner/owocr/owocr/run.py,sha256=
|
33
|
+
GameSentenceMiner/owocr/owocr/ocr.py,sha256=KDW9twGdgqE2UsmefxEvJmQVjCho_ll256LgoCcO_qQ,43242
|
34
|
+
GameSentenceMiner/owocr/owocr/run.py,sha256=7Jfqt-MSYUbeEDBOFic6BmleL9leDmBzfW-kJAO5OO8,51188
|
35
35
|
GameSentenceMiner/owocr/owocr/screen_coordinate_picker.py,sha256=fjJ3CSXLti3WboGPpmsa7MWOwIXsfpHC8N4zKahGGY0,3346
|
36
36
|
GameSentenceMiner/vad/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
37
37
|
GameSentenceMiner/vad/silero_trim.py,sha256=ULf3zwS-JMsY82cKF7gZxREHw8L6lgpWF2U1YqgE9Oc,1681
|
@@ -51,9 +51,9 @@ GameSentenceMiner/web/static/web-app-manifest-512x512.png,sha256=wyqgCWCrLEUxSRX
|
|
51
51
|
GameSentenceMiner/web/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
52
52
|
GameSentenceMiner/web/templates/text_replacements.html,sha256=tV5c8mCaWSt_vKuUpbdbLAzXZ3ATZeDvQ9PnnAfqY0M,8598
|
53
53
|
GameSentenceMiner/web/templates/utility.html,sha256=NUp4Yjs6_j7YeqsM2rcF0LzwS6nXSBUWJDl-k2E8BbM,16270
|
54
|
-
gamesentenceminer-2.8.
|
55
|
-
gamesentenceminer-2.8.
|
56
|
-
gamesentenceminer-2.8.
|
57
|
-
gamesentenceminer-2.8.
|
58
|
-
gamesentenceminer-2.8.
|
59
|
-
gamesentenceminer-2.8.
|
54
|
+
gamesentenceminer-2.8.18.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
55
|
+
gamesentenceminer-2.8.18.dist-info/METADATA,sha256=gighpeXLuYOSZSnKGjFaYv21v3-hsmolCsCXs6oo0YI,5933
|
56
|
+
gamesentenceminer-2.8.18.dist-info/WHEEL,sha256=7ciDxtlje1X8OhobNuGgi1t-ACdFSelPnSmDPrtlobY,91
|
57
|
+
gamesentenceminer-2.8.18.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
|
58
|
+
gamesentenceminer-2.8.18.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
|
59
|
+
gamesentenceminer-2.8.18.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|