diff --git a/2bit.py b/2bit.py index 7346f6e..1789fc7 100644 --- a/2bit.py +++ b/2bit.py @@ -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" diff --git a/README.md b/README.md index 928d2f2..3a2b61c 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/test/run.py b/test/run.py index f026c30..a5efe3c 100644 --- a/test/run.py +++ b/test/run.py @@ -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")