Skip to contents

Ask OpenAI whether the supplied image depicts *artwork* — either a digital artwork (e.g. digital painting, illustration) or a professional digitization of physical artwork (a flat reproduction / scan). Photographs of artwork in situ (framed on a wall, inside a gallery, held by a person) are **not** treated as artwork by this predicate.

Usage

is_artwork(img_path, max_bytes = 2L * 1024L^2L, timeout = 30, max_tokens = 100)

Arguments

img_path

Character. Path to a thumbnail-sized image file.

max_bytes

Integer. Maximum accepted file size in bytes. Default `2 * 1024^2` (2 MB) — comfortably fits a 1000x1000 JPEG or PNG.

timeout

Numeric. Request timeout in seconds. Default 30.

max_tokens

Integer. Output token cap. Default 100.

Value

A list with:

`is_artwork`

Logical. `TRUE` if the image depicts artwork.

`confidence`

Numeric in `[0, 1]`. Model self-reported confidence.

`reason`

Character. One-sentence explanation.

`model`

Character. Model that produced the answer.

`usage`

List. Token usage from the Responses API.

Details

This function enforces a **thumbnail-input contract**: `img_path` must point to a file of at most `max_bytes` bytes (default 2 MB). It does **not** resize the image itself — callers are expected to pre-resize (e.g., to ~1000x1000 px) during ingestion. This keeps every call fast and deterministic: no libpng decode of large masters, no re-encoding, ~20 ms of local work before the API call.

The model, reasoning effort, and request shape are hardcoded. The `ART_OPENAI_MODEL` env var is deliberately **not** consulted.

Efficiency choices:

  • `gpt-5.4-nano` — smallest current GPT-5 tier with vision support.

  • `reasoning = list(effort = "none")` — skip chain-of-thought entirely.

  • `detail = "low"` — Responses API encodes the image as a single 85-token tile, independent of upload resolution.

  • Raw-byte read + magic-byte mime detection — no image library call.

  • Strict JSON schema with three small fields keeps output short.

Supported image formats: PNG, JPEG, WebP, GIF.

See also

[openai_responses()] for the underlying API call.

Examples

if (FALSE) { # \dontrun{
res <- is_artwork("path/to/thumbnail.jpg")
if (res$is_artwork && res$confidence > 0.8) {
  message("Looks like artwork: ", res$reason)
}
} # }