-
Notifications
You must be signed in to change notification settings - Fork 2
/
dither.py
85 lines (66 loc) · 2.17 KB
/
dither.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
"""Dithering algorithm.
Basically copy/pasted Isai Cicourel's code in this blog post:
https://www.codementor.io/@isaib.cicourel/image-manipulation-in-python-du1089j1u
"""
from PIL import Image
def get_saturation(value, quadrant):
if value > 223:
return 255
elif value > 159:
if quadrant != 1:
return 255
return 0
elif value > 95:
if quadrant == 0 or quadrant == 3:
return 255
return 0
elif value > 32:
if quadrant == 1:
return 255
return 0
else:
return 0
def get_pixel(image, i, j):
# Inside image bounds?
width, height = image.size
if i > width or j > height:
return None
# Get Pixel
pixel = image.getpixel((i, j))
return pixel
# Create a dithered version of the image
def convert(image):
# TODO: Make this work for images with height/width that isn't an even number!
# Get size
width, height = image.size
# Create new Image and a Pixel Map
new = Image.new("RGB", (width, height), "white")
pixels = new.load()
# Transform to half tones
for i in range(0, width, 2):
for j in range(0, height, 2):
# Get Pixels
p1 = get_pixel(image, i, j)
p2 = get_pixel(image, i, j + 1)
p3 = get_pixel(image, i + 1, j)
p4 = get_pixel(image, i + 1, j + 1)
# Color Saturation by RGB channel
red = (p1[0] + p2[0] + p3[0] + p4[0]) / 4
green = (p1[1] + p2[1] + p3[1] + p4[1]) / 4
blue = (p1[2] + p2[2] + p3[2] + p4[2]) / 4
# Results by channel
r = [0, 0, 0, 0]
g = [0, 0, 0, 0]
b = [0, 0, 0, 0]
# Get Quadrant Color
for x in range(0, 4):
r[x] = get_saturation(red, x)
g[x] = get_saturation(green, x)
b[x] = get_saturation(blue, x)
# Set Dithered Colors
pixels[i, j] = (r[0], g[0], b[0])
pixels[i, j + 1] = (r[1], g[1], b[1])
pixels[i + 1, j] = (r[2], g[2], b[2])
pixels[i + 1, j + 1] = (r[3], g[3], b[3])
# Return new image
return new