Skip to content

Commit 2ea7382

Browse files
committed
upload from mac
1 parent 7bebcfc commit 2ea7382

18 files changed

+1603
-0
lines changed

_2018/Image Effects.py

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Image Effects
2+
# Demonstrates some effects using different modules
3+
# from the Python Imaging Library (PIL).
4+
#
5+
# Tip: You can touch and hold an image in the output
6+
# to copy it to the clipboard or save it to your
7+
# camera roll.
8+
9+
import Image, ImageOps, ImageFilter
10+
from Image import BILINEAR
11+
from math import sqrt, sin, cos, atan2
12+
13+
def sketch(img):
14+
edge_img = img.filter(ImageFilter.CONTOUR)
15+
return ImageOps.grayscale(edge_img)
16+
17+
def color_tiles(img):
18+
size = img.size
19+
small_img = img.resize((size[0]/2, size[1]/2), BILINEAR)
20+
bw_img = small_img.convert('1', dither=False)
21+
gray_img = bw_img.convert('L')
22+
result = Image.new('RGB', size)
23+
tile1 = ImageOps.colorize(gray_img, 'green', 'red')
24+
tile2 = ImageOps.colorize(gray_img, 'purple', 'yellow')
25+
tile3 = ImageOps.colorize(gray_img, 'yellow', 'brown')
26+
tile4 = ImageOps.colorize(gray_img, 'red', 'cyan')
27+
result.paste(tile1, (0, 0))
28+
result.paste(tile2, (size[0]/2, 0))
29+
result.paste(tile3, (0, size[1]/2))
30+
result.paste(tile4, (size[0]/2, size[1]/2))
31+
return result
32+
33+
def twisted(img, strength):
34+
mesh = []
35+
m = 16
36+
w, h = img.size
37+
for x in xrange(w / m):
38+
for y in xrange(h / m):
39+
target_rect = (x * m, y * m, x * m + m, y * m + m)
40+
quad_points = ((x * m, y * m), (x * m, y * m + m),
41+
(x * m + m, y * m + m), (x * m + m, y * m))
42+
quad_list = []
43+
for qx, qy in quad_points:
44+
dx = w/2 - qx
45+
dy = h/2 - qy
46+
d = sqrt(dx**2 + dy**2)
47+
angle = atan2(dx, dy)
48+
angle += max((w/2 - d), 0) * strength
49+
qx = w/2 - sin(angle) * d
50+
qy = h/2 - cos(angle) * d
51+
quad_list.append(qx)
52+
quad_list.append(qy)
53+
mesh.append((target_rect, quad_list))
54+
return img.transform(img.size, Image.MESH, mesh, BILINEAR)
55+
56+
def main():
57+
img = Image.open('Test_Lenna')
58+
img = img.resize((256, 256), Image.BILINEAR)
59+
img.show()
60+
61+
sketch(img).show()
62+
color_tiles(img).show()
63+
twisted(img, 0.02).show()
64+
65+
if __name__ == '__main__':
66+
main()

_2018/Image Warp.py

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Image Warp
2+
#
3+
# Demonstrates an interesting use of the image_quad function
4+
# to distort an image based on touch.
5+
6+
from scene import *
7+
from math import sqrt, sin, pi, floor
8+
import Image
9+
10+
M = 16 # number of vert. and horiz. quads in the mesh (16*16=256)
11+
12+
class ImageWarp (Scene):
13+
def setup(self):
14+
self.offsets = [[(0.0, 0.0) for x in xrange(M+1)] for y in xrange(M+1)]
15+
if self.size.w >= 700:
16+
# Use the original image on iPad:
17+
self.img = 'Test_Lenna'
18+
s = 512
19+
else:
20+
# Resize the image for small screens:
21+
s = 256
22+
img_name = 'Test_Lenna'
23+
img = Image.open(img_name).convert('RGBA')
24+
img = img.resize((s, s), Image.BILINEAR)
25+
self.img = load_pil_image(img)
26+
self.img_size = s
27+
self.m = s / M
28+
29+
def draw_warped_image(self):
30+
m = self.m
31+
for x in xrange(M):
32+
for y in xrange(M):
33+
d = self.offsets
34+
# distances of the 4 corner points from their original position:
35+
d1 = d[x][y]; d2 = d[x + 1][y]
36+
d3 = d[x][y + 1]; d4 = d[x + 1][y + 1]
37+
image_quad(self.img,
38+
# distorted quad:
39+
x * m + d1[0], y * m + d1[1],
40+
x * m + m + d2[0], y * m + d2[1],
41+
x * m + d3[0], y * m + m + d3[1],
42+
x * m + m + d4[0], y * m + m + d4[1],
43+
# source quad in image:
44+
x * m, y * m, x * m + m, y * m,
45+
x * m, y * m + m, x * m + m, y * m + m)
46+
47+
def bulge(self, touch_x, touch_y):
48+
# push mesh vertices away from touch location:
49+
m = self.m
50+
r = self.img_size / 5
51+
for x in xrange(0, M + 1):
52+
for y in xrange(0, M + 1):
53+
offset = self.offsets[x][y]
54+
dist = sqrt((x*m-touch_x + offset[0])**2.0 +
55+
(y*m-touch_y + offset[1])**2.0)
56+
dx = x*m - touch_x
57+
dy = y*m - touch_y
58+
unit_x = dx / dist if dist > 0 else 0.0
59+
unit_y = dy / dist if dist > 0 else 0.0
60+
b = self.dt * 50
61+
if dist < r:
62+
falloff = max(sin(dist/r*pi), 0)
63+
offset_x = unit_x * b * falloff + offset[0]
64+
offset_y = unit_y * b * falloff + offset[1]
65+
self.offsets[x][y] = (offset_x, offset_y)
66+
67+
def revert(self):
68+
for x in xrange(0, M + 1):
69+
for y in xrange(0, M + 1):
70+
offset = self.offsets[x][y]
71+
offset_x = floor(offset[0] - cmp(offset[0], 0))
72+
offset_y = floor(offset[1] - cmp(offset[1], 0))
73+
self.offsets[x][y] = (offset_x, offset_y)
74+
75+
def draw(self):
76+
background(0, 0, 0)
77+
push_matrix()
78+
tx = self.size.w/2 - self.img_size/2
79+
ty = self.size.h/2 - self.img_size/2
80+
translate(tx, ty)
81+
text('Touch the image to deform it.', 'Helvetica-Bold',
82+
18, self.img_size/2, -30, alignment=5)
83+
text('Use two fingers to revert.', 'Helvetica-Bold',
84+
18, self.img_size/2, -60, alignment=5)
85+
self.draw_warped_image()
86+
pop_matrix()
87+
if len(self.touches) ==0:
88+
return
89+
if len(self.touches) > 1:
90+
self.revert()
91+
else:
92+
loc = self.touches.values()[0].location
93+
touch_x, touch_y = loc.x - tx, loc.y - ty
94+
self.bulge(touch_x, touch_y)
95+
96+
run(ImageWarp(), frame_interval=1)

_2018/Piano.py

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Piano
2+
#
3+
# A simple multi-touch piano.
4+
5+
from scene import *
6+
import sound
7+
from itertools import chain
8+
9+
class Key (object):
10+
def __init__(self, frame):
11+
self.frame = frame
12+
self.name = None
13+
self.touch = None
14+
self.color = Color(1, 1, 1)
15+
self.highlight_color = Color(0.9, 0.9, 0.9)
16+
17+
def hit_test(self, touch):
18+
return touch.location in self.frame
19+
20+
class Piano (Scene):
21+
def setup(self):
22+
self.white_keys = []
23+
self.black_keys = []
24+
white_key_names = ['Piano_C3', 'Piano_D3', 'Piano_E3',
25+
'Piano_F3', 'Piano_G3', 'Piano_A3',
26+
'Piano_B3', 'Piano_C4']
27+
black_key_names = ['Piano_C3#', 'Piano_D3#', 'Piano_F3#',
28+
'Piano_G3#', 'Piano_A3#']
29+
for key_name in chain(white_key_names, black_key_names):
30+
sound.load_effect(key_name)
31+
white_positions = range(8)
32+
black_positions = [0.5, 1.5, 3.5, 4.5, 5.5]
33+
key_w = self.size.w
34+
key_h = self.size.h / 8
35+
for i in range(len(white_key_names)):
36+
pos = white_positions[i]
37+
key = Key(Rect(0, pos * key_h, key_w, key_h))
38+
key.name = white_key_names[i]
39+
self.white_keys.append(key)
40+
for i in range(len(black_key_names)):
41+
pos = black_positions[i]
42+
key = Key(Rect(0, pos * key_h + 10, key_w * 0.6, key_h - 20))
43+
key.name = black_key_names[i]
44+
key.color = Color(0, 0, 0)
45+
key.highlight_color = Color(0.2, 0.2, 0.2)
46+
self.black_keys.append(key)
47+
48+
def draw(self):
49+
stroke_weight(1)
50+
stroke(0.5, 0.5, 0.5)
51+
for key in chain(self.white_keys, self.black_keys):
52+
if key.touch is not None:
53+
fill(*key.highlight_color.as_tuple())
54+
else:
55+
fill(*key.color.as_tuple())
56+
rect(*key.frame.as_tuple())
57+
58+
def touch_began(self, touch):
59+
for key in chain(self.black_keys, self.white_keys):
60+
if key.hit_test(touch):
61+
key.touch = touch
62+
sound.play_effect(key.name)
63+
return
64+
65+
def touch_moved(self, touch):
66+
hit_key = None
67+
for key in chain(self.black_keys, self.white_keys):
68+
hit = key.hit_test(touch)
69+
if hit and hit_key is None:
70+
hit_key = key
71+
if key.touch is None:
72+
key.touch = touch
73+
sound.play_effect(key.name)
74+
if key.touch == touch and key is not hit_key:
75+
key.touch = None
76+
77+
def touch_ended(self, touch):
78+
for key in chain(self.black_keys, self.white_keys):
79+
if key.touch == touch:
80+
key.touch = None
81+
82+
run(Piano(), PORTRAIT)

_2018/Plotter.py

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Function Plotter
2+
3+
import canvas
4+
import console
5+
from math import sin, cos, pi
6+
7+
def draw_grid(min_x, max_x, min_y, max_y):
8+
w, h = canvas.get_size()
9+
scale_x = w / (max_x - min_x)
10+
scale_y = h / (max_y - min_y)
11+
min_x, max_x = round(min_x), round(max_x)
12+
min_y, max_y = round(min_y), round(max_y)
13+
canvas.begin_updates()
14+
canvas.set_line_width(1)
15+
canvas.set_stroke_color(0.7, 0.7, 0.7)
16+
#Draw vertical grid lines:
17+
x = min_x
18+
while x <= max_x:
19+
if x != 0:
20+
draw_x = round(w / 2 + x * scale_x) + 0.5
21+
canvas.draw_line(draw_x, 0, draw_x, h)
22+
x += 0.5
23+
#Draw horizontal grid lines:
24+
y = min_y
25+
while y <= max_y:
26+
if y != 0:
27+
draw_y = round(h/2 + y * scale_y) + 0.5
28+
canvas.draw_line(0, draw_y, w, draw_y)
29+
y += 0.5
30+
#Draw x and y axis:
31+
canvas.set_stroke_color(0, 0, 0)
32+
canvas.draw_line(0, h/2, w, h/2)
33+
canvas.draw_line(w/2, 0, w/2, h)
34+
canvas.end_updates()
35+
36+
def plot_function(func, color, min_x, max_x, min_y, max_y):
37+
#Calculate scale, set line width and color:
38+
w, h = canvas.get_size()
39+
origin_x, origin_y = w * 0.5, h * 0.5
40+
scale_x = w / (max_x - min_x)
41+
scale_y = h / (max_y - min_y)
42+
canvas.set_stroke_color(*color)
43+
canvas.set_line_width(2)
44+
canvas.move_to(origin_x + scale_x * min_x,
45+
origin_y + func(min_x) * scale_y)
46+
#Draw the graph line:
47+
x = min_x
48+
while x <= max_x:
49+
x += 0.05
50+
draw_x = origin_x + scale_x * x
51+
draw_y = origin_y + func(x) * scale_y
52+
canvas.add_line(draw_x, draw_y)
53+
canvas.set_fill_color(*color)
54+
canvas.draw_path()
55+
56+
#Set up the canvas size and clear any text output:
57+
console.clear()
58+
canvas.set_size(688, 688)
59+
#Draw the grid:
60+
area = (-pi, pi, -pi, pi)
61+
draw_grid(*area)
62+
#Draw 4 different graphs (sin(x), cos(x), x^2, x^3):
63+
plot_function(sin, (1, 0, 0), *area)
64+
plot_function(cos, (0, 0, 1), *area)
65+
plot_function(lambda x: x ** 2, (0, 1, 1), *area)
66+
plot_function(lambda x: x ** 3, (1.0, 0.5, 0), *area)

0 commit comments

Comments
 (0)