feat: add gesture sequences and calibrated pixel drags
This commit is contained in:
1 parent
2a3bbaa3fb
commit
479a185192
31 files changed
+2440
-44
No files matched your search
@@ -517,14 +517,20 @@ def crop_and_annotate_target(
|
||||
return out_buf.getvalue()
|
||||
|
||||
|
||||
def _resolve_coordinates(coord: Any, width: int, height: int) -> tuple[int, int] | None:
|
||||
def _resolve_coordinates(
|
||||
coord: Any, width: int, height: int, coordinate_space: str | None = None
|
||||
) -> tuple[int, int] | None:
|
||||
"""Helper to safely parse coordinates into pixel space."""
|
||||
if not isinstance(coord, (list, tuple)) or len(coord) < 2:
|
||||
return None
|
||||
try:
|
||||
x, y = float(coord[0]), float(coord[1])
|
||||
# If coordinates are normalized (0.0 <= x <= 1.0)
|
||||
if 0.0 <= x <= 1.0 and 0.0 <= y <= 1.0:
|
||||
if coordinate_space == "pixel":
|
||||
px, py = int(round(x)), int(round(y))
|
||||
elif coordinate_space == "normalized":
|
||||
px, py = int(round(x * width / 1000)), int(round(y * height / 1000))
|
||||
elif 0.0 <= x <= 1.0 and 0.0 <= y <= 1.0:
|
||||
px = int(round(x * width))
|
||||
py = int(round(y * height))
|
||||
elif 0 <= x <= 1000 and 0 <= y <= 1000 and (width > 1000 or height > 1000):
|
||||
@@ -563,6 +569,17 @@ def draw_action_overlay_on_image(
|
||||
if not image_bytes:
|
||||
return image_bytes
|
||||
|
||||
if action_name == "action_sequence":
|
||||
receipts = action_args.get("sequence_results")
|
||||
annotated = image_bytes
|
||||
for member in receipts if isinstance(receipts, list) else []:
|
||||
if (
|
||||
isinstance(member, dict)
|
||||
and member.get("execution") == "completed"
|
||||
and member.get("action") in {"click", "drag"}
|
||||
):
|
||||
annotated = draw_action_overlay_on_image(annotated, member["action"], member)
|
||||
return annotated
|
||||
try:
|
||||
img = Image.open(io.BytesIO(image_bytes))
|
||||
if img.mode in ("RGBA", "P"):
|
||||
@@ -584,7 +601,7 @@ def draw_action_overlay_on_image(
|
||||
or action_args.get("coordinates")
|
||||
or action_args.get("point")
|
||||
)
|
||||
pt = _resolve_coordinates(coord, width, height)
|
||||
pt = _resolve_coordinates(coord, width, height, action_args.get("coordinate_space"))
|
||||
if pt:
|
||||
x, y = pt
|
||||
# Outer white aura
|
||||
@@ -637,7 +654,9 @@ def draw_action_overlay_on_image(
|
||||
if isinstance(sequence, list):
|
||||
pts = []
|
||||
for coord in sequence:
|
||||
pt = _resolve_coordinates(coord, width, height)
|
||||
pt = _resolve_coordinates(
|
||||
coord, width, height, action_args.get("coordinate_space")
|
||||
)
|
||||
if pt:
|
||||
pts.append(pt)
|
||||
|
||||
@@ -703,8 +722,12 @@ def draw_action_overlay_on_image(
|
||||
start_pt, end_pt = None, None
|
||||
|
||||
if kind == "coords" and isinstance(target, list) and len(target) == 4:
|
||||
start_pt = _resolve_coordinates(target[:2], width, height)
|
||||
end_pt = _resolve_coordinates(target[2:], width, height)
|
||||
start_pt = _resolve_coordinates(
|
||||
target[:2], width, height, action_args.get("coordinate_space")
|
||||
)
|
||||
end_pt = _resolve_coordinates(
|
||||
target[2:], width, height, action_args.get("coordinate_space")
|
||||
)
|
||||
elif kind == "direction" and isinstance(target, str):
|
||||
direction = target.lower()
|
||||
cx, cy = width // 2, height // 2
|
||||
@@ -758,7 +781,7 @@ def draw_action_overlay_on_image(
|
||||
elif action in ("input_text", "type"):
|
||||
coord = action_args.get("target") or action_args.get("coordinates")
|
||||
if coord:
|
||||
pt = _resolve_coordinates(coord, width, height)
|
||||
pt = _resolve_coordinates(coord, width, height, action_args.get("coordinate_space"))
|
||||
if pt:
|
||||
x, y = pt
|
||||
box_w = max(60, int(base_dim * 0.15))
|
||||
@@ -805,9 +828,21 @@ def overlay_action_on_screenshot(image_bytes: bytes, action_obj: Any) -> bytes |
|
||||
"sequence",
|
||||
"targets",
|
||||
"normalized_coordinates",
|
||||
"coordinate_space",
|
||||
"sequence_results",
|
||||
):
|
||||
if key in action and key not in action_args:
|
||||
action_args[key] = action[key]
|
||||
if (
|
||||
act_name == "drag"
|
||||
and isinstance(action.get("coordinates"), list)
|
||||
and len(action["coordinates"]) == 4
|
||||
):
|
||||
action_args.update(
|
||||
start=action["coordinates"][:2],
|
||||
end=action["coordinates"][2:],
|
||||
coordinate_space=action.get("coordinate_space"),
|
||||
)
|
||||
annotated = draw_action_overlay_on_image(
|
||||
image_bytes=image_bytes, action_name=act_name, action_args=action_args
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user