Approve Shu spearman handpainted sprite v3

This commit is contained in:
2026-07-01 11:06:33 +09:00
parent 199bc47192
commit 513c6ec226
24 changed files with 183 additions and 52 deletions

View File

@@ -23,6 +23,8 @@ REPORT_TITLE = "Shu Infantry Quality Restart Sample v3"
SAMPLE_LABEL = "shu sample"
COMPARE_STEMS = ["unit-liu-bei", "unit-guan-yu", "unit-zhang-fei", "unit-rebel", STEM]
COMPARE_LABELS = ["liu-bei", "guan-yu", "zhang-fei", "rebel", "shu-infantry"]
FIT_WIDTH_SCALE = 1.0
MIN_FRAME_HEIGHT = 0
FRAME = 313
DIRECTIONS = ("south", "east", "north", "west")
BASE_FRAMES_PER_DIRECTION = 16
@@ -186,7 +188,18 @@ def solidify_alpha(image: Image.Image) -> Image.Image:
return Image.fromarray(arr, "RGBA")
def grow_to_minimum_height(subject: Image.Image, max_width: int, max_height: int) -> Image.Image:
if MIN_FRAME_HEIGHT <= 0 or subject.height >= MIN_FRAME_HEIGHT:
return subject
grow = min(max_width / subject.width, max_height / subject.height, MIN_FRAME_HEIGHT / subject.height)
if grow <= 1:
return subject
size = (max(1, round(subject.width * grow)), max(1, round(subject.height * grow)))
return trim_to_alpha(solidify_alpha(subject.resize(size, Image.Resampling.LANCZOS)))
def fit_frame(source: Image.Image, max_width: int, max_height: int, bottom: int = 304, x_offset: int = 0, allow_detached_effects = False) -> Image.Image:
max_width = int(round(max_width * FIT_WIDTH_SCALE))
subject = crop_subject(source, allow_detached_effects)
if subject.width <= 1 or subject.height <= 1:
return Image.new("RGBA", (FRAME, FRAME), (0, 0, 0, 0))
@@ -194,9 +207,11 @@ def fit_frame(source: Image.Image, max_width: int, max_height: int, bottom: int
size = (max(1, round(subject.width * scale)), max(1, round(subject.height * scale)))
subject = solidify_alpha(subject.resize(size, Image.Resampling.LANCZOS))
subject = trim_to_alpha(subject)
subject = grow_to_minimum_height(subject, max_width, max_height)
if not allow_detached_effects:
subject = keep_largest_component(subject)
subject = trim_to_alpha(subject)
subject = grow_to_minimum_height(subject, max_width, max_height)
frame = Image.new("RGBA", (FRAME, FRAME), (0, 0, 0, 0))
x = (FRAME - subject.width) // 2 + x_offset
y = bottom - subject.height
@@ -517,6 +532,8 @@ def parse_args() -> argparse.Namespace:
parser.add_argument("--sample-label", default=SAMPLE_LABEL)
parser.add_argument("--compare-stems", default=",".join(COMPARE_STEMS))
parser.add_argument("--compare-labels", default=",".join(COMPARE_LABELS))
parser.add_argument("--fit-width-scale", type=float, default=FIT_WIDTH_SCALE)
parser.add_argument("--min-frame-height", type=int, default=MIN_FRAME_HEIGHT)
return parser.parse_args()
@@ -524,6 +541,7 @@ def configure(args: argparse.Namespace) -> None:
global SOURCE, WORK_DIR, BATTLE_REFERENCE, STEM, OUTPUT_PREFIX
global CONTACT_TITLE, BEFORE_TITLE, BEFORE_SCALE_LABEL, REPORT_TITLE, SAMPLE_LABEL
global COMPARE_STEMS, COMPARE_LABELS
global FIT_WIDTH_SCALE, MIN_FRAME_HEIGHT
SOURCE = project_path(args.source)
WORK_DIR = project_path(args.work_dir)
@@ -537,6 +555,8 @@ def configure(args: argparse.Namespace) -> None:
SAMPLE_LABEL = args.sample_label
COMPARE_STEMS = split_csv(args.compare_stems)
COMPARE_LABELS = split_csv(args.compare_labels)
FIT_WIDTH_SCALE = args.fit_width_scale
MIN_FRAME_HEIGHT = args.min_frame_height
if len(COMPARE_STEMS) != len(COMPARE_LABELS):
raise ValueError("--compare-stems and --compare-labels must have the same number of entries")

View File

@@ -72,12 +72,12 @@ def write_text_block(draw: ImageDraw.ImageDraw, x: int, y: int, lines: list[str]
draw.text((x, y + index * 21), line, fill=fill, font=small)
def render_board() -> Path:
def render_board() -> Path | None:
manifest = load_json(MANIFEST_PATH)
audit = load_json(AUDIT_PATH)
pending = manifest.get("pendingApproval", [])
if not pending:
raise ValueError("no pendingApproval unit to render")
return None
stem = pending[0]
candidates = manifest.get("currentApprovalCandidate", {})
@@ -151,6 +151,9 @@ def render_board() -> Path:
def main() -> None:
path = render_board()
if path is None:
print("Skipped current approval board: no pendingApproval unit to render")
return
print(f"Wrote {path}")