Automation Script Reference
Record a processing pipeline once, then replay it on hundreds of images in one click. Edit scripts to add filters, change parameters, collect OCR results β no limits.
Overview
The automation system works in two stages:
- 1Record. Perform your steps in the capture overlay β area selection, perspective correction, OCR, save. Every action is recorded.
- 2Edit (optional). Open the generated script in the editor. Change the folder path, tweak coordinates, add conditional logic.
- 3Play. The engine iterates over every image in the folder and applies the pipeline. Fast, parallel-friendly, resumable.
Vec<AutomationAction> in memory and serialises them to a human-readable .rhai script file. The overlay Play button reruns from memory (instant). The Script Editor runs from the file (fully editable). Both paths produce identical output.Automation Toolbar
The toolbar appears on the right side of the capture overlay when PRO or Trial is active. It is completely hidden for non-PRO users.
| Button | Action |
|---|---|
| π Set Folder | Opens a folder picker. All scripts, input images and output files are stored here. Persists across sessions. |
| βΊ Record | Toggle. Turns red when active. Stopping recording writes automation_YYYYMMDD_HHMMSS.rhai to the folder. |
| βΈ Pause | Pauses / resumes recording without discarding accumulated actions. |
| βΆ Play | Runs the last recorded pipeline on every image in the folder. |
| β Edit | Opens the Script Editor pre-populated with the last generated script. |
Recording a Script
Every interaction with the overlay during recording is captured as an action:
| User action | Script line generated |
|---|---|
| Confirm area selection | img = crop_area(img, x, y, w, h); |
| Apply perspective | img = apply_perspective(img, [tl_x,tl_y, tr_x,tr_y, br_x,br_y, bl_x,bl_y]); |
| Apply curve / arc dewarp | img = apply_curve(img, top, side); |
| Draw / annotate | img = apply_drawings(img, "/path/overlay.png"); |
| OCR (final action) | text = ocr_and_copy(img); + save_ocr_to_text(text, image_path); + save_to_folder(img, batch_timestamp); |
| Copy to clipboard | copy_to_clipboard(img); |
| Save to folder | save_to_folder(img, batch_timestamp); |
CaptureArea (derived from the current selection) and SaveToFolder so every recording always produces a usable script.Script Editor
Open the editor from: System tray β β Automation Script Editor Β· PRO, or from the overlay toolbar via the β button.
Abrir β open any .rhai file.βSalvar β save current script.βExecutar β run on folder (same as F5).βFechar β close.
Language Syntax
Scripts use a Rhai-compatible syntax. Everything below is supported by the built-in engine.
Variables
let x = 42; // declare
x = x + 1; // assign
x += " world"; // compound assign (also works with strings)Types
let n = 42; // integer (i64)
let f = 3.14; // float (f64)
let s = "hello"; // string
let neg = -0.08; // negative literal
let arr = [1, 2, 3]; // arrayString concatenation
let greeting = "Hello, " + name + "!";
let log_line = path + "\n" + text + "\n\n";
all_text += log_line; // append with +=For loop
for image_path in images_in_folder(folder) {
let img = load_image(image_path);
let text = "";
// ... pipeline steps
}If / else
if image_path.contains("_processed") {
continue; // skip already-processed images
}
if text.is_empty() {
save_to_folder(img, batch_timestamp);
} else {
save_ocr_to_text(text, image_path);
save_to_folder(img, batch_timestamp);
}Operators
| Category | Operators |
|---|---|
| Arithmetic | + - * / |
| Comparison | == != < > <= >= |
| Logical | && || ! |
| Unary | - (negate) ! (not) |
| Compound | += |
Method call syntax
Method calls are desugared to function calls β a.method(b) is identical to method(a, b).
// These are equivalent:
if image_path.contains("_processed") { continue; }
if contains(image_path, "_processed") { continue; }
let lower = text.to_lower();
let lower = to_lower(text);Comments
// This is a line comment β everything after // is ignored
let folder = "C:/scans/invoices"; // inline commentBuilt-in Functions
Image processing
| Signature | Returns | Description |
|---|---|---|
load_image(path) | Image | Load an image from an absolute path. |
crop_area(img, x, y, w, h) | Image | Crop to the rectangle (x, y, width, height). Values are clamped to image bounds. |
apply_perspective(img, corners) | Image | 4-point perspective correction. corners is an 8-element array [tl_x, tl_y, tr_x, tr_y, br_x, br_y, bl_x, bl_y]. |
apply_curve(img, top, side) | Image | Arc/curve de-warp. top and side are floats in roughly -1.0 .. 1.0. |
apply_drawings(img, overlay_path) | Image | Alpha-blend a saved drawing overlay PNG on top of the image. Pass empty string to skip. |
Output
| Signature | Returns | Description |
|---|---|---|
ocr_and_copy(img) | String | Run OCR on the image. Copies extracted text to the Windows clipboard. Returns the text. |
save_ocr_to_text(text, image_path) | () | Write text to output/{stem}.txt. Must be called after ocr_and_copy(). |
copy_to_clipboard(img) | () | Copy the processed image (not text) to the Windows clipboard. |
save_to_folder(img, batch_timestamp) | () | Save the processed image as output/{stem}_{timestamp}_processed.png. |
Iteration & utility
| Signature | Returns | Description |
|---|---|---|
images_in_folder(folder) | Array | Return sorted array of absolute image paths (.png .jpg .jpeg .bmp .tif .tiff .webp) in folder. Excludes automation_* files. |
current_timestamp() | String | Return the current time as YYYYMMDD_HHMMSS. Used for batch_timestamp so each run gets a unique name. |
wait_ms(ms) | () | Pause execution for ms milliseconds. |
print(value) | () | Log a value to the application trace log. |
String helpers
All string helpers can be called as method(str, ...) or as str.method(...).
| Signature | Returns | Description |
|---|---|---|
contains(s, pattern) | bool | True if s contains pattern. |
starts_with(s, prefix) | bool | True if s starts with prefix. |
ends_with(s, suffix) | bool | True if s ends with suffix. |
is_empty(s) | bool | True if s is an empty string or empty array. |
len(s) | int | Character count (string) or element count (array). |
to_lower(s) | String | Lowercase copy. |
to_upper(s) | String | Uppercase copy. |
trim(s) | String | Strip leading/trailing whitespace. |
Variables & Scope
The engine pre-seeds the script scope with two variables before execution:
| Variable | Type | Description |
|---|---|---|
batch_timestamp | String | Timestamp of when Play / Executar was pressed. Format: YYYYMMDD_HHMMSS. Embedded in all output filenames. |
folder | String | Absolute path to the configured working folder. |
Scripts typically override batch_timestamp with let batch_timestamp = current_timestamp(); so each run uses a fresh timestamp. The variable set by the engine is a useful fallback for scripts without this line.
Inside a for loop, image_path and img are the per-iteration variables. text is conventionally declared as let text = ""; and populated by ocr_and_copy.
Example Scripts
1. Crop + OCR + save image and text file
The template generated after a typical recording session.
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Kiky Notes PRO β Automation Script
// Actions : crop, ocr, save-text, save-image
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
let batch_timestamp = current_timestamp();
let folder = "C:/Users/you/Documents/invoices";
for image_path in images_in_folder(folder) {
let img = load_image(image_path);
let text = "";
img = crop_area(img, 120, 80, 1400, 900);
text = ocr_and_copy(img);
save_ocr_to_text(text, image_path);
save_to_folder(img, batch_timestamp);
}2. Perspective correction + save
Scanned documents photographed at an angle.
let batch_timestamp = current_timestamp();
let folder = "C:/scans/books";
for image_path in images_in_folder(folder) {
let img = load_image(image_path);
img = apply_perspective(img, [45,30, 1390,25, 1410,950, 30,960]);
save_to_folder(img, batch_timestamp);
}3. Full pipeline β perspective + curve + OCR
let batch_timestamp = current_timestamp();
let folder = "C:/scans/curved_pages";
for image_path in images_in_folder(folder) {
let img = load_image(image_path);
let text = "";
img = apply_perspective(img, [50,40, 1380,35, 1400,960, 40,970]);
img = apply_curve(img, 0.08, 0.05);
text = ocr_and_copy(img);
save_ocr_to_text(text, image_path);
save_to_folder(img, batch_timestamp);
}4. Run a single image (no loop)
Useful when pasting a path directly and running via the editor.
let batch_timestamp = current_timestamp();
let image_path = "C:/Desktop/receipt.png";
let img = load_image(image_path);
let text = "";
img = crop_area(img, 0, 0, 800, 1200);
text = ocr_and_copy(img);
save_ocr_to_text(text, image_path);
save_to_folder(img, batch_timestamp);Power-User Techniques
Skip already-processed files
for image_path in images_in_folder(folder) {
if image_path.contains("_processed") { continue; }
let img = load_image(image_path);
// ... pipeline
}Collect all OCR results into one file
let batch_timestamp = current_timestamp();
let folder = "C:/invoices";
let all_text = "";
for image_path in images_in_folder(folder) {
let img = load_image(image_path);
img = crop_area(img, 0, 100, 1600, 2000);
let text = ocr_and_copy(img);
all_text += image_path + "\n" + text + "\n\n";
save_to_folder(img, batch_timestamp);
}
// Write the combined file using the folder path as a placeholder image_path
save_ocr_to_text(all_text, folder + "/combined_ocr.txt");Keyword filter β only save if OCR finds a word
let batch_timestamp = current_timestamp();
let folder = "C:/mail";
let keywords = ["invoice", "amount due", "total"];
for image_path in images_in_folder(folder) {
let img = load_image(image_path);
let text = ocr_and_copy(img);
let matched = false;
for kw in keywords {
if text.to_lower().contains(kw) {
matched = true;
}
}
if matched {
save_to_folder(img, batch_timestamp);
save_ocr_to_text(text, image_path);
}
}Change working folder without re-recording
Just edit the folder variable at the top of the script and press F5.
// Change only this line to switch to a different batch:
let folder = "D:/new_batch/march_invoices";
for image_path in images_in_folder(folder) {
let img = load_image(image_path);
img = crop_area(img, 120, 80, 1400, 900);
// ... same pipeline, different folder
save_to_folder(img, batch_timestamp);
}Conditional crop based on filename
for image_path in images_in_folder(folder) {
let img = load_image(image_path);
// Use a tighter crop for files named "receipt_*"
if image_path.contains("receipt_") {
img = crop_area(img, 50, 50, 900, 1200);
} else {
img = crop_area(img, 120, 80, 1400, 900);
}
save_to_folder(img, batch_timestamp);
}Output Files
All output files are written to {working_folder}/output/.
| File | Name pattern | Written by |
|---|---|---|
| Processed image | {stem}_{timestamp}_processed.png | save_to_folder() |
| OCR text file | {stem}.txt | save_ocr_to_text() |
| Combined OCR | any name via save_ocr_to_text() | manual in script |
| Error log | errors.txt | engine β on failure |
Folder layout
working_folder/ βββ invoice1.jpg β input images βββ invoice2.png βββ automation_20260322_153000.rhai β generated scripts βββ output/ βββ invoice1_20260322_153000_processed.png βββ invoice1.txt βββ invoice2_20260322_153000_processed.png βββ invoice2.txt βββ errors.txt β only when errors occurFiles whose stems start with automation_ are automatically excluded from images_in_folder() results β they are script files, not image inputs.