Gizeh - Cairo for tourists
Gizeh是一个用于矢量图形的Python库
本地环境使用python3.8,首先安装依赖
pip install gizeh
pip install moviepy
利用以上这些库,可以创建矢量动画
以下为示例代码
入门示例 绘制一个黑色圆形
import gizeh
surface = gizeh.Surface(width=300, height=300) # dimensions in pixel
circle = gizeh.circle(r=40, # radius, in pixels
xy=[150, 150], # coordinates of the center
fill=(1, 1, 0)) # 'red' in RGB coordinates
circle.draw(surface) # draw the circle on the surface
surface.get_npimage() # export as a numpy array (we will use that)
surface.write_to_png("小球.png") # export as a PNG
示例1 放大变小的圆形
import gizeh
import moviepy.editor as mpy
W, H = 128, 128 # width, height, in pixels
duration = 2 # duration of the clip, in seconds
def make_frame(t):
surface = gizeh.Surface(W, H)
radius = W * (1 + (t * (duration - t)) ** 2) / 6
circle = gizeh.circle(radius, xy=(W / 2, H / 2), fill=(1, 1, 1))
circle.draw(surface)
return surface.get_npimage()
clip = mpy.VideoClip(make_frame, duration=duration)
clip.write_gif("放大缩小圆形.gif", fps=15, opt="OptimizePlus", fuzz=10)
示例2 黑洞效果
import numpy as np
import gizeh
import moviepy.editor as mpy
W,H = 128,128
duration = 2
ncircles = 20 # Number of circles
def make_frame(t):
surface = gizeh.Surface(W,H)
for i in range(ncircles):
angle = 2*np.pi*(1.0*i/ncircles+t/duration)
center = W*( 0.5+ gizeh.polar2cart(0.1,angle))
circle = gizeh.circle(r= W*(1.0-1.0*i/ncircles),
xy= center, fill= (i%2,i%2,i%2))
circle.draw(surface)
return surface.get_npimage()
clip = mpy.VideoClip(make_frame, duration=duration)
clip.write_gif("circles.gif",fps=15, opt="OptimizePlus", fuzz=10)
示例3 多小球运动
import gizeh as gz
import moviepy.editor as mpy
import numpy as np
W = H = 150
D = 2 # duration
nballs = 60
# generate random values of radius, color, center
radii = np.random.randint(.1 * W, .2 * W, nballs)
colors = np.random.rand(nballs, 3)
centers = np.random.randint(0, W, (nballs, 2))
def make_frame(t):
surface = gz.Surface(W, H)
for r, color, center in zip(radii, colors, centers):
angle = 2 * np.pi * (t / D * np.sign(color[0] - .5) + color[1])
xy = center + gz.polar2cart(W / 5, angle) # center of the ball
gradient = gz.ColorGradient(type="radial",
stops_colors=[(0, color), (1, color / 10)],
xy1=[0.3, -0.3], xy2=[0, 0], xy3=[0, 1.4])
ball = gz.circle(r=1, fill=gradient).scale(r).translate(xy)
ball.draw(surface)
return surface.get_npimage()
clip = mpy.VideoClip(make_frame, duration=D)
clip.write_gif("多小球运动.gif", fps=15, opt="OptimizePlus")
示例4 弹跳小球
import gizeh as gz
import moviepy.editor as mpy
W, H = 200, 75
D = 3
r = 10 # radius of the ball
DJ, HJ = 50, 35 # distance and height of the jumps
ground = 0.75 * H # y-coordinate of the ground
gradient = gz.ColorGradient(type="radial",
stops_colors=[(0, (1, 0, 0)), (1, (0.1, 0, 0))],
xy1=[0.3, -0.3], xy2=[0, 0], xy3=[0, 1.4])
def make_frame(t):
surface = gz.Surface(W, H, bg_color=(1, 1, 1))
x = (-W / 3) + (5 * W / 3) * (t / D)
y = ground - HJ * 4 * (x % DJ) * (DJ - (x % DJ)) / DJ ** 2
coef = (HJ - y) / HJ
shadow_gradient = gz.ColorGradient(type="radial",
stops_colors=[(0, (0, 0, 0, .2 - coef / 5)), (1, (0, 0, 0, 0))],
xy1=[0, 0], xy2=[0, 0], xy3=[0, 1.4])
shadow = (gz.circle(r=(1 - coef / 4), fill=shadow_gradient)
.scale(r, r / 2).translate((x, ground + r / 2)))
shadow.draw(surface)
ball = gz.circle(r=1, fill=gradient).scale(r).translate((x, y))
ball.draw(surface)
return surface.get_npimage()
clip = mpy.VideoClip(make_frame, duration=D)
clip.write_gif("bouncingball.gif", fps=25, opt="OptimizePlus")
示例5 齿轮 旋转
import gizeh as gz
import moviepy.editor as mpy
import numpy as np
W, H = 256, 256
DURATION = 2.0
NDISKS_PER_CYCLE = 8
SPEED = .05
def make_frame(t):
dt = 1.0 * DURATION / 2 / NDISKS_PER_CYCLE # delay between disks
N = int(NDISKS_PER_CYCLE / SPEED) # total number of disks
t0 = 1.0 / SPEED # indicates at which avancement to start
surface = gz.Surface(W, H)
for i in range(1, N):
a = (np.pi / NDISKS_PER_CYCLE) * (N - i - 1)
r = np.maximum(0, .05 * (t + t0 - dt * (N - i - 1)))
center = W * (0.5 + gz.polar2cart(r, a))
color = 3 * ((1.0 * i / NDISKS_PER_CYCLE) % 1.0,)
circle = gz.circle(r=0.3 * W, xy=center, fill=color,
stroke_width=0.01 * W)
circle.draw(surface)
contour1 = gz.circle(r=.65 * W, xy=[W / 2, W / 2], stroke_width=.5 * W)
contour2 = gz.circle(r=.42 * W, xy=[W / 2, W / 2], stroke_width=.02 * W,
stroke=(1, 1, 1))
contour1.draw(surface)
contour2.draw(surface)
return surface.get_npimage()
clip = mpy.VideoClip(make_frame, duration=DURATION)
clip.write_gif("齿轮旋转.gif", fps=20, opt="OptimizePlus", fuzz=10)
示例5 旋转字
import gizeh as gz
import moviepy.editor as mpy
import numpy as np
W, H = 300, 75
D = 2 # duration in seconds
r = 22 # size of the letters / pentagons
gradient = gz.ColorGradient("linear", ((0, (0, .5, 1)), (1, (0, 1, 1))),
xy1=(0, -r), xy2=(0, r))
polygon = gz.regular_polygon(r, 5, stroke_width=3, fill=gradient)
def make_frame(t):
surface = gz.Surface(W, H, bg_color=(1, 1, 1))
for i, letter in enumerate("GIZEH"):
angle = max(0, min(1, 2 * t / D - 1.0 * i / 5)) * 2 * np.pi
txt = gz.text(letter, "Amiri", 3 * r / 2, fontweight='bold')
group = (gz.Group([polygon, txt])
.rotate(angle)
.translate((W * (i + 1) / 6, H / 2)))
group.draw(surface)
return surface.get_npimage()
clip = mpy.VideoClip(make_frame, duration=D)
clip.write_gif("gizeh.gif", fps=20, opt="OptimizePlus")
其他示例
更多示例请参考
https://zulko.github.io/blog/2014/09/20/vector-animations-with-python/
其他:
目前该库还是停留在较早时期,可能作者转到其他方向了,感谢作者提供如此美好的软件。
项目开发、代码讲解、疑难问题、环境搭建 请联系:gaoyue_13
微信搜一搜:逮猫大兄弟。感谢支持~