diff --git a/src/diffenator2/__init__.py b/src/diffenator2/__init__.py index 98da207..4f00787 100644 --- a/src/diffenator2/__init__.py +++ b/src/diffenator2/__init__.py @@ -141,6 +141,7 @@ def ninja_diff( ), command="diff", diffbrowsers_templates=[], + debug_gifs: bool = False, **kwargs ): args = { diff --git a/src/diffenator2/__main__.py b/src/diffenator2/__main__.py index f0f2668..99e1986 100644 --- a/src/diffenator2/__main__.py +++ b/src/diffenator2/__main__.py @@ -67,6 +67,9 @@ def main(**kwargs): diff_parser.add_argument( "--no-words", action="store_true", help="Skip diffing wordlists" ) + diff_parser.add_argument( + "--debug-gifs", action="store_true", help="Generate debug gifs" + ) parser.add_argument( "--diffenator-template", default=resource_filename( diff --git a/src/diffenator2/_diffenator.py b/src/diffenator2/_diffenator.py index cde8385..2ddba63 100755 --- a/src/diffenator2/_diffenator.py +++ b/src/diffenator2/_diffenator.py @@ -22,7 +22,7 @@ class DiffFonts: - def __init__(self, matcher, threshold=0.01, font_size=28, words=True, tables=True): + def __init__(self, matcher, threshold=0.01, font_size=28, words=True, tables=True, debug_gifs=False): self.old_font = matcher.old_fonts[0] self.new_font = matcher.new_fonts[0] @@ -32,6 +32,7 @@ def __init__(self, matcher, threshold=0.01, font_size=28, words=True, tables=Tru self.do_words = words self.do_tables = tables self.font_size = font_size + self.debug_gifs = debug_gifs def diff_all(self): self.diff_tables() @@ -59,6 +60,7 @@ def diff_words(self): threshold=self.threshold, do_words=self.do_words, font_size=self.font_size, + debug_gifs=self.debug_gifs, ) def filter_characters(self, characters): @@ -102,7 +104,8 @@ def main(): words=not args.no_words, tables=not args.no_tables, threshold=args.threshold, - font_size=args.font_size + font_size=args.font_size, + debug_gifs=args.debug_gifs, ) diff.diff_all() if args.user_wordlist: diff --git a/src/diffenator2/renderer.py b/src/diffenator2/renderer.py index 17618a0..4f29f7b 100644 --- a/src/diffenator2/renderer.py +++ b/src/diffenator2/renderer.py @@ -12,6 +12,7 @@ from blackrenderer.backends import getSurfaceClass from PIL import Image, ImageOps, ImageChops from diffenator2.font import DFont +from diffenator2.utils import gen_gif import numpy as np import freetype as ft from dataclasses import dataclass, field @@ -245,6 +246,15 @@ def diff(self, string): self.img_b = Image.fromarray(img_b) return pc, diff_map + def debug_gif(self, fp): + img_a = self.img_a.convert('RGBA') + img_a_background = Image.new('RGBA', img_a.size, (255,255,255)) + img_a = Image.alpha_composite(img_a_background, img_a) + img_b = self.img_b.convert('RGBA') + img_b_background = Image.new('RGBA', img_b.size, (255,255,255)) + img_b = Image.alpha_composite(img_b_background, img_b) + gen_gif(img_a, img_b, fp) + if __name__ == "__main__": parser = argparse.ArgumentParser(description="Draw some text") diff --git a/src/diffenator2/shape.py b/src/diffenator2/shape.py index 3714fdf..98423ba 100644 --- a/src/diffenator2/shape.py +++ b/src/diffenator2/shape.py @@ -8,6 +8,7 @@ from diffenator2 import THRESHOLD from diffenator2.renderer import FONT_SIZE, PixelDiffer from diffenator2.template_elements import Word, WordDiff, Glyph, GlyphDiff +from diffenator2.utils import gen_gif from pkg_resources import resource_filename import tqdm from diffenator2.segmenting import textSegments @@ -46,12 +47,12 @@ class GlyphItems: modified: list -def test_fonts(font_a, font_b, threshold=THRESHOLD, do_words=True, font_size=FONT_SIZE): +def test_fonts(font_a, font_b, threshold=THRESHOLD, do_words=True, font_size=FONT_SIZE, debug_gifs=False): glyphs = test_font_glyphs(font_a, font_b, threshold=threshold, font_size=font_size) skip_glyphs = glyphs.missing + glyphs.new if do_words: words = test_font_words( - font_a, font_b, skip_glyphs, threshold=threshold, font_size=font_size + font_a, font_b, skip_glyphs, threshold=threshold, font_size=font_size, debug_gifs=debug_gifs ) else: words = {} @@ -82,7 +83,7 @@ def test_font_glyphs(font_a, font_b, threshold=THRESHOLD, font_size=FONT_SIZE): def test_font_words( - font_a, font_b, skip_glyphs=set(), threshold=THRESHOLD, font_size=FONT_SIZE + font_a, font_b, skip_glyphs=set(), threshold=THRESHOLD, font_size=FONT_SIZE, debug_gifs=False ): from youseedee import ucd_data from collections import defaultdict @@ -111,6 +112,7 @@ def test_font_words( skip_glyphs, threshold=threshold, font_size=font_size, + debug_gifs=debug_gifs, ) return res @@ -149,6 +151,7 @@ def test_words( hash_func=gid_pos_hash, threshold=THRESHOLD, font_size=FONT_SIZE, + debug_gifs=False, ): res = set() @@ -203,6 +206,12 @@ def test_words( if pc < threshold: continue + if debug_gifs: + out_fp = "debug_gifs" + if not os.path.exists("debug_gifs"): + os.makedirs("debug_gifs") + fp = os.path.join(out_fp, f"{pc:.2f}_{word.string}.gif".replace("/", "_")) + differ.debug_gif(fp) res.add( ( pc, diff --git a/src/diffenator2/utils.py b/src/diffenator2/utils.py index f9e0ef3..fa92b1a 100644 --- a/src/diffenator2/utils.py +++ b/src/diffenator2/utils.py @@ -131,17 +131,21 @@ def gen_gifs(dir1: str, dir2: str, dst_dir: str): img_a_path = os.path.join(dir1, img) img_b_path = os.path.join(dir2, img) dst = os.path.join(dst_dir, gif_filename) - gen_gif(img_a_path, img_b_path, dst) + gen_gif_from_filepaths(img_a_path, img_b_path, dst) -def gen_gif(img_a_path: str, img_b_path: str, dst: str): +def gen_gif_from_filepaths(img_a_path: str, img_b_path: str, dst: str): with Image.open(img_a_path) as img_a, Image.open(img_b_path) as img_b: - # Images must have same dimensions in order for PIL to gen gif - # 4-tuple defining the left, upper, right, and lower - crop_box = (0, 0, min(img_a.width, img_b.width), min(img_a.height, img_b.height)) - img_a = img_a.crop(crop_box) - img_b = img_b.crop(crop_box) - img_a.save(dst, save_all=True, append_images=[img_b], loop=10000, duration=1000) + gen_gif(img_a, img_b, dst) + + +def gen_gif(img_a, img_b, dst): + # Images must have same dimensions in order for PIL to gen gif + # 4-tuple defining the left, upper, right, and lower + crop_box = (0, 0, min(img_a.width, img_b.width), min(img_a.height, img_b.height)) + img_a = img_a.crop(crop_box) + img_b = img_b.crop(crop_box) + img_a.save(dst, save_all=True, append_images=[img_b], loop=10000, duration=1000) @lru_cache()