Added dithering, added documentation for dithering and bits per color, vastly simplified test suite by abstracting control logic to another function, added tests for dithering, removed debug info
This commit is contained in:
parent
246635ba26
commit
78466698fc
25
2bit.py
25
2bit.py
|
@ -1,18 +1,21 @@
|
|||
bits = 2
|
||||
outfile = "out.png"
|
||||
print_debug = False
|
||||
per_color = False
|
||||
dither = False
|
||||
|
||||
# End of the configuration section
|
||||
|
||||
import PIL.Image, sys
|
||||
import PIL.Image, sys, random
|
||||
if len(sys.argv) >= 3:
|
||||
outfile = sys.argv[2]
|
||||
if len(sys.argv) >= 4:
|
||||
bits = int(sys.argv[3])
|
||||
per_color = "--per-color" in [f.lower() for f in sys.argv]
|
||||
def debug(*args):
|
||||
if print_debug: print(*args)
|
||||
args = [f.lower() for f in sys.argv]
|
||||
if "--dither" in args:
|
||||
dither = float(args[args.index("--dither") + 1].replace("%",""))
|
||||
if dither > 1:
|
||||
dither /= 100
|
||||
per_color = "--per-color" in args
|
||||
def binprecision(start, bits, length):
|
||||
end = bin(int(start))[2:]
|
||||
while len(end) < bits:
|
||||
|
@ -26,25 +29,21 @@ elif bits == 1:
|
|||
mode = "1" # 1x1 bit unsigned integer
|
||||
out = PIL.Image.new(mode,image.size)
|
||||
colors = [int(i*255.0/(2**bits-1)) for i in range(2**bits)]
|
||||
debug(image.width, image.height)
|
||||
for x in range(image.width):
|
||||
for y in range(image.height):
|
||||
pos = (x,y)
|
||||
color = image.getpixel(pos)
|
||||
debug(color)
|
||||
if len(color) == 4:
|
||||
color = color[:3] # Exclude alpha layer
|
||||
color = list(color)
|
||||
if not per_color:
|
||||
color = [float(sum(color))/len(color)]
|
||||
debug(color)
|
||||
for z in color: debug(bin(int(z)))
|
||||
for z in range(len(color)):
|
||||
if dither:
|
||||
color[z] += 255 * random.uniform(-dither,dither)
|
||||
color[z] = min(color[z], 255)
|
||||
color[z] = max(color[z], 0)
|
||||
index = int(binprecision(color[z], 8, bits), 2)
|
||||
debug(index)
|
||||
color[z] = colors[index]
|
||||
out.putpixel(pos, tuple(color))
|
||||
debug()
|
||||
debug("------------")
|
||||
debug()
|
||||
out.save(outfile)
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
Inspired by [2bit](http://2bit.neocities.org/)
|
||||
|
||||
Usage: `python3 2bit.py infile.png [outfile.png] [bits]`
|
||||
Usage: `python3 2bit.py infile.png [outfile.png] [bits] [--per-color] [--dither dither_value]`
|
||||
|
||||
dither\_value can be like `50%`, `50` or `.5`
|
||||
|
||||
Warning: Will probably turn transparency black
|
||||
|
||||
|
|
36
test/run.py
36
test/run.py
|
@ -8,19 +8,39 @@ files = glob.glob("*")
|
|||
del files[files.index("run.py")]
|
||||
if not os.path.isdir("out"): os.mkdir("out")
|
||||
i = 0
|
||||
max_i = len(files) * (8+8)
|
||||
max_i = len(files) * (16*3)
|
||||
|
||||
def getparams(i):
|
||||
percolor = dither = False
|
||||
if i % 16 >= 8:
|
||||
percolor = True
|
||||
if i >= 16:
|
||||
dither = '15'
|
||||
if i >= 32:
|
||||
dither = '50'
|
||||
return percolor, dither
|
||||
|
||||
for f in files:
|
||||
if (os.path.isdir(f)): continue
|
||||
for bits in range(8+8):
|
||||
if (f[-3:]) == '.py': continue
|
||||
for bits in range(16*3):
|
||||
bits += 1
|
||||
percolor = []
|
||||
pc = ""
|
||||
if bits > 8:
|
||||
percolor, dither = getparams(i)
|
||||
if not percolor:
|
||||
percolor = []
|
||||
pc = ""
|
||||
else:
|
||||
percolor = ["--per-color"]
|
||||
pc = "-per-color"
|
||||
pc = "per-color-"
|
||||
if not dither:
|
||||
dither = []
|
||||
dc = ""
|
||||
else:
|
||||
dc = "dither-" + dither + "%-"
|
||||
dither = ["--dither", dither]
|
||||
print(str(int(float(1000*i)/max_i)/10) + "% done")
|
||||
bits_formatted = str((bits-1)%8+1)
|
||||
outfilename = "out/" + ".".join(f.split(".")[:-1]) + "-output" + pc + "-" + bits_formatted + "bits.png"
|
||||
outfilename = "out/" + ".".join(f.split(".")[:-1]) + "-output-" + pc + dc + bits_formatted + "bits.png"
|
||||
print("On " + outfilename)
|
||||
subprocess.call(["python3", "../2bit.py", f, outfilename, bits_formatted, *percolor])
|
||||
subprocess.call(["python3", "../2bit.py", f, outfilename, bits_formatted, *percolor, *dither])
|
||||
i += 1
|
||||
|
|
Loading…
Reference in New Issue