Skip to content

Instantly share code, notes, and snippets.

@robertknight
Created January 20, 2026 08:25
Show Gist options
  • Select an option

  • Save robertknight/79a713cb80efedd417ac66e024931db0 to your computer and use it in GitHub Desktop.

Select an option

Save robertknight/79a713cb80efedd417ac66e024931db0 to your computer and use it in GitHub Desktop.
ocrs clipboard flag addition

Session Prompts

  1. Review the code for the ocrs-cli crate which is a CLI tool for OCR. Then make a plan to implement a new feature which will allow processing images taken from the system clipboard. The feature should be behind a clipboard Cargo feature which is disabled by default. To read from the clipboard, the arboard crate (https://docs.rs/arboard/latest/arboard/) should be used.

  2. `Implement the following plan:

Plan: Clipboard Support for ocrs-cli

Overview

Add a --clipboard flag to read images from the system clipboard instead of a file path. This feature will be behind a clipboard Cargo feature (disabled by default) using the arboard crate.

Files to Modify

  1. ocrs-cli/Cargo.toml - Add arboard dependency and feature
  2. ocrs-cli/src/main.rs - Add CLI flag and image loading logic

Implementation Details

1. Cargo.toml Changes

Add arboard as an optional dependency with the clipboard feature:

[dependencies]
arboard = { version = "3", optional = true }

[features]
clipboard = ["arboard"]

Note: arboard should be conditional on non-WASM targets since clipboard access isn't available in WASM environments:

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
arboard = { version = "3", optional = true }

2. main.rs Changes

A. Modify Args struct

Change image: String to image: Option<String> and add a clipboard: bool field:

struct Args {
    // ... existing fields ...

    /// Path to image to process (None if using clipboard)
    image: Option<String>,

    /// Read image from system clipboard instead of file
    #[cfg(feature = "clipboard")]
    clipboard: bool,
}

B. Update parse_args()

  • Add --clipboard flag parsing (only when feature is enabled)
  • Make image argument optional when --clipboard is provided
  • Update help text to document the new flag
  • Validate that either --clipboard or an image path is provided (but not both)

C. Add clipboard image loading function

Create a new function to read from clipboard and convert to the expected tensor format:

#[cfg(feature = "clipboard")]
fn load_image_from_clipboard() -> anyhow::Result<NdTensor<u8, 3>> {
    use arboard::Clipboard;

    let mut clipboard = Clipboard::new()
        .context("Failed to access clipboard")?;

    let image_data = clipboard.get_image()
        .context("Failed to get image from clipboard. Is there an image copied?")?;

    // arboard returns RGBA, convert to RGB
    let rgba_bytes = image_data.bytes.into_owned();
    let rgb_bytes: Vec<u8> = rgba_bytes
        .chunks_exact(4)
        .flat_map(|chunk| [chunk[0], chunk[1], chunk[2]])
        .collect();

    Ok(NdTensor::from_data(
        [image_data.height, image_data.width, 3],
        rgb_bytes,
    ))
}

D. Update main() image loading logic

Replace the current image loading code with conditional logic:

let color_img: NdTensor<u8, 3> = {
    #[cfg(feature = "clipboard")]
    if args.clipboard {
        load_image_from_clipboard()?
    } else {
        load_image_from_file(args.image.as_ref().unwrap())?
    }

    #[cfg(not(feature = "clipboard"))]
    load_image_from_file(&args.image)?
};

E. Handle JSON output input_path field

When clipboard is used, the input_path for JSON output should indicate clipboard source (e.g., "<clipboard>").

Help Text Addition

  --clipboard

    Read image from system clipboard (requires 'clipboard' feature)

Error Handling

  • Clear error if clipboard access fails
  • Clear error if clipboard doesn't contain an image
  • Validation error if both --clipboard and image path provided
  • Validation error if neither --clipboard nor image path provided

Verification

  1. Build with feature disabled (default): cargo build -p ocrs-cli

    • Verify --clipboard flag is not available
    • Verify existing functionality works
  2. Build with feature enabled: cargo build -p ocrs-cli --features clipboard

    • Copy an image to clipboard
    • Run ocrs --clipboard and verify OCR output
    • Test with --json output to verify <clipboard> path handling
    • Test error case: run without image in clipboard
    • Test error case: provide both --clipboard and image path
  3. Run existing tests: `cargo test -p ocrs-cli``

  4. ``Change argument parsing so that -c is accepted as a shorthand for `--clipboard```

  5. Cool, this is working. I'd like to refactor the code to reduce the number of `cfg` blocks. To do this, make it so that the `--clipboard` flag is always available, but the `load_image_from_clipboard` fails with a helpful message if the clipboard feature is not enabled. The message should read "ocrs was compiled without clipboard support. Use `cargo install ocrs --features clipboard` to enable it."

  6. Commit the change and include a note that this supercedes https://github.com/robertknight/ocrs/pull/128.

  7. Open a GitHub PR

  8. Remove the "Test plan" bit from the commit summary.

  9. Change the crate name in the `cargo install` error message to `ocrs-cli`.

  10. Refactor the `Args` struct so that instead of using two separate fields for clipboard and path, an enum is used instead. This should avoid the need for `unwrap` calls elsewhere.

  11. Update the README in the root of the repository to note that support for reading from the clipboard can be enabled by adding `--features clipboard` to the install command. Also update the CLI Usage section to note that `ocrs --clipboard` or `ocrs -c` will read from the clipboard.

  12. Please list all the prompts I gave you during this session, exactly as I wrote them.

  13. Can you read the full transcript and add the original prompt to the list.

  14. Save this list to a file called session.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment