"""Zuschnitt aufhellen, Untergrund abschneiden, richtig herum drehen.""" import io import numpy as np from PIL import Image from app import imaging, segment from tests.helpers import photo_with_cards def _jpeg(width: int, height: int, color=(255, 255, 255)) -> bytes: buffer = io.BytesIO() Image.new("RGB", (width, height), color).save(buffer, format="JPEG") return buffer.getvalue() def _size(raw: bytes) -> tuple: return Image.open(io.BytesIO(raw)).size def test_drehung_um_null_grad_laesst_die_datei_unangetastet(): raw = _jpeg(40, 20) assert imaging.rotate_jpeg(raw, 0) is raw assert imaging.rotate_jpeg(raw, 360) is raw def test_drehung_um_180_grad_behaelt_das_format(): assert _size(imaging.rotate_jpeg(_jpeg(40, 20), 180)) == (40, 20) def test_drehung_um_90_grad_tauscht_die_seiten(): assert _size(imaging.rotate_jpeg(_jpeg(40, 20), 90)) == (20, 40) assert _size(imaging.rotate_jpeg(_jpeg(40, 20), 270)) == (20, 40) def test_drehrichtung_ist_im_uhrzeigersinn(): # Oben links schwarz: nach 90 Grad im Uhrzeigersinn liegt es oben rechts. image = np.full((20, 40, 3), 255, dtype=np.uint8) image[:10, :20] = 0 buffer = io.BytesIO() Image.fromarray(image).save(buffer, format="PNG") gedreht = np.asarray( Image.open(io.BytesIO(imaging.rotate_jpeg(buffer.getvalue(), 90))) ) assert gedreht[:10, -10:].mean() < 60 # oben rechts jetzt dunkel assert gedreht[:10, :10].mean() > 195 # oben links jetzt hell def test_helle_karte_wird_aufgehellt(): # Karte mit Helligkeitsverlauf, wie ihn schraeges Licht erzeugt. verlauf = np.linspace(150, 225, 400, dtype=np.float32) karte = np.repeat(verlauf[None, :, None], 250, axis=0).repeat(3, axis=2) karte = karte.astype(np.uint8) aufgehellt = segment.flatten(karte) assert aufgehellt.mean() > karte.mean() + 20 # Der Verlauf ist danach deutlich flacher als vorher. vorher = float(karte[:, -1].mean() - karte[:, 0].mean()) nachher = float(aufgehellt[:, -1].mean() - aufgehellt[:, 0].mean()) assert nachher < vorher / 2 def test_dunkle_karte_bleibt_dunkel(): dunkel = np.full((250, 400, 3), 40, dtype=np.uint8) assert np.array_equal(segment.flatten(dunkel), dunkel) def test_zuschnitt_laesst_den_untergrund_draussen(): # Der Untergrund im Testfoto ist dunkel. Bleibt ein Streifen davon im # Zuschnitt, waeren die Randspalten deutlich dunkler als die Mitte. crops, _ = segment.segment(photo_with_cards(count=4)) for crop in crops: rand = np.concatenate([crop[:, :3], crop[:, -3:]], axis=1) assert rand.mean() > 170 def test_einzug_zieht_die_ecken_zur_mitte(): quad = np.array([[0, 0], [100, 0], [100, 100], [0, 100]], dtype="float32") kleiner = segment._shrink(quad, factor=0.1) assert kleiner[0][0] > quad[0][0] assert kleiner[2][0] < quad[2][0] assert np.allclose(kleiner.mean(axis=0), quad.mean(axis=0))