### Merge branch 'master' of Lephenixnoir/sprite-optimizer into master

 `@ -32,8 +32,9 @@ def print_stats(img):` ``` ``` `def get_lines(img):` ` """Generate all potential lines the image contains"""` ` lines = []` ` pixels = [(x, y) for x in range(img.width) for y in range(img.height) if img.getpixel((x, y)) == 0]` ` lines = set()` ` lines_uniq = set()` ` pixels = {(x, y) for x in range(img.width) for y in range(img.height) if img.getpixel((x, y)) == 0}` ``` ``` ` i, n = 0, len(pixels) * len(pixels)` ``` ``` `@ -42,53 +43,21 @@ def get_lines(img):` ` # for each pair of pixels, get the line` ` for a in pixels:` ` for b in pixels:` ` line = list(bresenham(a[0], a[1], b[0], b[1]))` ` is_in = True` ` for p in line:` ` if p not in pixels:` ` is_in = False` ` break` ` line = tuple(bresenham(*a, *b))` ` line_uniq = tuple(sorted(line))` ``` ``` ` # if image contains the line, put it on the array` ` if is_in:` ` lines.append(line)` ` if set(line).issubset(pixels) and line_uniq not in lines_uniq:` ` lines.add(line)` ` lines_uniq.add(line_uniq)` ` i += 1` ` if progress:` ` print("\rGet lines: {:.1%}".format(i / n), end = "")` ` if progress:` ` print("\rGet lines: complete")` ``` ``` ` if progress:` ` print("\rGet lines: complete")` ` print("{} lines found".format(len(lines)))` ` return lines` ``` ``` ``` ``` `def removing_doubles(lines):` ` """Remove lines that are symetric"""` ` results = []` ` n = len(lines)` ``` ``` ` if progress:` ` print("Remove duplicated lines:", end = "")` ` # for each line, see if it's already in the output array` ` # beware not to change the orientation of the line (bresenham is not symetric)` ` # TODO: optimize a bit this operation` ` for i, l in enumerate(lines):` ` s = sorted(l)` ` same = False` ` for o in results:` ` if sorted(o) == s:` ` same = True` ` break` ` if same == False:` ` results.append(l)` ` if progress:` ` print("\rRemove double lines: {:.1%}".format(i / n), end = "")` ` if progress:` ` print("\rRemove double lines: complete")` ``` ``` ` if progress:` ` print("{} lines kept".format(len(results)))` ` return results` ` return list(lines)` ``` ``` ``` ``` `def removing_useless(lines):` `@ -99,18 +68,20 @@ def removing_useless(lines):` ` if progress:` ` print("Remove useless lines:", end = "")` ` # for each line, see if there is a line that contains every pixel of it` ` for i, l in enumerate(lines):` ` lines_set = [ set(l) for l in lines ]` ``` ``` ` for i, l in enumerate(lines_set):` ` inclusions = 0` ` # others are all lines that are not l` ` others = (x for x in lines if x != l)` ` for k in others:` ` if len(list(set(l).intersection(set(k)))) == len(l):` ` for j, k in enumerate(lines_set):` ` if i == j: continue` ` if l.issubset(k):` ` inclusions += 1` ` break` ` # or len(l) == 1 : we keep single pixels to complete the image if necessary` ` # TODO: do some tests to see if it's worth or not` ` if inclusions == 0 or len(l) == 1:` ` results.append((len(l), l))` ` results.append((len(l), lines[i], l))` ` if progress:` ` print("\rRemove useless lines: {:.1%}".format(i / n), end = "")` ` if progress:` `@ -123,22 +94,24 @@ def removing_useless(lines):` ``` ``` `def get_best_solution(img, lines):` ` """Compute an optimized solution. The magic part of the algorithm"""` ` px_left = [(x, y) for x in range(img.width) for y in range(img.height) if img.getpixel((x, y)) == 0]` ` px_left = {(x, y) for x in range(img.width) for y in range(img.height)` ` if img.getpixel((x, y)) == 0}` ` results = []` ` n = len(px_left)` ``` ``` ` if progress:` ` print("Draw:", end = "")` ` # while the entier image has not been drown` ` while len(px_left):` ` while px_left:` ` # define the length of lines` ` lines = [(sum([1 for p in l if p in px_left]) - len(l)/(2*max(img.size)), l) for n, l in lines]` ` lines = [(len(l_set.intersection(px_left)) - len(l)/(2*max(img.size)),` ` l, l_set) for n, l, l_set in lines]` ` # sort them by length` ` lines = sorted(lines)` ` # pop the longest` ` (p, line) = lines.pop()` ` (p, line, line_set) = lines.pop()` ` # define the pixels that are not covered by any lines` ` px_left = [p for p in px_left if p not in line]` ` px_left = px_left.difference(line_set)` ` results.append((line[0], line[-1]))` ` if progress:` ` print("\rDraw: {:.0%}".format(1 - len(px_left)/n), end="")` `@ -222,7 +195,6 @@ if __name__ == "__main__":` ` if args.info:` ` print_stats(image)` ` lines = get_lines(image)` ` lines = removing_doubles(lines)` ` lines = removing_useless(lines)` ` lines = get_best_solution(image, lines)` ` code = generate_code(lines, args)`