app.image - Image Processing API

Image info retrieval, format conversion, resizing, and more.

Basic Info

app.image.size(path)

Get image dimensions (in pixels).

Parameters:

  • path (string) - Image file path

Returns: table|nil - {width, height} or nil

local size = app.image.size("/path/to/image.jpg")
if size then
    app.log.info("Dimensions: " .. size.width .. "x" .. size.height)
end

app.image.format(path)

Get image format.

Parameters:

  • path (string) - Image file path

Returns: string|nil - Format name (jpeg, png, gif, tiff, bmp, webp, heic)

local format = app.image.format("/path/to/image.jpg")  -- "jpeg"

Conversion Operations

app.image.convert(srcPath, destPath, format?)

Convert image format.

Parameters:

  • srcPath (string) - Source image path
  • destPath (string) - Destination path
  • format (string, optional) - Target format (if not specified, inferred from destination file extension)

Returns: boolean - Whether successful

-- Auto-detect format from extension
app.image.convert("/path/to/image.jpg", "/path/to/image.png")

-- Explicitly specify format
app.image.convert("/path/to/image.png", "/path/to/output.jpg", "jpeg")

app.image.resize(srcPath, destPath, width, height)

Resize an image.

Parameters:

  • srcPath (string) - Source image path
  • destPath (string) - Destination path
  • width (number) - Target width
  • height (number) - Target height

Returns: boolean - Whether successful

app.image.resize("/path/to/image.jpg", "/path/to/thumb.jpg", 200, 150)

app.image.scale(srcPath, destPath, factor)

Scale an image proportionally.

Parameters:

  • srcPath (string) - Source image path
  • destPath (string) - Destination path
  • factor (number) - Scale factor (e.g., 0.5 to halve, 2.0 to double)

Returns: boolean - Whether successful

-- Scale down to 50%
app.image.scale("/path/to/image.jpg", "/path/to/half.jpg", 0.5)

-- Scale up 2x
app.image.scale("/path/to/image.jpg", "/path/to/double.jpg", 2.0)

Other Operations

app.image.rotate(srcPath, destPath, degrees)

Rotate an image.

Parameters:

  • srcPath (string) - Source image path
  • destPath (string) - Destination path
  • degrees (number) - Rotation angle (clockwise)

Returns: boolean - Whether successful

app.image.rotate("/path/to/image.jpg", "/path/to/rotated.jpg", 90)

app.image.crop(srcPath, destPath, x, y, width, height)

Crop an image.

Parameters:

  • srcPath (string) - Source image path
  • destPath (string) - Destination path
  • x (number) - Starting X coordinate
  • y (number) - Starting Y coordinate
  • width (number) - Crop width
  • height (number) - Crop height

Returns: boolean - Whether successful

app.image.crop("/path/to/image.jpg", "/path/to/cropped.jpg",
    100, 100, 500, 300)

app.image.exif(path)

Get EXIF and metadata information of an image.

Parameters:

  • path (string) - Image file path

Returns: table, error - Contains the following fields:

  • pixelWidth (number) - Pixel width
  • pixelHeight (number) - Pixel height
  • dpiWidth (number) - DPI width
  • dpiHeight (number) - DPI height
  • colorModel (string) - Color model
  • depth (number) - Bit depth
  • orientation (number) - Orientation
  • exif (table) - EXIF sub-dictionary
  • tiff (table) - TIFF sub-dictionary
  • gps (table) - GPS sub-dictionary
local info, err = app.image.exif("/path/to/photo.jpg")
if info then
    app.log.info("Dimensions: " .. info.pixelWidth .. "x" .. info.pixelHeight)
    if info.exif then
        app.log.info("EXIF data: " .. app.json.stringify(info.exif))
    end
end

app.image.thumbnail(srcPath, destPath, maxSize)

Generate a thumbnail while preserving the original aspect ratio.

Parameters:

  • srcPath (string) - Source image path
  • destPath (string) - Destination path
  • maxSize (number) - Maximum edge length (in pixels)

Returns: boolean, error

local ok, err = app.image.thumbnail("/path/to/photo.jpg", "/path/to/thumb.jpg", 200)

app.image.watermark(srcPath, destPath, text, options?)

Add a text watermark.

Parameters:

  • srcPath (string) - Source image path
  • destPath (string) - Destination path
  • text (string) - Watermark text
  • options (table, optional):
    • fontSize (number) - Font size (default 24)
    • opacity (number) - Opacity 0-1 (default 0.5)
    • position (string) - Position: "topLeft", "topRight", "bottomLeft", "bottomRight" (default), "center"
    • color (string) - Color: "white" (default), "black", "red", "blue", "green", "gray"

Returns: boolean, error

local ok, err = app.image.watermark(
    "/path/to/photo.jpg",
    "/path/to/watermarked.jpg",
    "© 2024 My Company",
    {fontSize = 36, opacity = 0.3, position = "bottomRight", color = "white"}
)

app.image.flip(srcPath, destPath, direction)

Flip an image.

Parameters:

  • srcPath (string) - Source image path
  • destPath (string) - Destination path
  • direction (string) - Flip direction: "horizontal" or "vertical"

Returns: boolean, error

app.image.flip("/path/to/image.jpg", "/path/to/flipped.jpg", "horizontal")

app.image.grayscale(srcPath, destPath)

Convert an image to grayscale.

Parameters:

  • srcPath (string) - Source image path
  • destPath (string) - Destination path

Returns: boolean, error

app.image.grayscale("/path/to/image.jpg", "/path/to/gray.jpg")

app.image.composite(basePath, overlayPath, destPath, options?)

Overlay one image onto another.

Parameters:

  • basePath (string) - Base image path
  • overlayPath (string) - Overlay image path
  • destPath (string) - Destination path
  • options (table, optional):
    • x (number) - Overlay X coordinate (default 0)
    • y (number) - Overlay Y coordinate (default 0)
    • opacity (number) - Overlay opacity 0-1 (default 1.0)

Returns: boolean, error

app.image.composite(
    "/path/to/background.jpg",
    "/path/to/logo.png",
    "/path/to/result.jpg",
    {x = 50, y = 50, opacity = 0.8}
)

Examples

Batch Generate Thumbnails

function MyPlugin:handleThumbnails(context)
    local result = app.dialog.form({
        title = "Generate Thumbnails",
        fields = {
            {type = "number", id = "width", label = "Width", default = 200},
            {type = "number", id = "height", label = "Height", default = 200}
        }
    })

    if not result then return end

    local thumbDir = app.path.join(context.currentDirectory, "thumbnails")
    app.file.mkdir(thumbDir)

    local count = 0
    for _, file in ipairs(context.selectedFiles) do
        local size = app.image.size(file)
        if size then
            local thumbPath = app.path.join(thumbDir, app.path.basename(file))

            if app.image.resize(file, thumbPath, result.width, result.height) then
                count = count + 1
            end
        end
    end

    app.notification.show("Done", "Generated " .. count .. " thumbnails")
    app.finder.reveal(thumbDir)
end

Batch Convert Format

function MyPlugin:handleConvertToPNG(context)
    local count = 0
    for _, file in ipairs(context.selectedFiles) do
        local format = app.image.format(file)
        if format and format ~= "png" then
            local destPath = app.path.removeExtension(file) .. ".png"

            if app.image.convert(file, destPath) then
                count = count + 1
            end
        end
    end

    app.notification.show("Done", "Converted " .. count .. " images to PNG")
end
Developer Documentation
User Guide
Getting Started Script Menus FAQ
Script Development
Development Guide
Plugin Development
Quick Start Development Guide Example Plugins
API Reference
Overview API Query Plugin Info Logging Finder Context Plugin Settings Internationalization
UI & Interaction
Dialog Progress Notification Chooser WebView Status Bar Dock
Files & Paths
File Operations Path Utilities Finder Actions Trash Extended Attributes Metadata File Watcher
Data Formats
JSON Plist CSV XML PDF Image
Text & Encoding
String Regex Date & Time Color Crypto
System
Shell Commands Process Application System Info AppleScript Shortcuts
System Info
Network Power/Battery Screen/Appearance Audio Bluetooth Location
Network
HTTP WebSocket URL
Input & Clipboard
Keyboard Mouse Hotkey Clipboard Window
Storage
SQLite Keychain UserDefaults
Media
OCR QR Code
Utilities
Archive UTI Share Timer Wake Lock Thread