Browse Source

add option to rotate svg and animate the rotation in steps

master
phschoen 1 year ago
parent
commit
7d11169866
  1. 17
      Makefile
  2. 47
      render.py

17
Makefile

@ -1,9 +1,9 @@
inputs = $(wildcard *.svg)
outputs = $(inputs:%.svg=output/%_44100.wav)
outputs += $(inputs:%.svg=output/%_48000.wav)
outputs += $(inputs:%.svg=output/%_96000.wav)
outputs += $(inputs:%.svg=output/%_192000.wav)
# outputs = $(inputs:%.svg=output/%_44100.wav)
# outputs += $(inputs:%.svg=output/%_48000.wav)
# outputs += $(inputs:%.svg=output/%_96000.wav)
outputs += $(inputs:%.svg=output/%all.wav)
.PHONY: all
all: output ${outputs}
@ -23,6 +23,15 @@ output/%_96000.wav: %.svg
output/%_192000.wav: %.svg
./render.py -s 192000 -o $(@:%.svg=%_192000.wav) $<
output/%all.wav: %.svg
for number in {000..360..5} ; do \
./render.py -s 192000 -t 0.1 -o output/$(@F)_$$number.wav -r $$number $< ; \
done
sox output/$(@F)_*.wav $@
ffmpeg -f concat -safe 0 -i <( for f in output/$(@F)_*.wav; do echo "file '$$(pwd)/$$f'"; done ) output.wav
rm output/$(@F)_*.wav
.PHONY: clean
clean:
rm -rf output

47
render.py

@ -22,11 +22,20 @@
# ----------------------------------------------------------------------------
import sys
import math
import wave
import argparse
from svgpathtools import svg2paths
def rot_p(p_center, p, angle_d):
angle = math.radians(angle_d)
ox = p_center[0]
oy = p_center[1]
qx = ox + math.cos(angle) * (p[0] - ox) - math.sin(angle) * (p[1] - oy)
qy = oy + math.sin(angle) * (p[0] - ox) + math.cos(angle) * (p[1] - oy)
p = [qx, qy]
return p
def read_image(filename, path_steps, volume_percent):
def read_image(filename, path_steps, volume_percent, angle_d):
paths, attributes = svg2paths(filename)
path = paths[0]
if len(paths) > 1:
@ -37,15 +46,47 @@ def read_image(filename, path_steps, volume_percent):
points = [[path[0].start.real, path[0].start.imag]]
p_min = [points[0][0], points[0][1]]
p_max = [points[0][0], points[0][1]]
# find center
for segment in path:
p = [segment.end.real, segment.end.imag]
for i in range(0, 2):
if p[i] < p_min[i]:
p_min[i] = p[i]
if p[i] > p_max[i]:
p_max[i] = p[i]
p_center = [ p_min[0] + (p_max[0] - p_min[0] )/2 , p_min[1] + (p_max[1] - p_min[1] )/2]
# find min max for all rotatations
for segment in path:
p_org = [segment.end.real, segment.end.imag]
for a in range(0, 360, 5):
p = rot_p(p_center, p_org , a)
for i in range(0, 2):
if p[i] < p_min[i]:
p_min[i] = p[i]
if p[i] > p_max[i]:
p_max[i] = p[i]
p = [path[0].start.real, path[0].start.imag]
p = rot_p(p_center, p , angle_d)
points = [p]
# p_min = [points[0][0], points[0][1]]
# p_max = [points[0][0], points[0][1]]
for segment in path:
p = [segment.end.real, segment.end.imag]
p = rot_p(p_center, p , angle_d)
for i in range(0, 2):
if p[i] < p_min[i]:
p_min[i] = p[i]
if p[i] > p_max[i]:
p_max[i] = p[i]
points.append(p)
print("min={} max={}".format(p_min, p_max))
print("center={} ".format(p_center))
data = bytearray()
@ -109,11 +150,13 @@ def main():
help="Volume of output file in percent. Defaults to 100%%.")
parser.add_argument("-i", "--interpolate", dest="interpolate", default=10, type=int,
help="Steps on interpolated paths. Defaults to 10.")
parser.add_argument("-r", "--rotate", dest="angle_d", default=10, type=int,
help="angle to rotate Defaults to 10.")
args = parser.parse_args()
print(args)
wave = read_image(args.input, args.interpolate, args.volume)
wave = read_image(args.input, args.interpolate, args.volume, args.angle_d)
samplecount = int(len(wave) / 2 / 2) # stereo, int16
drawrate = args.samplerate / samplecount

Loading…
Cancel
Save