diff --git a/bin/compare_them_all.py b/bin/compare_them_all.py new file mode 100644 index 0000000..ad0be63 --- /dev/null +++ b/bin/compare_them_all.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- +# +# Compare desktop/mobile shots of all themes from publik-base-theme. +# +# Usage: +# --input1-directory -- directory to find version 1 screenshots +# --input2-directory -- directory to find version 2 screenshots +# --output-directory DIRECTORY -- directory to store comparison results, defaults to results/ +# --overlay OVERLAY -- limit to given overlay ("none" to exclude overlays) +# --theme THEME -- theme to shot (substring match) +# +# Example: +# hobo-manage tenant_command runscript compare_them_all.py -d hobo.fred.local.0d.be +# + +import argparse +import os +import sys +from hobo.theme.utils import get_themes +from django.template import Template, Context +from PIL import Image, ImageDraw + +parser = argparse.ArgumentParser() +parser.add_argument('--input1-directory', dest='input1_directory', type=str, required=True) +parser.add_argument('--input2-directory', dest='input2_directory', type=str, required=True) +parser.add_argument('--output-directory', dest='output_directory', type=str, default='results') +parser.add_argument('--overlay', dest='overlay', type=str, default='none') +parser.add_argument('--theme', dest='theme', type=str) +args = parser.parse_args() + +if not os.path.exists(args.output_directory): + os.mkdir(args.output_directory) + + +result = [] + +for theme in get_themes(): + theme_id = theme['id'] + if args.overlay == 'all': + pass + elif args.overlay == 'none' and not theme.get('overlay'): + pass + elif args.overlay == theme.get('overlay'): + pass + else: + continue + if args.theme and args.theme not in theme['id']: + continue + sys.stderr.write("%-25s" % theme_id) + shots = [ + 'desktop', + 'mobile', + 'mobile-horizontal', + ] + + def process_region(image, x, y, width, height): + region_total = 0 + # This can be used as the sensitivity factor, the larger it is the less sensitive the comparison + factor = 100 + for coordinate_y in range(y, y + height): + for coordinate_x in range(x, x + width): + try: + pixel = image.getpixel((coordinate_x, coordinate_y)) + region_total += sum(pixel) / 4 + except Exception: + return + return region_total / factor + + theme_data = { + 'label': theme['label'], + 'shots': [], + } + + for shot in shots: + filepath_1 = os.path.join(args.input1_directory, '%s-%s.png' % (theme_id, shot)) + filepath_2 = os.path.join(args.input2_directory, '%s-%s.png' % (theme_id, shot)) + filepath_output = os.path.join(args.output_directory, '%s-%s.png' % (theme_id, shot)) + try: + screenshot_1 = Image.open(filepath_1) + screenshot_2 = Image.open(filepath_2) + except FileNotFoundError: + continue + width, height = screenshot_1.size + + columns = 60 + rows = 80 + screen_width, screen_height = screenshot_1.size + + block_width = ((screen_width - 1) // columns) + 1 + block_height = ((screen_height - 1) // rows) + 1 + + for y in range(0, screen_height, block_height + 1): + for x in range(0, screen_width, block_width + 1): + region_1 = process_region(screenshot_1, x, y, block_width, block_height) + region_2 = process_region(screenshot_2, x, y, block_width, block_height) + + if region_1 is not None and region_2 is not None and region_1 != region_2: + draw = ImageDraw.Draw(screenshot_1) + draw.rectangle((x, y, x + block_width, y + block_height), outline="red") + + screenshot_1.save(filepath_output) + theme_data['shots'].append({ + 'label': shot, + 'width': width, + 'height': height, + 'before': '../%s' % filepath_1, + 'after': '../%s' % filepath_2, + 'diff': '../%s' % filepath_output, + }) + result.append(theme_data) + +sys.stderr.write(u'\n') + +with open('index_template.html', 'r') as f: + template = Template(f.read()) + context = Context({'themes': result}) + html = template.render(context) + +with open(os.path.join(args.output_directory, 'index.html'), 'w') as f: + f.write(html) diff --git a/bin/index_template.html b/bin/index_template.html new file mode 100644 index 0000000..7db64f6 --- /dev/null +++ b/bin/index_template.html @@ -0,0 +1,26 @@ + + +
+ + + + + {% for theme in themes %} +