Coverage for subtractor/pixel.py: 97.50%

30 statements  

« prev     ^ index     » next       coverage.py v7.4.1, created at 2024-02-04 22:33:07 +00:00

1# -*- coding: utf-8 -*- 

2# pylint: disable=c-extension-no-member,expression-not-assigned,line-too-long,logging-fstring-interpolation 

3"""Juggle with pixels.""" 

4import typing 

5 

6import png # type: ignore 

7from PIL import Image # type: ignore 

8from pixelmatch.contrib.PIL import pixelmatch 

9 

10OPTIONS = {'threshold': 0.05} 

11 

12 

13@typing.no_type_check 

14def shape_of_png(path): 

15 """MVP like initial shape reader for PNG from path.""" 

16 try: 

17 with path.open('rb') as handle: 

18 a_png = png.Reader(file=handle) 

19 width, height, _, info = a_png.read() # Ignore the rows iterator 

20 return True, width, height, info 

21 except Exception as err: # pylint: disable=broad-except 

22 return False, None, None, {'error': str(err).replace('\n', '$NL$')} 

23 

24 

25@typing.no_type_check 

26def read_img(path): 

27 """HACK A DID ACK""" 

28 return Image.open(path) 

29 

30 

31@typing.no_type_check 

32def pil_to_flatten_data(img): 

33 """ 

34 Convert data from [(R1, G1, B1, A1), (R2, G2, B2, A2)] to [R1, G1, B1, A1, R2, G2, B2, A2] 

35 """ 

36 return [x for p in img.convert('RGBA').getdata() for x in p] 

37 

38 

39@typing.no_type_check 

40def diff_img(ref, obs, sub): 

41 """Read from ref and obs, calculate the subtraction, output at sub. 

42 

43 Returns the mismatch pixel count, width, and height.""" 

44 img_a = read_img(ref) 

45 img_b = read_img(obs) 

46 width, height = img_a.size 

47 img_diff = Image.new('RGB', (width, height)) 

48 mismatch = pixelmatch(img_a, img_b, img_diff, **OPTIONS) 

49 

50 img_diff.save(sub) 

51 return mismatch, width, height