First commit
This commit is contained in:
commit
28d07dd7aa
|
@ -0,0 +1,143 @@
|
|||
#!/usr/bin/python3
|
||||
# lid: lo-fi image dithering
|
||||
# written by sloum
|
||||
# licence: public domain - use it, improve it, share it!
|
||||
#########
|
||||
|
||||
from PIL import Image
|
||||
import sys
|
||||
import os.path
|
||||
|
||||
# Main program to output the new image
|
||||
def dither(r):
|
||||
im = Image.open(r["path"]).convert("L")
|
||||
width, height = im.size
|
||||
new = create_image(width, height)
|
||||
newpixels = new.load()
|
||||
|
||||
dots = [
|
||||
[64, 128],
|
||||
[192, 0]
|
||||
]
|
||||
|
||||
count = 0
|
||||
print(" dithering...\033[?25l", end="")
|
||||
for row in range(0, height):
|
||||
if not row % 7:
|
||||
print_spinner(count)
|
||||
count += 1
|
||||
if count > 3:
|
||||
count = 0
|
||||
for col in range(0, width):
|
||||
dotrow = 1 if row % 2 else 0
|
||||
dotcol = 1 if col % 2 else 0
|
||||
impx = get_pixel(im, col, row)
|
||||
newpixels[col, row] = int(impx > dots[dotrow][dotcol])
|
||||
|
||||
new.save("{}.{}".format(r["out"], r["-f"]), r["-f"].upper(), optimize=True, quality=25)
|
||||
print("\033[20C\nfinished\033[?25h")
|
||||
|
||||
def print_spinner(n):
|
||||
parts = ["- "," - "," - "," -"]
|
||||
print("\r{}".format(parts[n]), end="")
|
||||
|
||||
# Create a new image with the given size
|
||||
def create_image(i, j):
|
||||
image = Image.new("1", (i, j))
|
||||
return image
|
||||
|
||||
|
||||
# Get the pixel from the given image
|
||||
def get_pixel(image, i, j):
|
||||
width, height = image.size
|
||||
if i > width or j > height:
|
||||
return None
|
||||
|
||||
# Get Pixel
|
||||
pixel = image.getpixel((i, j))
|
||||
return pixel
|
||||
|
||||
|
||||
def display_help():
|
||||
helptext = """
|
||||
lid - lo-fi image dithering
|
||||
|
||||
syntax:
|
||||
lid [option]... [infile] [outfile]
|
||||
|
||||
options:
|
||||
-f output format. defaults to the recommended setting: png
|
||||
-q image quality. defaults to 90. only has effect on png/jpg
|
||||
|
||||
arguments:
|
||||
infile path to a valid image file on your system
|
||||
outfile file name to output, do not include file extension
|
||||
|
||||
example usage:
|
||||
lid -f jpeg -q 75 ~/my_picture.png my_dithered_picture
|
||||
"""
|
||||
print(helptext)
|
||||
|
||||
|
||||
# Get and validate the arguments
|
||||
# returns dict or None
|
||||
def parse_input():
|
||||
args = sys.argv[1:]
|
||||
argmap = {
|
||||
"-f": "png", # output format
|
||||
"-q": 90, # optimization quality
|
||||
"path": None, # path to file
|
||||
"out": "lid_file" # output filename
|
||||
}
|
||||
if len(args) < 1:
|
||||
print("lid error: expected image filepath, received None")
|
||||
return None
|
||||
|
||||
if "help" in args or "-h" in args or "--help" in args:
|
||||
display_help()
|
||||
sys.exit(1)
|
||||
|
||||
item = None
|
||||
for x in args:
|
||||
if x in argmap:
|
||||
item = x
|
||||
continue
|
||||
elif item:
|
||||
argmap[item] = x
|
||||
item = None
|
||||
elif len(x) > 0 and x[0] == "-":
|
||||
print("lid error: unknown flag {}".format(x))
|
||||
return None
|
||||
else:
|
||||
if argmap["path"]:
|
||||
argmap["out"] = x
|
||||
else:
|
||||
argmap["path"] = x
|
||||
|
||||
if not argmap["-f"] in ["jpeg", "jpg", "png", "gif", None]:
|
||||
print("lid error: invalid format requested with -f flag. Options: jpeg, png, gif. Defaults to png")
|
||||
return None
|
||||
elif argmap["-f"] == "jpg":
|
||||
argmap["-f"] = "jpeg"
|
||||
|
||||
try:
|
||||
argmap["-q"] = int(argmap["-q"])
|
||||
if argmap["-q"] < 1 or argmap["-q"] > 100:
|
||||
print("lid error: -q value must be between 1 and 100")
|
||||
return None
|
||||
except ValueError:
|
||||
print("lid error: -q value must be an integer")
|
||||
return None
|
||||
|
||||
if not argmap["path"] or not os.path.isfile(argmap["path"]):
|
||||
print("lid error: invalid filepath")
|
||||
return None
|
||||
|
||||
return argmap
|
||||
|
||||
if __name__ == "__main__":
|
||||
request = parse_input()
|
||||
if request:
|
||||
dither(request)
|
||||
sys.exit(0)
|
||||
sys.exit(1)
|
Loading…
Reference in New Issue