Object MethodScanning and DetectionComing soonv1.0.51

Region:findColorBlobs(color, options?)

Finds every connected patch of one colour in this region from a single capture: a hex string, a list of hex strings or colour assets, a colour asset, or an HSV range. Returns an array of {x, y, w, h, cx, cy, area, fill} tables: an empty table when nothing matches, nil for invalid arguments or a scan that could not run. The call never taps and leaves getLastMatch unchanged.

Documented for app version 1.0.51 (not on Google Play yet)Updated:

Detailed Explanation

This section explains when to use the API, how to call it, and which structures it works best with in production flow.

How To Call It

This is an object method: call it with a colon on a Region object created with Region(x, y, w, h), or Region() for the whole screen (region:<method>(...)). The global Region table does not have this method. Requires Macro Handler 1.0.51 or later.

When To Use It

Use it when a script needs every patch of a colour at once, for example to count health-bar segments, pick the largest marker or tap each coloured dot, instead of calling region:findColor again and again with exclusions. Call Snap.screenRefresh() first when the screen may have changed. FindParam is not read: the second argument is an options table.

Parameters and Return

color is a hex string such as "#FF0000", "#AARRGGBB" or "#F00", a list of up to 16 hex strings or colour assets matched together, Asset.color(...), or an HSV table { hMin, hMax, sMin, sMax, vMin, vMax } with hue in degrees and s and v from 0 to 1. Numbers, text assets and image assets are refused. options: tolerance (0-255, default 10), minArea (default 1), maxResults (1-256, default 32), connectivity (8 or 4), step (1-8 sampling stride; areas become estimates), sort ("area" or "position") and excludeRegion. x, y, w, h, cx and cy are in the macro's coordinates, while area and minArea count screen-capture pixels of the device running the macro and are not rescaled: on another resolution compare w and h instead. fill is the matched share of the box. The result is an empty table when nothing matches and nil for invalid arguments or a failed scan (System.lastScanError() says why).

Best Combined With

Check for nil first, then loop over the rows: #blobs is the number of patches and, with sort = "area", blobs[1] is the largest. Tap a patch with click(Point(b.cx, b.cy)). Each call captures the screen once, so a polling loop should wait between calls.

Example Usage

The snippet below is a starter pattern that can be applied directly in runtime flow.

-- Region:findColorBlobs
Snap.screenRefresh()
local region = Region()
local blobs = region:findColorBlobs("#FF0000", { minArea = 20 })
-- nil: the call could not run; {}: no patch matched
if blobs and #blobs > 0 then
  print("patches: " .. #blobs .. ", largest area: " .. blobs[1].area)
end

Copyable Progressive Examples

From foundation to combined usage, each level is provided as a separate code block so you can copy the level you need and adapt it directly.

Foundation

Shows the shortest direct way to call the API.

Foundation
-- Region:findColorBlobs
Snap.screenRefresh()
local region = Region()
local blobs = region:findColorBlobs("#FF0000", { minArea = 20 })
-- nil: the call could not run; {}: no patch matched
if blobs and #blobs > 0 then
  print("patches: " .. #blobs .. ", largest area: " .. blobs[1].area)
end

Simple

Wraps the base call with minimal flow control.

Simple
local stepOk = true
-- Region:findColorBlobs
Snap.screenRefresh()
local region = Region()
local blobs = region:findColorBlobs("#FF0000", { minArea = 20 })
-- nil: the call could not run; {}: no patch matched
if blobs and #blobs > 0 then
  print("patches: " .. #blobs .. ", largest area: " .. blobs[1].area)
end
if stepOk then
  wait(200)
end

Practical Flow

A practical pattern for real macros with pcall, logging, and guards.

Practical Flow
local ok, err = pcall(function()
  -- Region:findColorBlobs
  Snap.screenRefresh()
  local region = Region()
  local blobs = region:findColorBlobs("#FF0000", { minArea = 20 })
  -- nil: the call could not run; {}: no patch matched
  if blobs and #blobs > 0 then
    print("patches: " .. #blobs .. ", largest area: " .. blobs[1].area)
  end
end)

if not ok then
  print("API step failed: Region:findColorBlobs: " .. tostring(err))
  requestStop()
end

Detailed

This level packages the API into a reusable helper with error reporting.

Detailed
-- findColorBlobs returns plain tables: nil means the call failed, {} means nothing matched
local function run_findcolorblobs_step()
  -- Region:findColorBlobs
  Snap.screenRefresh()
  local region = Region()
  local blobs = region:findColorBlobs("#FF0000", { minArea = 20 })
  -- nil: the call could not run; {}: no patch matched
  if blobs and #blobs > 0 then
    print("patches: " .. #blobs .. ", largest area: " .. blobs[1].area)
  end
end

local ok, err = pcall(run_findcolorblobs_step)
if not ok then
  toast("Step failed")
  print(err)
end

Combined

Combines the API with related structures to form a more realistic workflow.

Combined
-- Region:findColorBlobs: tap every red marker, largest first
Snap.screenRefresh()
local region = Region()
local blobs = region:findColorBlobs("#FF0000", { tolerance = 12, minArea = 20, sort = "area" })
if blobs == nil then
  print("findColorBlobs failed: " .. tostring(System.lastScanError()))
elseif #blobs == 0 then
  print("no red marker")
else
  for _, b in ipairs(blobs) do
    click(Point(b.cx, b.cy))
    wait(150)
  end
end