From 432ea936fbe094784efa0649d0a0003ccbdfc9b1 Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Wed, 27 Jul 2022 21:25:02 -0300 Subject: Add a helper to add units en-masse. Next is the SDK --- README | 13 +++++++- units.py | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 1 deletion(-) create mode 100755 units.py diff --git a/README b/README index 75a72a6..50abb68 100644 --- a/README +++ b/README @@ -50,5 +50,16 @@ pip3 install pillow opencv-python``` Image name should be the faction + monster ID. Model `FFMM`. So an imperial spearman is named `0001` and an arch wizard is named `0701`. Attribution template is sent to ATTR.txt for convenience - +* units.py + * Based in "ready-units" folder, using semi-qualified name (e.g. 1002 - 1 star, + unit 2; The "10" prefix and 0x suffix is not needed). Resizes image to 640x960 + and finds a face, which is then centered and a square is produced, then the + three image slices are made. Accepts PNG and JPG input, output is Webp. + If there is a image with same name but "sq_" prefix, it's used instead of face + detection tool. The output is saved in square/ and unit/ subfolder + * Structure: + ready-units/ + unit/ + square/ + base/ ← Save your images here diff --git a/units.py b/units.py new file mode 100755 index 0000000..8cdbba7 --- /dev/null +++ b/units.py @@ -0,0 +1,115 @@ +#!/usr/bin/python3 + +import os, subprocess, cv2 + +# This is a much more complex script. BY ALL MEANS use base folder + +pwd = os.getcwd() +f = open("ATTR.txt", "w") +bf1=[] +subprocess.call("cp ready-units/base/* ready-units/", shell=True) +FILES = list(os.listdir(pwd + "/ready-units")) + +for it in FILES: + if not it.endswith("png") and not it.endswith("jpg"): + continue + if it.startswith("sq_"): + continue + + name = it.split(".")[0] + path = pwd + "/ready-units/" + sqne = "sq_%s" % it + + try: + unitid = int(name) + except: + print("ERROR: %s is not parseable" % it) + continue + + print("%s" % it) + + """ + # Force to PNG + if it.endswith("jpg"): + # WARNING: DESTRUCTIVE + subprocess.call("convert %s/%s %s/%s.png" % (path, it, path, it), shell=True) + subprocess.call("rm %s/%s" % (path, it), shell=True) + it = "%s.png" % it + """ + + # Resizing + img = cv2.imread(path+it) + w, h = img.shape[:2] + if h != 640 or w != 960: + # Resize the image, relying entirely in ImageMagick + # Preserving aspect ratio is turned OFF (Crop would be better) + # WARNING: DESTRUCTIVE + subprocess.call("convert %s/%s -resize 640x960\! %s/%s" % (path, it, path, it), shell=True) + print("[OK] Image resized") + + # A square doesn't exists + # Generate one with opencv + if not sqne in FILES: + cPath="lbpcascade_animeface.xml" + iPath="ready-units/%s" % it + cascade=cv2.CascadeClassifier(cPath) + org_img=cv2.imread(iPath) + img=cv2.cvtColor(org_img, cv2.COLOR_BGR2GRAY) + maxi = 3.2 + step = 0.1 + curr = 1.0 + faces = [] + # Detect faces + while len(faces) != 1: + if curr == 1.0: + faces = cascade.detectMultiScale(img, scaleFactor=1.01, minNeighbors=5) + else: + faces = cascade.detectMultiScale(img, scaleFactor=curr, minNeighbors=5) + curr+=step + if curr > maxi: + break + + if len(faces) != 1: + print("\033[1mERROR: %s has %d faces, no square possible!\033[0m" % (it, len(faces))) + bf1.append("* ERROR: %s needs a square\n" % it) + continue + + face=faces[0] + + # Calculate offset + xoff=max(0, 340-face[2])/2 + yoff=max(0, 340-face[3])/2 + + x=max(0, face[0]-xoff) + y=max(0, face[1]-yoff) + + subprocess.call("convert %s -crop %dx%d+%d+%d %s/%s" % (iPath, 340, 340, x, y, path, sqne), shell=True) + print("[OK] Success finding face at (%d,%d)" % (x, y)) + + # Resize the squared image (DESTRUCTIVE) + # FIXME: Add alpha channel + subprocess.call("convert %s/%s -resize 340x340\! -alpha on %s/%s.png" % (path, sqne, path, sqne), shell=True) + + # Format the squared image (DESTRUCTIVE) + subprocess.call("convert %s/%s.png mask.png -alpha off -compose CopyOpacity -composite %s/%s.webp" % (path, sqne, path, sqne), shell=True) + sqne+=".webp" + + # Make copies + i=0 + while i < 3: + subprocess.call("convert %s/%s %s/unit/10%04d%02d.webp" % (path, it, path, unitid, i), shell=True) + subprocess.call("convert %s/%s %s/square/10%04d%02d.webp" % (path, sqne, path, unitid, i), shell=True) + i+=1 + + # Save to attribution + bf1.append("\t10%04d NAME (AUTHOR)\t(CC BY SA)\t(SOURCE)\n" % (unitid)) + +# Save attribution file +for it in sorted(bf1): + f.write(it) +f.close() + +# Remove the working files +# IF YOU DID NOT USE BASE FOLDER, CONSIDER THE FILES FORSAKEN +subprocess.call("rm ready-units/*.*", shell=True) + -- cgit v1.2.3-60-g2f50