Comments (13)
Currently svg isn't directly supported but simply because we didn't find a good way to make use of it in animations. It would be fairly simple though to render the single images as svgs as it's supported by Luxor. You can search for PNG inside Javis and replace it with SVG. That should be all there is to it if you are only interested in the single frames in the temporary directory
from javis.jl.
Currently svg isn't directly supported but simply because we didn't find a good way to make use of it in animations. It would be fairly simple though to render the single images as svgs as it's supported by Luxor. You can search for PNG inside Javis and replace it with SVG. That should be all there is to it if you are only interested in the single frames in the temporary directory
Simply changing to .png
might not quite work like how they want exactly ...right ? , by the time we call Image.save to save it to tempdir
we have already rasterized the image into frame_image
, i dont know if Image.save will convert it back to svg , but even if it does you wont get the original vector image as you would have got if Luxor wrote the svg.
from javis.jl.
Hi @aburousan changing
act!(circles[i], Action(1:1, anim_translate(circles[i-1])))
with
act!(circles[i], Action(1:1, anim_translate(O, circles[i-1])))
Should fix the error, could you check if it does?
from javis.jl.
It's rendering but now it's showing new error
E:\>julia fourier.jl
#points: 643
TSP cost: 1851.3679707085373
Rendering frames...100%|████████████████████████████████████████████████████████████████████████| Time: 0:00:28
ERROR: LoadError: failed process: Process(`'C:\Users\Syeda Spandita Zaman\.julia\artifacts\ecb81e6429c089c1da802644fae337754832d534\bin\ffmpeg.exe' -loglevel panic -framerate 30 -i 'C:\Users\SYEDAS~1\AppData\Local\Temp\jl_t5RcVi/%10d.png' -i 'C:\Users\SYEDAS~1\AppData\Local\Temp\jl_t5RcVi/palette.png' -lavfi paletteuse -y 'E:\gifs/julia_logo_dft.gif'`, ProcessExited(1)) [1]
Stacktrace:
[1] pipeline_error
@ .\process.jl:531 [inlined]
[2] run(::Cmd; wait::Bool)
@ Base .\process.jl:446
[3] run
@ .\process.jl:444 [inlined]
[4] (::FFMPEG.var"#4#6"{Cmd})(command_path::String)
@ FFMPEG C:\Users\Syeda Spandita Zaman\.julia\packages\FFMPEG\OUpap\src\FFMPEG.jl:112
[5] (::JLLWrappers.var"#2#3"{FFMPEG.var"#4#6"{Cmd}, String})()
@ JLLWrappers C:\Users\Syeda Spandita Zaman\.julia\packages\JLLWrappers\QpMQW\src\runtime.jl:49
[6] withenv(f::JLLWrappers.var"#2#3"{FFMPEG.var"#4#6"{Cmd}, String}, keyvals::Pair{String, String})
@ Base .\env.jl:172
[7] withenv_executable_wrapper(f::Function, executable_path::String, PATH::String, LIBPATH::String, adjust_PATH::Bool, adjust_LIBPATH::Bool)
@ JLLWrappers C:\Users\Syeda Spandita Zaman\.julia\packages\JLLWrappers\QpMQW\src\runtime.jl:48
[8] #invokelatest#2
@ .\essentials.jl:716 [inlined]
[9] invokelatest
@ .\essentials.jl:714 [inlined]
[10] #ffmpeg#3
@ C:\Users\Syeda Spandita Zaman\.julia\packages\JLLWrappers\QpMQW\src\products\executable_generators.jl:21 [inlined]
[11] ffmpeg
@ C:\Users\Syeda Spandita Zaman\.julia\packages\JLLWrappers\QpMQW\src\products\executable_generators.jl:21 [inlined]
[12] #exe#2
@ C:\Users\Syeda Spandita Zaman\.julia\packages\FFMPEG\OUpap\src\FFMPEG.jl:111 [inlined]
[13] ffmpeg_exe
@ C:\Users\Syeda Spandita Zaman\.julia\packages\FFMPEG\OUpap\src\FFMPEG.jl:123 [inlined]
[14] render(video::Video; framerate::Int64, pathname::String, liveview::Bool, streamconfig::Nothing, tempdirectory::String, ffmpeg_loglevel::String, rescale_factor::Float64, postprocess_frames_flow::typeof(identity), postprocess_frame::typeof(Javis.default_postprocess))
@ Javis C:\Users\Syeda Spandita Zaman\.julia\packages\Javis\TCcr1\src\Javis.jl:350
[15] animate_fourier(options::NamedTuple{(:npoints, :nplay_frames, :nruns, :nend_frames, :width, :height, :shape_scale, :tsp_quality_factor, :filename), Tuple{Int64, Int64, Int64, Int64, Int64, Int64, Float64, Int64, String}})
@ Main E:\\fourier.jl:146
[16] main()
@ Main E:\\fourier.jl:185
[17] top-level scope
@ E:\\fourier.jl:188
in expression starting at E:\fourier.jl:188
from javis.jl.
Hi, this I believe might depend on the pathname you used but I can't find this out without seeing your code.
Could you share the exact code you use?
from javis.jl.
Basically the last line with render
as I assume everything else is from our Fourier example.
from javis.jl.
This is the code
using Javis, FFTW, FFTViews
using TravelingSalesmanHeuristics
function ground(args...)
background("black")
sethue("white")
end
function circ(; r = 10, vec = O, action = :stroke, color = "white")
sethue(color)
circle(O, r, action)
my_arrow(O, vec)
return vec
end
function my_arrow(start_pos, end_pos)
arrow(
start_pos,
end_pos;
linewidth = distance(start_pos, end_pos) / 100,
arrowheadlength = 7,
)
return end_pos
end
function draw_line(
p1 = O,
p2 = O;
color = "white",
action = :stroke,
edge = "solid",
linewidth = 3,
)
sethue(color)
setdash(edge)
setline(linewidth)
line(p1, p2, action)
end
function draw_path!(path, pos, color)
sethue(color)
push!(path, pos)
return draw_line.(path[2:end], path[1:(end - 1)]; color = color)
end
function get_points(npoints, options)
Drawing() # julialogo needs a drawing
julialogo(; action = :path, centered = true)
shapes = pathtopoly()
new_shapes = shapes[1:6]
last_i = 1
# the circles in the JuliaLogo are part of a single shape
# this loop creates new shapes for each circle
for shape in shapes[7:7]
max_dist = 0.0
for i in 2:length(shape)
d = distance(shape[i - 1], shape[i])
if d > 3
push!(new_shapes, shape[last_i:(i - 1)])
last_i = i
end
end
end
push!(new_shapes, shapes[7][last_i:end])
shapes = new_shapes
for i in 1:length(shapes)
shapes[i] .*= options.shape_scale
end
total_distance = 0.0
for shape in shapes
total_distance += polyperimeter(shape)
end
parts = []
points = Point[]
start_i = 1
for shape in shapes
len = polyperimeter(shape)
portion = len / total_distance
nlocalpoints = floor(Int, portion * npoints)
new_points = [
Javis.get_polypoint_at(shape, i / (nlocalpoints - 1)) for
i in 0:(nlocalpoints - 1)
]
append!(points, new_points)
new_i = start_i + length(new_points) - 1
push!(parts, start_i:new_i)
start_i = new_i
end
return points, parts
end
c2p(c::Complex) = Point(real(c), imag(c))
remap_idx(i::Int) = (-1)^i * floor(Int, i / 2)
remap_inv(n::Int) = 2n * sign(n) - 1 * (n > 0)
function animate_fourier(options)
npoints = options.npoints
nplay_frames = options.nplay_frames
nruns = options.nruns
nframes = nplay_frames + options.nend_frames
# obtain points from julialogo
points, parts = get_points(npoints, options)
npoints = length(points)
println("#points: $npoints")
# solve tsp to reduce length of extra edges
distmat = [distance(points[i], points[j]) for i in 1:npoints, j in 1:npoints]
path, cost = solve_tsp(distmat; quality_factor = options.tsp_quality_factor)
println("TSP cost: $cost")
points = points[path] # tsp saves the last point again
# optain the fft result and scale
x = [p.x for p in points]
y = [p.y for p in points]
fs = FFTView(fft(complex.(x, y)))
# normalize the points as fs isn't normalized
fs ./= npoints
npoints = length(fs)
video = Video(options.width, options.height)
Background(1:nframes, ground)
circles = Object[]
for i in 1:npoints
ridx = remap_idx(i)
push!(circles, Object((args...) -> circ(; r = abs(fs[ridx]), vec = c2p(fs[ridx]))))
if i > 1
# translate to the tip of the vector of the previous circle
act!(circles[i], Action(1:1, anim_translate(O, circles[i-1])))
end
ridx = remap_idx(i)
act!(circles[i], Action(1:nplay_frames, anim_rotate(0.0, ridx * 2π * nruns)))
end
trace_points = Point[]
Object(1:nframes, (args...) -> draw_path!(trace_points, pos(circles[end]), "red"))
return render(video; pathname = joinpath(@__DIR__, options.filename))
end
function main()
hd_options = (
npoints = 3001, # rough number of points for the shape => number of circles
nplay_frames = 1200, # number of frames for the animation of fourier
nruns = 2, # how often it's drawn
nend_frames = 200, # number of frames in the end
width = 1920,
height = 1080,
shape_scale = 2.5, # scale factor for the logo
tsp_quality_factor = 50,
filename = "julia_hd.mp4",
)
fast_options = (
npoints = 1001, # rough number of points for the shape => number of circles
nplay_frames = 600, # number of frames for the animation of fourier
nruns = 1, # how often it's drawn
nend_frames = 200, # number of frames in the end
width = 1000,
height = 768,
shape_scale = 1.5, # scale factor for the logo
tsp_quality_factor = 40,
filename = "julia_fast.mp4",
)
gif_options = (
npoints = 651, # rough number of points for the shape => number of circles
nplay_frames = 600, # number of frames for the animation of fourier
nruns = 2, # how often it's drawn
nend_frames = 0, # number of frames in the end
width = 350,
height = 219,
shape_scale = 0.8, # scale factor for the logo
tsp_quality_factor = 80,
filename = "gifs/julia_logo_dft.gif",
)
return animate_fourier(gif_options)
end
main()
from javis.jl.
Hi, you need to change this line:
return render(video; pathname = joinpath(@__DIR__, options.filename))
with something like
return render(video; pathname = "path2gif.gif")
Can you tell if this does it?
from javis.jl.
Thanks ... Now it's working like a charm...
If you don't mind, I have another question.
How can we save a particular frame of the animation as svg? And how can we make a Fourier plot for any random word(text)?
from javis.jl.
running `render(video,tempdirecory='moviedir',pathname="") will save each frame as .png in moviedir
as of now there is seems to be no way to get svg of a frame from render , the frame is returned rasterized for render
to stitch it.
(someone who knows the innards of Javis better than me plis confirm)
from javis.jl.
Hi, I also don't think it is possible right away, perhaps playing a bit with Javis code.
@aburousan would like to try and open a PR to fix the example? If you don't no worries I will do it! :)
from javis.jl.
Sure
from javis.jl.
Ah you're right I think before we added layer functionality this was actually as simple as I described but now it would be a bit more involved.
from javis.jl.
Related Issues (20)
- LaTeX without npm HOT 15
- [BUG] Irrational and Integer angles fail in rotation Actions
- [BUG] Documentation error
- Parallel gif rendering HOT 4
- [BUG] Javis breaks windows HOT 4
- Move liveview outside Javis HOT 1
- [BUG] Not clear what `point` is in `anim_rotate_around( angle , point)` HOT 3
- [BUG] Documenter "edit on github" points to master branch
- [BUG] render fails with StackOverflowError on Tutorial 1 HOT 1
- [BUG] keyword arguments do not match for latex()
- [BUG] Tutorial 6 code issue
- Allow editing multiple videos at the same time. HOT 3
- Two interesting ways to render LaTeX aside from MathJax HOT 1
- [BUG] Luxor automatically in scope
- [BUG] issue with follow_path not working if object start_pos is not origin
- Educational Entropy example
- [BUG] Animation action setting hue works on those created by box but not by JBox HOT 2
- Problem while precompiling Javis HOT 2
- [BUG] Javis.Background and Javis.@JShape undefined HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from javis.jl.