92 lines
5.4 KiB
Python
92 lines
5.4 KiB
Python
import sys
|
|
from pathlib import Path
|
|
import tempfile
|
|
import unittest
|
|
import numpy as np
|
|
from PIL import Image, ImageDraw
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
from finish_masks import IllustrationCoverage, compile_finish, export_finish, extract_raw_ridges, prepare_illustration
|
|
|
|
class RidgeBehavior(unittest.TestCase):
|
|
def test_uniform_dark_glass_is_not_a_divider(self):
|
|
self.assertFalse(extract_raw_ridges(Image.new('RGB', (128, 128), (28, 28, 28))).any())
|
|
|
|
def test_dark_colored_seams_and_no_opposite_edge_wrap(self):
|
|
im = Image.new('RGB', (160, 160), (145, 145, 145)); d = ImageDraw.Draw(im)
|
|
d.rectangle((75, 0, 81, 159), fill=(35, 48, 82))
|
|
confidence = extract_raw_ridges(im)
|
|
self.assertGreater(int(confidence[80, 78]), 50)
|
|
im = Image.new('RGB', (160, 160), (145, 145, 145));ImageDraw.Draw(im).rectangle((0, 0, 6, 159), fill=(10, 10, 10))
|
|
self.assertFalse(extract_raw_ridges(im)[:, 140:].any())
|
|
|
|
def test_both_sides_required_for_shadow_step(self):
|
|
im = Image.new('RGB', (160, 160), (145, 145, 145));ImageDraw.Draw(im).rectangle((45, 0, 114, 159), fill=(10, 10, 10))
|
|
confidence = extract_raw_ridges(im)
|
|
self.assertEqual(int(confidence[80, 45]), 0)
|
|
self.assertEqual(int(confidence[80, 80]), 0)
|
|
|
|
def test_master_fit_is_explicit(self):
|
|
with self.assertRaises(ValueError): prepare_illustration(Image.new('RGB', (1000, 1400)))
|
|
|
|
class PrintingComposition(unittest.TestCase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.panes = np.full((2800, 2000), .8, dtype=np.float32)
|
|
cls.ridges = np.zeros((2800, 2000), dtype=np.uint8);cls.ridges[:, 1000] = 255
|
|
cls.illustration = IllustrationCoverage(cls.panes, cls.ridges)
|
|
cls.frame = Image.new('RGBA', (2000, 2800));ImageDraw.Draw(cls.frame).rectangle((0, 0, 1999, 2799), outline=(0, 0, 0, 255), width=24)
|
|
cls.backing = Image.new('RGBA', (2000, 2800));d = ImageDraw.Draw(cls.backing)
|
|
d.rectangle((300, 60, 1700, 360), fill=(0, 0, 0, 255));d.rectangle((300, 2180, 1700, 2730), fill=(0, 0, 0, 255))
|
|
cls.normal_overlay = Image.alpha_composite(cls.frame, cls.backing)
|
|
cls.text = Image.new('RGBA', (2000, 2800));ImageDraw.Draw(cls.text).rectangle((850, 180, 900, 220), fill=(0, 0, 0, 255))
|
|
|
|
def masks(self):
|
|
return {'normal': compile_finish(self.illustration, 'normal', self.normal_overlay, self.text),
|
|
'textless': compile_finish(self.illustration, 'textless', self.frame),
|
|
'borderless': compile_finish(self.illustration, 'borderless', self.backing, self.text),
|
|
'boundless': compile_finish(self.illustration, 'boundless')}
|
|
|
|
def test_removed_layers_restore_only_their_protection(self):
|
|
masks = {k: np.asarray(v) for k, v in self.masks().items()}
|
|
self.assertEqual(int(masks['normal'][200, 870]), 0)
|
|
self.assertEqual(int(masks['borderless'][200, 870]), 0)
|
|
self.assertEqual(int(masks['textless'][200, 870]), 204)
|
|
self.assertEqual(int(masks['boundless'][200, 870]), 204)
|
|
self.assertEqual(int(masks['normal'][0, 0]), 0)
|
|
self.assertEqual(int(masks['textless'][0, 0]), 0)
|
|
self.assertEqual(int(masks['borderless'][0, 0]), 204)
|
|
self.assertEqual(int(masks['boundless'][0, 0]), 204)
|
|
for mask in masks.values(): self.assertFalse(mask[:, 1000].any())
|
|
|
|
def test_actual_alpha_union_and_detached_glyphs(self):
|
|
overlay = Image.new('RGBA', (2000, 2800));text = Image.new('RGBA', (2000, 2800))
|
|
overlay.putpixel((123, 456), (0, 0, 0, 128));text.putpixel((123, 456), (0, 0, 0, 128))
|
|
text.putpixel((456, 789), (0, 0, 0, 255))
|
|
mask = np.asarray(compile_finish(self.illustration, 'borderless', overlay, text))
|
|
self.assertEqual(int(mask[456, 123]), 51)
|
|
self.assertEqual(int(mask[789, 456]), 0)
|
|
self.assertEqual(int(mask[790, 456]), 204)
|
|
|
|
def test_invalid_component_contracts_fail(self):
|
|
for printing, overlay, text in [('normal', self.frame, None), ('textless', self.frame, self.text),
|
|
('boundless', self.frame, None), ('borderless', None, self.text),
|
|
('normal', Image.new('RGB', (2000, 2800)), self.text),
|
|
('normal', Image.new('RGBA', (1000, 1400)), self.text),
|
|
('normal', Image.new('RGBA', (2000, 2800)), self.text)]:
|
|
with self.subTest(printing=printing), self.assertRaises(ValueError):
|
|
compile_finish(self.illustration, printing, overlay, text)
|
|
|
|
def test_all_printing_exports_are_registered_opaque_scalars(self):
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
for printing, master in self.masks().items():
|
|
files = export_finish(master, Path(temporary), 'probe', printing)
|
|
self.assertEqual([f['size'] for f in files], [[2000, 2800], [1000, 1400], [500, 700]])
|
|
for record in files:
|
|
rgba = np.asarray(Image.open(record['path']))
|
|
self.assertTrue(np.all(rgba[:, :, 3] == 255))
|
|
self.assertTrue(np.array_equal(rgba[:, :, 0], rgba[:, :, 1]))
|
|
self.assertTrue(np.array_equal(rgba[:, :, 0], rgba[:, :, 2]))
|
|
if printing in ('normal', 'textless'): self.assertEqual(int(rgba[0, 0, 0]), 0)
|
|
|
|
if __name__ == '__main__': unittest.main()
|