93 lines
3.2 KiB
Python
93 lines
3.2 KiB
Python
import sys
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
from PIL import Image
|
|
|
|
SCRIPTS = Path(__file__).resolve().parents[1] / "scripts"
|
|
sys.path.insert(0, str(SCRIPTS))
|
|
|
|
from build_scroll_skins import build_asset, remove_chroma_background, sanitize_output_edges, stretch_safe_center
|
|
|
|
|
|
class BuildScrollSkinsTests(unittest.TestCase):
|
|
def setUp(self):
|
|
self.directory = tempfile.TemporaryDirectory()
|
|
self.addCleanup(self.directory.cleanup)
|
|
self.root = Path(self.directory.name)
|
|
|
|
def test_chroma_background_becomes_transparent_black(self):
|
|
image = Image.new("RGB", (4, 2), (0, 255, 0))
|
|
image.putpixel((1, 0), (180, 30, 20))
|
|
|
|
cleaned = remove_chroma_background(image, (0, 255, 0), tolerance=80)
|
|
|
|
self.assertEqual((0, 0, 0, 0), cleaned.getpixel((0, 0)))
|
|
self.assertEqual((180, 30, 20, 255), cleaned.getpixel((1, 0)))
|
|
|
|
def test_safe_center_stretch_preserves_caps_and_exact_size(self):
|
|
image = Image.new("RGBA", (30, 10), (150, 20, 10, 255))
|
|
for y in range(10):
|
|
for x in range(5):
|
|
image.putpixel((x, y), (220, 170, 40, 255))
|
|
image.putpixel((29 - x, y), (220, 170, 40, 255))
|
|
|
|
output = stretch_safe_center(
|
|
image,
|
|
output_size=(60, 20),
|
|
cap_width=5,
|
|
padding=2,
|
|
)
|
|
|
|
self.assertEqual((60, 20), output.size)
|
|
self.assertEqual((0, 0, 0, 0), output.getpixel((0, 0)))
|
|
self.assertEqual((220, 170, 40, 255), output.getpixel((3, 10)))
|
|
self.assertEqual((150, 20, 10, 255), output.getpixel((30, 10)))
|
|
self.assertEqual((220, 170, 40, 255), output.getpixel((56, 10)))
|
|
|
|
def test_sanitizes_only_forbidden_edge_artifacts(self):
|
|
image = Image.new("RGBA", (3, 1), (248, 240, 220, 255))
|
|
image.putpixel((0, 0), (0, 255, 0, 128))
|
|
image.putpixel((1, 0), (250, 250, 250, 96))
|
|
|
|
cleaned = sanitize_output_edges(image)
|
|
|
|
self.assertEqual((0, 0, 0, 0), cleaned.getpixel((0, 0)))
|
|
self.assertEqual((0, 0, 0, 0), cleaned.getpixel((1, 0)))
|
|
self.assertEqual((248, 240, 220, 255), cleaned.getpixel((2, 0)))
|
|
|
|
def test_build_asset_honors_declared_palette_size(self):
|
|
source = Image.new("RGB", (32, 16), (0, 255, 0))
|
|
for y in range(1, 15):
|
|
for x in range(1, 31):
|
|
source.putpixel((x, y), (120 + (x % 30) * 4, 20 + y, 10))
|
|
source_path = self.root / "source.png"
|
|
output_path = self.root / "output.png"
|
|
source.save(source_path)
|
|
asset = {
|
|
"id": "palette-test",
|
|
"source": "source.png",
|
|
"output": "output.png",
|
|
"outputPixels": {"width": 60, "height": 30},
|
|
"alpha": {"transparentOuterPadding": 1},
|
|
"processing": {
|
|
"capWidth": 4,
|
|
"keyColor": "#00FF00",
|
|
"keyTolerance": 80,
|
|
"paletteColors": 8,
|
|
},
|
|
}
|
|
|
|
build_asset(asset, self.root)
|
|
|
|
with Image.open(output_path) as output:
|
|
visible_colors = {
|
|
pixel[:3] for pixel in output.convert("RGBA").get_flattened_data() if pixel[3] > 0
|
|
}
|
|
self.assertLessEqual(len(visible_colors), 8)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|