screen-toolkit : full screen utility (#221)
* screen-toolkit: add Noctalia v5 plugin * screen-toolkit: credit original plugin * screen-toolkit: fix recording, OCR capture, and result panel UX * screen-toolkit: rename record tool labels to Record / Rec FS * screen-toolkit: update plugin thumbnail * screen-toolkit: fix README validation (backtick deps, result panel toggle) * screen-toolkit: fix OCR results and dependencies * screen-toolkit: backtick recording and annotator deps in README --------- Co-authored-by: Ahmed5Emad <ahmed5emad@users.noreply.github.com>
This commit is contained in:
Executable
+99
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env bash
|
||||
# Args: $1=gx $2=gy $3=gw $4=gh $5=lang $6=upscale_flag $7=psm $8=output_path
|
||||
#
|
||||
# Exit codes:
|
||||
# 1 — missing dependency (dep name written to stdout)
|
||||
# 2 — bad/missing args
|
||||
# 3 — capture failed
|
||||
# 4 — image processing failed
|
||||
# Exit 0 with empty stdout = no text found (service handles this case)
|
||||
|
||||
GX="$1"; GY="$2"; GW="$3"; GH="$4"
|
||||
RAW_LANG="${5:-eng}"
|
||||
UPSCALE="$6"
|
||||
USER_PSM="${7:-3}"
|
||||
FILE="${8:-/tmp/screen-toolkit-ocr.png}"
|
||||
TMP_BASE="/tmp/screen-toolkit-ocr-work-$$"
|
||||
TMP="${TMP_BASE}.pnm"
|
||||
TMP_NOISE="${TMP_BASE}-nr.pnm"
|
||||
GRIM_CURSOR_ARGS=()
|
||||
[ "${SCREEN_TOOLKIT_CAPTURE_CURSOR:-0}" = "1" ] && GRIM_CURSOR_ARGS+=(-c)
|
||||
|
||||
cleanup() { rm -f "$TMP" "$TMP_NOISE"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
for dep in grim magick tesseract; do
|
||||
command -v "$dep" >/dev/null 2>&1 || { echo "$dep"; exit 1; }
|
||||
done
|
||||
|
||||
[ -z "$GX" ] || [ -z "$GY" ] || [ -z "$GW" ] || [ -z "$GH" ] && exit 2
|
||||
|
||||
LANG=$(echo "$RAW_LANG" | tr '+' '\n' \
|
||||
| grep -v '^osd$' \
|
||||
| grep -v '^$' \
|
||||
| tr '\n' '+' \
|
||||
| sed 's/+$//')
|
||||
[ -z "$LANG" ] && LANG="eng"
|
||||
|
||||
AVAILABLE=$(tesseract --list-langs 2>/dev/null | tail -n +2)
|
||||
VALID_LANGS=""
|
||||
IFS='+' read -ra LANG_PARTS <<< "$LANG"
|
||||
for l in "${LANG_PARTS[@]}"; do
|
||||
if echo "$AVAILABLE" | grep -qx "$l"; then
|
||||
VALID_LANGS="${VALID_LANGS}+${l}"
|
||||
fi
|
||||
done
|
||||
LANG="${VALID_LANGS#+}"
|
||||
[ -z "$LANG" ] && LANG="eng"
|
||||
|
||||
sleep 0.15
|
||||
|
||||
# Capture the requested region. Without this the script would keep re-reading
|
||||
# whatever stale image happens to be left at $FILE (stale OCR results).
|
||||
grim "${GRIM_CURSOR_ARGS[@]}" -g "${GX},${GY} ${GW}x${GH}" "$FILE" 2>/dev/null \
|
||||
|| { echo "ERROR: grim capture failed" >&2; exit 3; }
|
||||
|
||||
if [ -z "$UPSCALE" ] && [ "$GW" -lt 200 ] 2>/dev/null; then
|
||||
SCALE=$(awk "BEGIN{printf \"%.0f\", 300 / $GW}")
|
||||
UPSCALE="-scale ${SCALE}00%"
|
||||
fi
|
||||
|
||||
magick "$FILE" $UPSCALE \
|
||||
-colorspace Gray \
|
||||
-normalize \
|
||||
-contrast-stretch 2%x1% \
|
||||
-sharpen 0x1.5 \
|
||||
+repage \
|
||||
"$TMP" 2>/dev/null || exit 4
|
||||
|
||||
MEAN=$(magick "$TMP" -format '%[fx:mean]' info: 2>/dev/null)
|
||||
if awk "BEGIN{exit !($MEAN < 0.4)}"; then
|
||||
magick "$TMP" -negate "$TMP" 2>/dev/null
|
||||
fi
|
||||
magick "$TMP" -median 1 "$TMP_NOISE" 2>/dev/null
|
||||
|
||||
run_ocr() { tesseract "$1" stdout -l "$LANG" --psm "$2" --oem 1 2>/dev/null; }
|
||||
count_chars() { printf '%s' "$1" | tr -d '[:space:]' | wc -c; }
|
||||
|
||||
TEXT=$(run_ocr "$TMP" "$USER_PSM")
|
||||
BEST_LEN=$(count_chars "$TEXT")
|
||||
BEST_TEXT="$TEXT"
|
||||
|
||||
if [ "$BEST_LEN" -lt 4 ] || [ "$USER_PSM" -ne 6 ]; then
|
||||
TEXT2=$(run_ocr "$TMP_NOISE" 6)
|
||||
LEN2=$(count_chars "$TEXT2")
|
||||
[ "$LEN2" -gt "$BEST_LEN" ] && { BEST_LEN=$LEN2; BEST_TEXT="$TEXT2"; }
|
||||
fi
|
||||
if [ "$BEST_LEN" -lt 4 ]; then
|
||||
TEXT3=$(run_ocr "$TMP_NOISE" 4)
|
||||
LEN3=$(count_chars "$TEXT3")
|
||||
[ "$LEN3" -gt "$BEST_LEN" ] && { BEST_LEN=$LEN3; BEST_TEXT="$TEXT3"; }
|
||||
fi
|
||||
if [ "$BEST_LEN" -lt 4 ]; then
|
||||
TEXT4=$(magick "$TMP" -threshold 85% stdout 2>/dev/null \
|
||||
| tesseract - stdout -l "$LANG" --psm 11 --oem 1 2>/dev/null)
|
||||
LEN4=$(count_chars "$TEXT4")
|
||||
[ "$LEN4" -gt "$BEST_LEN" ] && BEST_TEXT="$TEXT4"
|
||||
fi
|
||||
|
||||
printf '%s' "$BEST_TEXT"
|
||||
Reference in New Issue
Block a user