diff --git a/.gitignore b/.gitignore index 76cb155..b3aa60a 100644 --- a/.gitignore +++ b/.gitignore @@ -131,4 +131,5 @@ dmypy.json # 地图资源 fastapi_genshin_map/GetMapImage/map_data fastapi_genshin_map/GetMapImage/resource_data +fastapi_genshin_map/GetMapImage/icon_data fastapi_genshin_map/GetMapImage/genshinmap.log \ No newline at end of file diff --git a/README.md b/README.md index 391fedc..c21f6e0 100644 --- a/README.md +++ b/README.md @@ -43,4 +43,4 @@ + [GPL-3.0 License](https://github.com/KimigaiiWuyi/GenshinUID/blob/main/LICENSE) ©[@KimigaiiWuyi](https://github.com/KimigaiiWuyi) ## 丨返回图示例 -![测试.jpg](https://s2.loli.net/2022/10/17/D2cI5tQdgVk3Uuz.jpg) +![测试.jpg](https://s2.loli.net/2023/10/18/Khd5LRQF3HqrEVD.jpg) diff --git a/fastapi_genshin_map/GetMapImage/GenshinMap/genshinmap/img.py b/fastapi_genshin_map/GetMapImage/GenshinMap/genshinmap/img.py index 4facad1..4d12938 100644 --- a/fastapi_genshin_map/GetMapImage/GenshinMap/genshinmap/img.py +++ b/fastapi_genshin_map/GetMapImage/GenshinMap/genshinmap/img.py @@ -6,7 +6,7 @@ import numpy as np from sklearn.cluster import KMeans from shapely.geometry import Point, Polygon -from .models import XYPoint +from .models import XYPoint, XYZPoint Pos = Tuple[float, float] Poses = List[XYPoint] @@ -14,8 +14,8 @@ Points = List[Point] def k_means_points( - points: List[XYPoint], length: int = 500, clusters: int = 3 -) -> List[Tuple[XYPoint, XYPoint, Poses]]: + points: List[XYZPoint], length: int = 500, clusters: int = 3 +) -> List[Tuple[XYZPoint, XYZPoint, Poses]]: """ 通过 K-Means 获取集群坐标列表 diff --git a/fastapi_genshin_map/GetMapImage/GenshinMap/genshinmap/models.py b/fastapi_genshin_map/GetMapImage/GenshinMap/genshinmap/models.py index 5e97c07..02d8f48 100644 --- a/fastapi_genshin_map/GetMapImage/GenshinMap/genshinmap/models.py +++ b/fastapi_genshin_map/GetMapImage/GenshinMap/genshinmap/models.py @@ -59,6 +59,10 @@ class Point(BaseModel): author_name: str ctime: str display_state: int + area_id: int + ext_attrs: str + z_level: int + icon_sign: int class Slice(BaseModel): @@ -100,6 +104,12 @@ class XYPoint(NamedTuple): y: float +class XYZPoint(NamedTuple): + x: float + y: float + z: int + + class Kind(BaseModel): id: int name: str diff --git a/fastapi_genshin_map/GetMapImage/GenshinMap/genshinmap/utils.py b/fastapi_genshin_map/GetMapImage/GenshinMap/genshinmap/utils.py index d747225..e017251 100644 --- a/fastapi_genshin_map/GetMapImage/GenshinMap/genshinmap/utils.py +++ b/fastapi_genshin_map/GetMapImage/GenshinMap/genshinmap/utils.py @@ -8,7 +8,7 @@ from asyncio import gather, create_task from PIL import Image from httpx import AsyncClient -from .models import Maps, Point, XYPoint +from .models import Maps, Point, XYPoint, XYZPoint CLIENT = AsyncClient() @@ -76,7 +76,7 @@ async def get_map_by_pos( return await get_img(map.slices[_pos_to_index(x, y)]) -def get_points_by_id(id_: int, points: List[Point]) -> List[XYPoint]: +def get_points_by_id(id_: int, points: List[Point]) -> List[XYZPoint]: """ 根据 Label ID 获取坐标点 @@ -91,13 +91,13 @@ def get_points_by_id(id_: int, points: List[Point]) -> List[XYPoint]: `list[XYPoint]` """ return [ - XYPoint(point.x_pos, point.y_pos) + XYZPoint(point.x_pos, point.y_pos, point.z_level) for point in points if point.label_id == id_ ] -def convert_pos(points: List[XYPoint], origin: List[int]) -> List[XYPoint]: +def convert_pos(points: List[XYZPoint], origin: List[int]) -> List[XYZPoint]: """ 将米游社资源坐标转换为以左上角为原点的坐标系的坐标 @@ -118,7 +118,7 @@ def convert_pos(points: List[XYPoint], origin: List[int]) -> List[XYPoint]: >>> convert_pos(points, origin) [XYPoint(x=6044, y=9335), XYPoint(x=644, y=6135)] """ - return [XYPoint(x + origin[0], y + origin[1]) for x, y in points] + return [XYZPoint(x + origin[0], y + origin[1], z) for x, y, z in points] def convert_pos_crop( diff --git a/fastapi_genshin_map/GetMapImage/download.py b/fastapi_genshin_map/GetMapImage/download.py new file mode 100644 index 0000000..8803a6d --- /dev/null +++ b/fastapi_genshin_map/GetMapImage/download.py @@ -0,0 +1,10 @@ +import aiofiles +import aiohttp + + +async def download_file(url, save_path): + async with aiohttp.ClientSession() as session: + async with session.get(url) as response: + if response.status == 200: + async with aiofiles.open(save_path, "wb") as f: + await f.write(await response.read()) diff --git a/fastapi_genshin_map/GetMapImage/get_map_image.py b/fastapi_genshin_map/GetMapImage/get_map_image.py index e863bdb..06f9cc9 100644 --- a/fastapi_genshin_map/GetMapImage/get_map_image.py +++ b/fastapi_genshin_map/GetMapImage/get_map_image.py @@ -9,6 +9,7 @@ from PIL import Image from .GenshinMap.genshinmap import img, models, request, utils from .logger import logger +from .download import download_file Image.MAX_IMAGE_PIXELS = 333120000 router = APIRouter(prefix="/get_map") @@ -16,6 +17,7 @@ TEXT_PATH = Path(__file__).parent / "texture2d" mark_quest = Image.open(TEXT_PATH / "mark_quest.png").resize((32, 32)) MAP = Path(__file__).parent / "map_data" RESOURCE_PATH = Path(__file__).parent / "resource_data" +ICON_PATH = Path(__file__).parent / "icon_data" CHASM_PATH = MAP / "chasm.png" ENKANOMIYA_PATH = MAP / "enkanomiya.png" TEYVAT_PATH = MAP / "teyvat.png" @@ -30,6 +32,9 @@ MAP_ID_DICT = { # MapID.golden_apple_archipelago, # 金苹果群岛 } +if not ICON_PATH.exists(): + ICON_PATH.mkdir(exist_ok=True) + @router.on_event("startup") async def create_genshin_map(): @@ -89,15 +94,16 @@ async def get_map_response( return save_path maps = await request.get_maps(map_id) - labels = await request.get_labels(map_id) + trees = await request.get_labels(map_id) # 请求资源ID resource_id = 0 - for label in labels: - for child in label.children: - if resource_name == child.name: - resource_id = child.id - resource_name = child.name + for tree in trees: + for label in tree.children: + if resource_name == label.name: + resource_id = label.id + resource_name = label.name + icon = label.icon break if resource_id == 0: @@ -109,6 +115,7 @@ async def get_map_response( # 转换坐标 transmittable_converted = utils.convert_pos(transmittable, maps.detail.origin) + print(transmittable_converted) # 进行最密点获取 if is_cluster: @@ -167,9 +174,20 @@ async def get_map_response( int(point.x) - int(lt_point.x), int(point.y) - int(lt_point.y), ) - genshin_map.paste( - mark_quest, (point_trans[0] - 16, point_trans[1] - 16), mark_quest - ) + + icon_path = ICON_PATH / f"{resource_name}.png" + if not icon_path.exists(): + await download_file(icon, icon_path) + icon_pic = Image.open(icon_path).resize((52, 52)) + + if point.z <= 3: + mark = Image.open(TEXT_PATH / f"mark_{point.z}.png") + else: + mark = Image.open(TEXT_PATH / f"mark_B.png") + + mark.paste(icon_pic, (25, 17), icon_pic) + + genshin_map.paste(mark, (point_trans[0] - 50, point_trans[1] - 100), mark) # 转换RGB图 genshin_map = genshin_map.convert("RGB") @@ -199,6 +217,7 @@ async def get_map_by_point( if resource_name == a or resource_name in resource_aliases[m][a]: return a return resource_name + # 判断别名 resource_name = resource_aliases_to_name(resource_name) diff --git a/fastapi_genshin_map/GetMapImage/texture2d/mark_0.png b/fastapi_genshin_map/GetMapImage/texture2d/mark_0.png new file mode 100644 index 0000000..6a99d41 Binary files /dev/null and b/fastapi_genshin_map/GetMapImage/texture2d/mark_0.png differ diff --git a/fastapi_genshin_map/GetMapImage/texture2d/mark_1.png b/fastapi_genshin_map/GetMapImage/texture2d/mark_1.png new file mode 100644 index 0000000..9429f91 Binary files /dev/null and b/fastapi_genshin_map/GetMapImage/texture2d/mark_1.png differ diff --git a/fastapi_genshin_map/GetMapImage/texture2d/mark_2.png b/fastapi_genshin_map/GetMapImage/texture2d/mark_2.png new file mode 100644 index 0000000..06a9c29 Binary files /dev/null and b/fastapi_genshin_map/GetMapImage/texture2d/mark_2.png differ diff --git a/fastapi_genshin_map/GetMapImage/texture2d/mark_3.png b/fastapi_genshin_map/GetMapImage/texture2d/mark_3.png new file mode 100644 index 0000000..f155051 Binary files /dev/null and b/fastapi_genshin_map/GetMapImage/texture2d/mark_3.png differ diff --git a/fastapi_genshin_map/GetMapImage/texture2d/mark_B.png b/fastapi_genshin_map/GetMapImage/texture2d/mark_B.png new file mode 100644 index 0000000..19d47a7 Binary files /dev/null and b/fastapi_genshin_map/GetMapImage/texture2d/mark_B.png differ