Added "auto" mode for nonrandom dithering, fixed tests

This commit is contained in:
Niles Rogoff 2016-07-21 13:58:17 -07:00
parent e014cdbcce
commit b6b57f57d0
3 changed files with 26 additions and 14 deletions

16
2bit.py
View File

@ -12,7 +12,12 @@ def format_dither(d):
d = float(int(float(dither) * 1000)) / 10
return str(d) + "%"
def auto_dither(bits):
return 1.0 / (bits + 1)
#return 1.0 / (bits + 1)
return 1.0 / (2**bits)
def auto_counter_max(w):
k = max(int(float(w)/200),2)
while w % (k + 1) == 0: k += 1
return k
if len(sys.argv) >= 3:
outfile = sys.argv[2]
if len(sys.argv) >= 4:
@ -29,8 +34,14 @@ if dither > 1:
dither /= 100
per_color = "--per-color" in args
use_non_random_dither = "--non-random-dither" in args
image = PIL.Image.open(sys.argv[1])
if use_non_random_dither:
counter_max = int(args[args.index("--non-random-dither") + 1])
counter_max = args[args.index("--non-random-dither") + 1]
if counter_max == "auto":
counter_max = auto_counter_max(image.height)
print("Using non-random dither counter value of " + str(counter_max) + " pixels")
else:
counter_max = int(counter_max)
if not dither:
dither = auto_dither(bits)
print("Non-random dither has no effect if dither is disabled. Guessing you want "+format_dither(dither)+" dither")
@ -39,7 +50,6 @@ def binprecision(start, bits, length):
while len(end) < bits:
end = '0' + end
return end[:length]
image = PIL.Image.open(sys.argv[1])
mode = "L" # 1x8 bit unsigned integer
if per_color:
mode = "RGB"

View File

@ -4,12 +4,12 @@ Inspired by [2bit](http://2bit.neocities.org/)
Usage: `python3 2bit.py infile.png [outfile.png] [bits] [--per-color] [--dither dither_value] [--non-random-dither num_pixels]`
dither\_value can be like `50%`, `50` or `.5`
You can change the number of bits for different results. 1 would be just black and white, while 8 would be the original image in greyscale.
dither\_value can be like `50%`, `50`, `.5` or `auto`
Note that using `--non-random-dither` without a dither argument will attempt to guess what dither percentage you want based on the number of bits
The best number for num\_pixels is usually 7, but it should ideally be coprime with the height of the image
The best number for num\_pixels varies with the image. In general, the height of the image modulo num\_pixels + 1 should not equal zero. Experiment with it. Using `auto` will try to guess a good value such that you don't get horizontal bars, but it's not very good at it.
Warning: Will probably turn transparency black
You can change the number of bits for different results. 1 would be just black and white, while 8 would be the original image in greyscale.

View File

@ -8,8 +8,6 @@ files = glob.glob("*")
del files[files.index("gentest.py")]
del files[files.index("run.py")]
if not os.path.isdir("out"): os.mkdir("out")
i = 0
max_i = len(files) * (112)
def run(bits, percolor, dither, nonrandom):
if not percolor:
percolor = []
@ -33,17 +31,21 @@ def run(bits, percolor, dither, nonrandom):
outfilename = "out/" + ".".join(f.split(".")[:-1]) + "-output-" + pc + dc + nc + bits_formatted + "bits.png"
print("On " + outfilename)
subprocess.call(["python3", "../2bit.py", f, outfilename, bits_formatted, *percolor, *dither, *nonrandom])
print(str(max_i) + " images to generate")
torun = []
for f in files:
if (os.path.isdir(f)): continue
if (f[-3:]) == '.py': continue
for bits in range(8):
for dither in [False, "15", "50", "auto"]:
for nonrandom in [False, "7", "10"]:
for nonrandom in [False, "7", "10", "auto"]:
for percolor in [False, True]:
if nonrandom and not dither: continue
i += 1
run(bits, percolor, dither, nonrandom)
print(str(int(float(1000*i)/max_i)/10) + "% done")
torun.append([bits, percolor, dither, nonrandom])
print(str(len(torun)) + " images to generate")
i = 0
for args in torun:
i += 1
print(str(int(i * 1000 / len(torun))/10.0) + "% done")
run(*args)
print("Done")