
import os
import re
import cv2
import numpy as np


# 工具类
class AiUtils(object):

    # 在屏幕中找到对应的图片
    @classmethod
    def findImageInScreen(cls, target):
        # 加载原始图像和模板图像
        image_path = AiUtils.imagePathWithName("bgv")  # 替换为你的图像路径
        template_path = AiUtils.imagePathWithName(target)  # 替换为你的模板路径

        # 读取图像和模板，确保它们都是单通道灰度图
        image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
        template = cv2.imread(template_path, cv2.IMREAD_GRAYSCALE)

        if image is None:
            raise ValueError("背景图无法加载")

        if template is None:
            raise ValueError("模板图无法加载")


        # 获取模板的宽度和高度
        w, h = template.shape[::-1]

        # 使用模板匹配方法
        res = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
        threshold = 0.7  # 匹配度阈值，可以根据需要调整
        loc = np.where(res >= threshold)

        # 检查是否有匹配结果
        if loc[0].size > 0:
            # 取第一个匹配位置
            pt = zip(*loc[::-1]).__next__()  # 获取第一个匹配点的坐标
            center_x = int(pt[0] + w // 2)
            center_y = int(pt[1] + h // 2)
            # print(f"第一个匹配到的小心心中心坐标: ({center_x}, {center_y})")
            return center_x, center_y
        else:
            print("未找到匹配的目标")
            return -1, -1


    # 使用正则查找字符串中的数字
    @classmethod
    def findNumber(cls, str):
        # 使用正则表达式匹配数字
        match = re.search(r'\d+', str)
        if match:
            return int(match.group())  # 将匹配到的数字转换为整数
        return None  # 如果没有找到数字，返回 None


    # 选择截图
    @classmethod
    def screenshot(cls):
        image_path = AiUtils.imagePathWithName("bgv")   # 替换为你的图像路径
        image = cv2.imread(image_path)

        # 如果图像过大，缩小显示
        scale_percent = 50  # 缩小比例
        width = int(image.shape[1] * scale_percent / 100)
        height = int(image.shape[0] * scale_percent / 100)
        dim = (width, height)
        resized_image = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)

        # 创建一个窗口并显示缩小后的图像
        cv2.namedWindow("Image")
        cv2.imshow("Image", resized_image)
        print("请在图像上选择爱心图标区域，然后按Enter键确认。")

        # 使用selectROI函数手动选择区域
        roi = cv2.selectROI("Image", resized_image, showCrosshair=True, fromCenter=False)

        # 将ROI坐标按原始图像尺寸放大
        x, y, w, h = roi
        x = int(x * image.shape[1] / resized_image.shape[1])
        y = int(y * image.shape[0] / resized_image.shape[0])
        w = int(w * image.shape[1] / resized_image.shape[1])
        h = int(h * image.shape[0] / resized_image.shape[0])

        # 根据选择的ROI提取爱心图标
        if w > 0 and h > 0:  # 确保选择的区域有宽度和高度
            heart_icon = image[y:y + h, x:x + w]

            # 转换为HSV颜色空间
            hsv = cv2.cvtColor(heart_icon, cv2.COLOR_BGR2HSV)

            # 定义红色的HSV范围
            lower_red1 = np.array([0, 120, 70])
            upper_red1 = np.array([10, 255, 255])
            lower_red2 = np.array([170, 120, 70])
            upper_red2 = np.array([180, 255, 255])

            # 创建掩模
            mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
            mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
            mask = mask1 + mask2

            # 反转掩模，因为我们想要的是爱心图标，而不是背景
            mask_inv = cv2.bitwise_not(mask)

            # 应用掩模
            heart_icon = cv2.bitwise_and(heart_icon, heart_icon, mask=mask_inv)

            # 创建一个全透明的背景
            height, width, channels = heart_icon.shape
            roi = np.zeros((height, width, channels), dtype=np.uint8)

            # 将爱心图标粘贴到透明背景上
            for c in range(channels):
                roi[:, :, c] = np.where(mask_inv == 255, heart_icon[:, :, c], roi[:, :, c])

            # 图片名称
            imgName = "temp.png"

            # 保存结果
            cv2.imwrite(imgName, roi)

            # 显示结果
            cv2.imshow("Heart Icon with Transparent Background", roi)
            cv2.waitKey(0)
            cv2.destroyAllWindows()
        else:
            print("未选择有效区域。")


    # 根据名称获取图片完整地址
    @classmethod
    def imagePathWithName(cls, name):
        current_file_path = os.path.abspath(__file__)
        # 获取当前文件所在的目录（即script目录）
        current_dir = os.path.dirname(current_file_path)
        # 由于script目录位于项目根目录下一级，因此需要向上一级目录移动两次
        project_root = os.path.abspath(os.path.join(current_dir, '..'))
        # 构建资源文件的完整路径，向上两级目录，然后进入 resources 目录
        resource_path = os.path.abspath(os.path.join(project_root, 'resources', name + ".png")).replace('/', '\\')
        return resource_path


# AiUtils.screenshot()