Skip to content

Commit

Permalink
img - more tests, refactors, fixes. find DONE
Browse files Browse the repository at this point in the history
  • Loading branch information
IGalat committed Sep 29, 2024
1 parent 1077a01 commit a780ee7
Show file tree
Hide file tree
Showing 4 changed files with 258 additions and 131 deletions.
32 changes: 24 additions & 8 deletions src/tapper/helper/_util/image/base.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
import os.path
import re
import sys
from functools import lru_cache
from typing import Any
from typing import Callable
from typing import Union

import mss
import numpy as np
import PIL.Image
import PIL.ImageGrab
import tapper
from mss.base import MSSBase
from numpy import ndarray
from tapper.helper._util import image_fuzz
from tapper.helper.model_types import BboxT
from tapper.helper.model_types import ImagePathT
from tapper.helper.model_types import ImagePixelMatrixT
from tapper.helper.model_types import ImageT
from tapper.helper.model_types import PixelColorT
from tapper.helper.model_types import XyCoordsT
from tapper.model import constants

Expand Down Expand Up @@ -147,7 +140,9 @@ def target_to_image(target: ImageT, bbox: BboxT | None) -> ImagePixelMatrixT:
return target_image


def outer_to_image(outer_or_path_maybe: ImageT | None, bbox: BboxT | None) -> ImagePixelMatrixT:
def outer_to_image(
outer_or_path_maybe: ImageT | None, bbox: BboxT | None
) -> ImagePixelMatrixT:
"""Transform and verify target from API input (or screenshot) to workable image-array."""
outer_maybe = to_pixel_matrix(outer_or_path_maybe)
if outer_maybe is not None and bbox is not None:
Expand All @@ -160,3 +155,24 @@ def outer_to_image(outer_or_path_maybe: ImageT | None, bbox: BboxT | None) -> Im
f"but got {bbox_x}x{bbox_y} vs outer {image_x}x{image_y}"
)
return get_screenshot_if_none_and_cut(outer_maybe, bbox)


def targets_normalize(
targets: (
list[ImageT] | tuple[list[ImageT], BboxT] | list[tuple[ImageT, BboxT | None]]
)
) -> list[tuple[ImagePixelMatrixT, BboxT | None, ImageT]]:
"""Transform any variant of input to :func:find_one_of to list[image-array, bbox, original target]"""
if not targets:
ValueError("find_one_of no targets supplied.")
if isinstance(targets, tuple):
target_images, bbox = targets
return [(to_pixel_matrix(image), bbox, image) for image in target_images]
elif isinstance(targets, list) and isinstance(targets[0], tuple):
return [(to_pixel_matrix(image), bbox, image) for image, bbox in targets]
else:
return [(to_pixel_matrix(image), None, image) for image in targets]


def save_to_disk(image: ImagePixelMatrixT, full_name_no_ext: ImagePathT) -> None:
PIL.Image.fromarray(image).save(full_name_no_ext, "PNG")
89 changes: 59 additions & 30 deletions src/tapper/helper/_util/image/find_util.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,10 @@
import os.path
import re
import sys
from functools import lru_cache
from lib2to3.pytree import convert
from sys import prefix
from typing import Any
from typing import Callable
from typing import Union

import mss
import numpy as np
import PIL.Image
import PIL.ImageGrab
import tapper
from mss.base import MSSBase
from numpy import ndarray
import time

from tapper.helper._util.image import base
from tapper.helper.model_types import BboxT
from tapper.helper.model_types import ImagePathT
from tapper.helper.model_types import ImagePixelMatrixT
from tapper.helper.model_types import ImageT
from tapper.helper.model_types import PixelColorT
from tapper.helper.model_types import XyCoordsT
from tapper.model import constants


def find_raw(
Expand All @@ -36,13 +18,13 @@ def find_raw(


def api_find_raw(
image: ImagePixelMatrixT,
target: ImagePixelMatrixT,
bbox: BboxT | None,
outer_maybe: ImagePixelMatrixT | None = None,
) -> tuple[float, XyCoordsT]:
x_start, y_start = base.get_start_coords(outer_maybe, bbox)
outer = base.outer_to_image(outer_maybe, bbox)
confidence, xy = find_raw(image, outer)
confidence, xy = find_raw(target, outer)
return confidence, (x_start + xy[0], y_start + xy[1])


Expand All @@ -61,8 +43,8 @@ def find(
def api_find(
target: ImageT,
bbox: BboxT | None,
outer_or_path_maybe: ImageT | None = None,
precision: float = 1.0,
outer_or_path_maybe: ImageT | None,
precision: float,
) -> XyCoordsT | None:
if target is None:
raise ValueError("image_find nees something to search for.")
Expand All @@ -75,13 +57,60 @@ def api_find(
return x_start + found[0], y_start + found[1]


def find_one_of() -> None:
pass
def find_one_of(
targets_normalized: list[tuple[ImagePixelMatrixT, BboxT | None, ImageT]],
outer_or_path_maybe: ImageT | None,
precision: float,
) -> tuple[ImageT, XyCoordsT] | tuple[None, None]:
outer = base.outer_to_image(outer_or_path_maybe, None)
for target, bbox, original in targets_normalized:
outer_cut = base.outer_to_image(outer, bbox)
if (xy := find(target, outer_cut, precision)) is not None:
return original, xy
return None, None


def api_find_one_of(
targets: list[ImageT]
| tuple[list[ImageT], BboxT]
| list[tuple[ImageT, BboxT | None]],
outer_or_path_maybe: ImageT | None,
precision: float,
) -> tuple[ImageT, XyCoordsT] | tuple[None, None]:
targets_normalized = base.targets_normalize(targets)
return find_one_of(targets_normalized, outer_or_path_maybe, precision)


def wait_for() -> None:
pass
def wait_for(
target: ImageT,
bbox: BboxT | None,
timeout: int | float,
interval: float,
precision: float,
) -> XyCoordsT | None:
target_image = base.target_to_image(target, bbox)
finish_time = time.perf_counter() + timeout
while time.perf_counter() < finish_time:
outer = base.outer_to_image(None, bbox)
if found := find(target_image, outer, precision):
return found
time.sleep(interval)
return None


def wait_for_one_of() -> None:
pass
def wait_for_one_of(
targets: list[ImageT]
| tuple[list[ImageT], BboxT]
| list[tuple[ImageT, BboxT | None]],
timeout: int | float,
interval: float,
precision: float,
) -> tuple[ImageT, XyCoordsT] | tuple[None, None]:
targets_normalized = base.targets_normalize(targets)
finish_time = time.perf_counter() + timeout
while time.perf_counter() < finish_time:
found, xy = find_one_of(targets_normalized, None, precision)
if found is not None and xy is not None:
return found, xy
time.sleep(interval)
return None, None
Loading

0 comments on commit a780ee7

Please sign in to comment.