2020-03-28 17:22:46 +00:00
|
|
|
import os
|
|
|
|
|
|
|
|
import numpy as np
|
|
|
|
from PIL import Image
|
|
|
|
|
|
|
|
from module.base.button import get_color
|
|
|
|
from module.config.config import AzurLaneConfig
|
|
|
|
from module.logger import logger
|
|
|
|
|
|
|
|
MODULE_FOLDER = './module'
|
|
|
|
BUTTON_FILE = 'assets.py'
|
|
|
|
IMPORT_EXP = """
|
|
|
|
from module.base.button import Button
|
|
|
|
from module.base.template import Template
|
|
|
|
|
|
|
|
# This file is generated by module.dev_tools.asset_extract.
|
|
|
|
# Don't modified it manually.
|
|
|
|
"""
|
|
|
|
IMPORT_EXP = IMPORT_EXP.strip().split('\n') + ['']
|
2020-06-04 14:40:59 +00:00
|
|
|
VALID_SERVER = ['cn', 'en', 'jp']
|
2020-03-28 17:22:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ImageExtractor:
|
|
|
|
def __init__(self, module, file, config):
|
|
|
|
"""
|
|
|
|
Args:
|
|
|
|
module(str):
|
|
|
|
file(str): xxx.png
|
|
|
|
config(AzurLaneConfig):
|
|
|
|
"""
|
|
|
|
self.module = module
|
|
|
|
self.name = os.path.splitext(file)[0]
|
|
|
|
self.config = config
|
2020-05-25 14:05:42 +00:00
|
|
|
self.area, self.color, self.button, self.file = {}, {}, {}, {}
|
|
|
|
for server in VALID_SERVER:
|
|
|
|
self.load(server)
|
2020-03-28 17:22:46 +00:00
|
|
|
|
2020-05-25 14:05:42 +00:00
|
|
|
def get_file(self, genre='', server='cn'):
|
2020-03-28 17:22:46 +00:00
|
|
|
file = '%s.%s.png' % (self.name, genre) if genre else '%s.png' % self.name
|
2020-05-25 14:05:42 +00:00
|
|
|
file = os.path.join(self.config.ASSETS_FOLDER, server, self.module, file)
|
2020-03-28 17:22:46 +00:00
|
|
|
return file
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def extract(file):
|
|
|
|
image = Image.open(file).convert('RGB')
|
2020-06-11 16:02:54 +00:00
|
|
|
if image.size != (1280, 720):
|
|
|
|
logger.warning(f'Incorrect asset {image.size} {file}')
|
2020-03-28 17:22:46 +00:00
|
|
|
bbox = image.getbbox()
|
|
|
|
mean = get_color(image=image, area=bbox)
|
|
|
|
mean = tuple(np.rint(mean).astype(int))
|
|
|
|
return bbox, mean
|
|
|
|
|
2020-05-25 14:05:42 +00:00
|
|
|
def load(self, server='cn'):
|
|
|
|
if os.path.exists(self.get_file(server=server)):
|
|
|
|
area, color = self.extract(self.get_file(server=server))
|
|
|
|
button = area
|
|
|
|
if os.path.exists(self.get_file('AREA', server=server)):
|
|
|
|
area, _ = self.extract(self.get_file('AREA', server=server))
|
|
|
|
if os.path.exists(self.get_file('COLOR', server=server)):
|
|
|
|
_, color = self.extract(self.get_file('COLOR', server=server))
|
|
|
|
if os.path.exists(self.get_file('BUTTON', server=server)):
|
|
|
|
button, _ = self.extract(self.get_file('BUTTON', server=server))
|
|
|
|
|
|
|
|
self.area[server] = area
|
|
|
|
self.color[server] = color
|
|
|
|
self.button[server] = button
|
|
|
|
self.file[server] = f"{self.config.ASSETS_FOLDER}/{server}/{self.module}/{self.name}.png"
|
|
|
|
else:
|
|
|
|
logger.attr(server, f'{self.name} not found, use cn server assets')
|
|
|
|
self.area[server] = self.area['cn']
|
|
|
|
self.color[server] = self.color['cn']
|
|
|
|
self.button[server] = self.button['cn']
|
|
|
|
self.file[server] = self.file['cn']
|
2020-03-28 17:22:46 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def expression(self):
|
2020-05-25 14:05:42 +00:00
|
|
|
return '%s = Button(area=%s, color=%s, button=%s, file=%s)' % (
|
|
|
|
self.name, self.area, self.color, self.button, self.file)
|
2020-03-28 17:22:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
class TemplateExtractor(ImageExtractor):
|
|
|
|
# def __init__(self, module, file, config):
|
|
|
|
# """
|
|
|
|
# Args:
|
|
|
|
# module(str):
|
|
|
|
# file(str): xxx.png
|
|
|
|
# config(AzurLaneConfig):
|
|
|
|
# """
|
|
|
|
# self.module = module
|
|
|
|
# self.file = file
|
|
|
|
# self.config = config
|
2020-06-11 16:02:54 +00:00
|
|
|
@staticmethod
|
|
|
|
def extract(file):
|
|
|
|
image = Image.open(file).convert('RGB')
|
|
|
|
bbox = image.getbbox()
|
|
|
|
mean = get_color(image=image, area=bbox)
|
|
|
|
mean = tuple(np.rint(mean).astype(int))
|
|
|
|
return bbox, mean
|
2020-03-28 17:22:46 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def expression(self):
|
2020-05-25 14:05:42 +00:00
|
|
|
return '%s = Template(file=%s)' % (
|
|
|
|
self.name, self.file)
|
2020-04-09 08:30:40 +00:00
|
|
|
# return '%s = Template(area=%s, color=%s, button=%s, file=\'%s\')' % (
|
|
|
|
# self.name, self.area, self.color, self.button,
|
|
|
|
# self.config.ASSETS_FOLDER + '/' + self.module + '/' + self.name + '.png')
|
2020-03-28 17:22:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
# class OcrExtractor(ImageExtractor):
|
|
|
|
# @property
|
|
|
|
# def expression(self):
|
|
|
|
# return '%s = OcrArea(area=%s, color=%s, button=%s, file=\'%s\')' % (
|
|
|
|
# self.name, self.area, self.color, self.button,
|
|
|
|
# self.config.ASSETS_FOLDER + '/' + self.module + '/' + self.name + '.png')
|
|
|
|
|
|
|
|
|
|
|
|
class ModuleExtractor:
|
|
|
|
def __init__(self, name, config):
|
|
|
|
self.name = name
|
|
|
|
self.config = config
|
2020-05-25 14:05:42 +00:00
|
|
|
self.folder = os.path.join(self.config.ASSETS_FOLDER, 'cn', name)
|
2020-03-28 17:22:46 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def split(file):
|
|
|
|
name, ext = os.path.splitext(file)
|
|
|
|
name, sub = os.path.splitext(name)
|
|
|
|
return name, sub, ext
|
|
|
|
|
|
|
|
def is_base_image(self, file):
|
|
|
|
_, sub, _ = self.split(file)
|
|
|
|
return sub == ''
|
|
|
|
|
|
|
|
@property
|
|
|
|
def expression(self):
|
|
|
|
exp = []
|
|
|
|
for file in os.listdir(self.folder):
|
|
|
|
if file[0].isdigit():
|
|
|
|
continue
|
|
|
|
if file.startswith('TEMPLATE_'):
|
|
|
|
exp.append(TemplateExtractor(module=self.name, file=file, config=self.config).expression)
|
|
|
|
continue
|
|
|
|
# if file.startswith('OCR_'):
|
|
|
|
# exp.append(OcrExtractor(module=self.name, file=file, config=self.config).expression)
|
|
|
|
# continue
|
|
|
|
if self.is_base_image(file):
|
|
|
|
exp.append(ImageExtractor(module=self.name, file=file, config=self.config).expression)
|
|
|
|
continue
|
|
|
|
|
|
|
|
logger.info('Module: %s(%s)' % (self.name, len(exp)))
|
|
|
|
exp = IMPORT_EXP + exp
|
|
|
|
return exp
|
|
|
|
|
|
|
|
def write(self):
|
|
|
|
folder = os.path.join(MODULE_FOLDER, self.name)
|
|
|
|
if not os.path.exists(folder):
|
|
|
|
os.mkdir(folder)
|
|
|
|
with open(os.path.join(folder, BUTTON_FILE), 'w') as f:
|
|
|
|
for text in self.expression:
|
|
|
|
f.write(text + '\n')
|
|
|
|
|
|
|
|
|
|
|
|
class AssetExtractor:
|
|
|
|
"""
|
|
|
|
Extract Asset to asset.py.
|
|
|
|
All the filename of assets should be in uppercase.
|
|
|
|
|
|
|
|
Asset name starts with digit will be ignore.
|
|
|
|
E.g. 2020XXXX.png.
|
|
|
|
Asset name starts with 'TEMPLATE_' will treat as template.
|
|
|
|
E.g. TEMPLATE_AMBUSH_EVADE_SUCCESS.png
|
|
|
|
> TEMPLATE_AMBUSH_EVADE_SUCCESS = Template(file='./assets/handler/TEMPLATE_AMBUSH_EVADE_SUCCESS.png')
|
|
|
|
Asset name starts other will treat as button.
|
|
|
|
E.g. GET_MISSION.png
|
|
|
|
> Button(area=(553, 482, 727, 539), color=(93, 142, 203), button=(553, 482, 727, 539), name='GET_MISSION')
|
|
|
|
Asset name like XXX.AREA.png, XXX.COLOR.png, XXX.BUTTON.png, will overwrite the attribute of XXX.png.
|
|
|
|
E.g. BATTLE_STATUS_S.BUTTON.png overwrites the attribute 'button' of BATTLE_STATUS_S
|
|
|
|
Asset name starts with 'OCR_' will be treat as button.
|
|
|
|
E.g. OCR_EXERCISE_TIMES.png.
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self, config):
|
|
|
|
logger.info('Assets extract')
|
2020-05-25 14:05:42 +00:00
|
|
|
|
|
|
|
for module in os.listdir(config.ASSETS_FOLDER + '/cn'):
|
|
|
|
if os.path.isdir(os.path.join(config.ASSETS_FOLDER + '/cn', module)):
|
2020-03-28 17:22:46 +00:00
|
|
|
me = ModuleExtractor(name=module, config=config)
|
|
|
|
me.write()
|
|
|
|
|
2020-05-26 18:42:25 +00:00
|
|
|
if __name__ == '__main__':
|
|
|
|
ae = AssetExtractor(AzurLaneConfig('template'))
|