Add some comments to the code

This commit is contained in:
Dark-Storm 2018-09-13 20:04:08 +02:00
parent e27a26590b
commit fd29a61a34
Signed by: Darks
GPG Key ID: F61F10FA138E797C
1 changed files with 39 additions and 6 deletions

View File

@ -1,5 +1,16 @@
#!/usr/bin/env python3
### Readme ###################################################################
# name: sprite-optimizer
# version: 1.1
# author: Dark-Storm
# license: CeCILL v2.1
#
# comments:
# lines are stored as arrays of pixels
##############################################################################
from argparse import ArgumentParser
from bresenham import bresenham
from PIL import Image, ImageDraw
@ -7,12 +18,12 @@ from random import randint
import sys
from time import time
rand = lambda: randint(0,200)
progress = False
def print_stats(img):
"""Print number and percentage of black pixels"""
pixels = img.getdata()
count = sum([1 for i in pixels if i == 0])
if progress:
@ -20,6 +31,7 @@ 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]
@ -27,6 +39,7 @@ def get_lines(img):
if progress:
print("Get lines:", end = "")
# 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]))
@ -35,6 +48,7 @@ def get_lines(img):
if p not in pixels:
is_in = False
break
# if image contains the line, put it on the array
if is_in:
lines.append(line)
i += 1
@ -49,11 +63,15 @@ def get_lines(img):
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
@ -74,18 +92,23 @@ def removing_doubles(lines):
def removing_useless(lines):
"""Remove lines that are sub-lines of other ones"""
results = []
n = len(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):
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):
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))
if progress:
@ -99,16 +122,22 @@ 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]
results = []
n = len(px_left)
if progress:
print("Draw:", end = "")
# while the entier image has not been drown
while len(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]
# sort them by length
lines = sorted(lines)
# pop the longest
(p, line) = 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]
results.append((line[0], line[-1]))
if progress:
@ -122,13 +151,16 @@ def get_best_solution(img, lines):
def generate_code(lines, args):
"""Generate Basic Casio code"""
str_x, str_y = "{", "{"
for (xa, ya), (x, y) in lines:
x, y = x + int(args.offset[0]), y + int(args.offset[1])
xa, ya = xa + int(args.offset[0]), ya + int(args.offset[1])
str_x += "{}, ".format(get_coord(x, xa))
str_y += "{}, ".format(get_coord(y, ya))
# Casio's bresenham is reversed compared to classic ones
# so we need to reverse the ends of the lines
for (x_end, y_end), (x_start, y_start) in lines:
x_start, y_start = x_start + int(args.offset[0]), y_start + int(args.offset[1])
x_end, y_end = x_end + int(args.offset[0]), y_end + int(args.offset[1])
str_x += "{}, ".format(get_coord(x_start, x_end))
str_y += "{}, ".format(get_coord(y_start, y_end))
str_x = str_x[:-2] + "}"
str_y = str_y[:-2] + "}"
@ -138,6 +170,7 @@ def generate_code(lines, args):
# From Zezeombye's BIDE
def get_coord(start, end):
"""Convert a pair of coordonates to the appropriate x+yT Multi DrawStat output"""
result = "";
if start != 0:
result += str(start)