Add --screenshot flag for interactive screen region selection
This commit is contained in:
parent
7e9a014f4c
commit
14bd455bde
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,8 +1,10 @@
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
build
|
||||
cmake-build-*
|
||||
|
||||
DESIGN.md
|
||||
|
||||
deps
|
||||
model
|
||||
build
|
||||
64
main.cpp
64
main.cpp
@ -14,6 +14,7 @@
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
static volatile bool g_interrupted = false;
|
||||
|
||||
@ -96,6 +97,46 @@ static std::vector<unsigned char> read_clipboard() {
|
||||
return data;
|
||||
}
|
||||
|
||||
static std::string capture_screenshot() {
|
||||
const char * tmpdir = getenv("TMPDIR");
|
||||
if (!tmpdir) tmpdir = "/tmp";
|
||||
std::string path = std::string(tmpdir) + "/ocr_screenshot.png";
|
||||
|
||||
fprintf(stderr, "Select a screen region to OCR...\n");
|
||||
|
||||
auto check = [&]() -> bool {
|
||||
struct stat st;
|
||||
return stat(path.c_str(), &st) == 0 && st.st_size > 0;
|
||||
};
|
||||
|
||||
// 1. gnome-screenshot (blocks until selection complete)
|
||||
unlink(path.c_str());
|
||||
if (system(("gnome-screenshot --area -f " + path + " >/dev/null 2>&1").c_str()) == 0 && check())
|
||||
return path;
|
||||
|
||||
// 2. spectacle (KDE, blocks)
|
||||
unlink(path.c_str());
|
||||
if (system(("spectacle --region -b -o " + path + " >/dev/null 2>&1").c_str()) == 0 && check())
|
||||
return path;
|
||||
|
||||
// 3. flameshot (writes raw PNG to stdout, blocks)
|
||||
unlink(path.c_str());
|
||||
if (system(("flameshot gui -r > " + path + " 2>/dev/null").c_str()) == 0 && check())
|
||||
return path;
|
||||
|
||||
// 4. maim (lightweight X11, blocks)
|
||||
unlink(path.c_str());
|
||||
if (system(("maim -s " + path + " 2>/dev/null").c_str()) == 0 && check())
|
||||
return path;
|
||||
|
||||
// 5. slurp + grim (Sway/Wayland, blocks)
|
||||
unlink(path.c_str());
|
||||
if (system(("slurp | grim -g - " + path + " 2>/dev/null").c_str()) == 0 && check())
|
||||
return path;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
static void print_usage(const char * prog) {
|
||||
fprintf(stderr,
|
||||
"Usage: %s -m <model> --mmproj <mmproj> [options] [<image_path>]\n"
|
||||
@ -111,6 +152,7 @@ static void print_usage(const char * prog) {
|
||||
" -s <seed> random seed\n"
|
||||
" --json output in JSON format\n"
|
||||
" --chat-template <name> chat template (default: auto from model)\n"
|
||||
" --screenshot interactively select screen region to OCR\n"
|
||||
" -h show this help\n"
|
||||
"\n"
|
||||
"If <image_path> is omitted, reads image from clipboard.\n"
|
||||
@ -118,8 +160,9 @@ static void print_usage(const char * prog) {
|
||||
"\n"
|
||||
"Examples:\n"
|
||||
" %s -m model.gguf --mmproj mmproj.gguf -p \"OCR\" image.png\n"
|
||||
" %s -m model.gguf --mmproj mmproj.gguf # use clipboard image\n",
|
||||
prog, prog, prog);
|
||||
" %s -m model.gguf --mmproj mmproj.gguf # use clipboard image\n"
|
||||
" %s -m model.gguf --mmproj mmproj.gguf --screenshot # select region\n",
|
||||
prog, prog, prog, prog);
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
@ -128,6 +171,7 @@ int main(int argc, char ** argv) {
|
||||
std::string image_path;
|
||||
std::string prompt = "OCR";
|
||||
std::string chat_template;
|
||||
bool screenshot_mode = false;
|
||||
int n_threads = (int)std::thread::hardware_concurrency();
|
||||
int n_gpu_layers = -1;
|
||||
int n_ctx = 8192;
|
||||
@ -151,6 +195,7 @@ int main(int argc, char ** argv) {
|
||||
{"ngl", required_argument, nullptr, 3},
|
||||
{"model", required_argument, nullptr, 'm'},
|
||||
{"chat-template", required_argument, nullptr, 4},
|
||||
{"screenshot", no_argument, nullptr, 5},
|
||||
{"help", no_argument, nullptr, 'h'},
|
||||
{nullptr, 0, nullptr, 0}
|
||||
};
|
||||
@ -162,7 +207,8 @@ int main(int argc, char ** argv) {
|
||||
case 1: json_output = true; break;
|
||||
case 2: mmproj_path = optarg; break;
|
||||
case 3: n_gpu_layers = std::stoi(optarg); break;
|
||||
case 4: chat_template = optarg; break;
|
||||
case 4: chat_template = optarg; break;
|
||||
case 5: screenshot_mode = true; break;
|
||||
case 'm': model_path = optarg; break;
|
||||
case 'p': prompt = optarg; break;
|
||||
case 't': n_threads = std::stoi(optarg); break;
|
||||
@ -178,7 +224,13 @@ int main(int argc, char ** argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
if (screenshot_mode) {
|
||||
image_path = capture_screenshot();
|
||||
if (image_path.empty()) {
|
||||
fprintf(stderr, "ERROR: no screenshot tool found. Install gnome-screenshot, flameshot, spectacle, maim, or slurp+grim.\n");
|
||||
return 1;
|
||||
}
|
||||
} else if (optind < argc) {
|
||||
image_path = argv[optind];
|
||||
}
|
||||
|
||||
@ -232,6 +284,7 @@ int main(int argc, char ** argv) {
|
||||
bmp = mtmd_helper_bitmap_init_from_file(ctx_vision, image_path.c_str());
|
||||
if (!bmp) {
|
||||
fprintf(stderr, "ERROR: failed to load image from %s\n", image_path.c_str());
|
||||
if (screenshot_mode) unlink(image_path.c_str());
|
||||
mtmd_free(ctx_vision);
|
||||
llama_free(lctx);
|
||||
llama_model_free(model);
|
||||
@ -296,6 +349,7 @@ int main(int argc, char ** argv) {
|
||||
fprintf(stderr, "ERROR: mtmd_tokenize failed (%d)\n", res);
|
||||
mtmd_input_chunks_free(chunks);
|
||||
mtmd_bitmap_free(bmp);
|
||||
if (screenshot_mode) unlink(image_path.c_str());
|
||||
mtmd_free(ctx_vision);
|
||||
llama_free(lctx);
|
||||
llama_model_free(model);
|
||||
@ -308,6 +362,7 @@ int main(int argc, char ** argv) {
|
||||
fprintf(stderr, "ERROR: mtmd_helper_eval_chunks failed (%d)\n", res);
|
||||
mtmd_input_chunks_free(chunks);
|
||||
mtmd_bitmap_free(bmp);
|
||||
if (screenshot_mode) unlink(image_path.c_str());
|
||||
mtmd_free(ctx_vision);
|
||||
llama_free(lctx);
|
||||
llama_model_free(model);
|
||||
@ -316,6 +371,7 @@ int main(int argc, char ** argv) {
|
||||
|
||||
mtmd_input_chunks_free(chunks);
|
||||
mtmd_bitmap_free(bmp);
|
||||
if (screenshot_mode) unlink(image_path.c_str());
|
||||
|
||||
struct llama_sampler * smpl = nullptr;
|
||||
if (temp <= 0.0f) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user