Julia의 애니메이션 작동 방식
소개
애니메이션으로 해보고 싶은 것이 있으므로, 기존의 코드로 어떠한 구현이 이루어지고 있는지를 조사한다.
특히 Plots.jl 1의 animation.jl을 읽습니다.
htps : // 기주 b. 코 m/쥬아아 Pぉts/P㎉ts. jl/bぉb/마s r/src/아니마치온. jl
우선 개요에서
Animation을 사용하는 방법
일반적인 사용법
anim = @animate for i in 1:10
plot(t->sinpi(t+i/5), range(0, 2, length=100))
end
#gif(anim, "sin.gif", fps=10)
매크로를 확장하면?
의미적으로는 다음의 코드가 된다.
anim = Animation()
for i in 1:10
plt = plot(t->sinpi(t+i/5), range(0, 2, length=100))
frame(anim, plt)
end
보다 정확하게는, @animate
의 부분을 @macroexpand
하면 매크로 전개 후의 코드를 얻을 수 있으므로 확인하자.
# gensym を使って変数名を生成した結果、 var"##tag#番号" という変数が得られる?
var"##anim#576" = Animation()
global var"##counter#577" = 1
for i = 1:10
plot((t->begin
sinpi(t + i / 5)
end), range(0, 2, length=100))
# 例えば 10 フレームごとにプロットする場合は var"##counter#577" を使って条件分岐する
if true
frame(var"##anim#576")
end
global var"##counter#577" += 1
end
var"##anim#576"
plt
가 명시되어 있지 않지만, 현재 플롯을 보관 유지하는 변수 CURRENT_PLOT
가 암묵적으로 사용된다 ( current()
를 통해서 불려 간다).
htps : // 기주 b. 코 m/쥬아아 Pぉts/P㎉ts. jl/bぉb/까지 r/src/pぉt. jl
처리 흐름
Animation을 사용하는 방법
일반적인 사용법
anim = @animate for i in 1:10
plot(t->sinpi(t+i/5), range(0, 2, length=100))
end
#gif(anim, "sin.gif", fps=10)
매크로를 확장하면?
의미적으로는 다음의 코드가 된다.
anim = Animation()
for i in 1:10
plt = plot(t->sinpi(t+i/5), range(0, 2, length=100))
frame(anim, plt)
end
보다 정확하게는,
@animate
의 부분을 @macroexpand
하면 매크로 전개 후의 코드를 얻을 수 있으므로 확인하자.# gensym を使って変数名を生成した結果、 var"##tag#番号" という変数が得られる?
var"##anim#576" = Animation()
global var"##counter#577" = 1
for i = 1:10
plot((t->begin
sinpi(t + i / 5)
end), range(0, 2, length=100))
# 例えば 10 フレームごとにプロットする場合は var"##counter#577" を使って条件分岐する
if true
frame(var"##anim#576")
end
global var"##counter#577" += 1
end
var"##anim#576"
plt
가 명시되어 있지 않지만, 현재 플롯을 보관 유지하는 변수 CURRENT_PLOT
가 암묵적으로 사용된다 ( current()
를 통해서 불려 간다).htps : // 기주 b. 코 m/쥬아아 Pぉts/P㎉ts. jl/bぉb/까지 r/src/pぉt. jl
처리 흐름
주요 함수에 대해 자세히 알아보기
애니메이션
일련 PNG 관리
animation.jl"Represents an animation object"
struct Animation
dir::String
frames::Vector{String}
end
function Animation()
tmpdir = convert(String, mktempdir())
Animation(tmpdir, String[])
end
"Represents an animation object"
struct Animation
dir::String
frames::Vector{String}
end
function Animation()
tmpdir = convert(String, mktempdir())
Animation(tmpdir, String[])
end
frames::Vector{String}
하지만 프레임수를 기억하는 것이지만, 왜 이것이 단순한 정수가 아니고, 캐릭터 라인의 배열이 되어 있을까는 궁금해 생각했다. 시도해 보면 (기본적으로 immutable이 되는) 구조체라면 내부 변수를 변경할 수 없지만, 내부 배열이라면 그 요소를 변경할 수 있는 것이다. immutable 의 제한을 회피하기 위해서 이런 방법을 취하고 있는 것일까. dir
는 변경되지 않는 편이 좋은 것은 이해할 수 있고, 뭐 그런 것일까 우선은 납득했다.frame
PNG 1프레임 출력
animation.jl
"""
frame(animation[, plot])
Add a plot (the current plot if not specified) to an existing animation
"""
function frame(anim::Animation, plt::P=current()) where P<:AbstractPlot
i = length(anim.frames) + 1
filename = @sprintf("%06d.png", i)
png(plt, joinpath(anim.dir, filename))
push!(anim.frames, filename)
end
여기서 보면 알 수 있듯이
Animation.frames
는 연속 PNG 파일 이름의 배열입니다.mp4
일련 PNG에서 mp4 만들기
엉망이지만 본질적으로이 두 줄로 집계됩니다.
fn
는 동영상의 파일 이름입니다.animation.jl
run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -pix_fmt yuv420p -y $fn`)
AnimatedGif(fn)
ffmpeg에 PNG 일련 번호 파일을 전달하여 mp4를 만듭니다.
그 후로 돌아온다
AnimatedGif
는 후술.바세. 처w
animation.jl
"Wraps the location of an animated gif so that it can be displayed"
struct AnimatedGif
filename::String
end
# write out html to view the gif... note the rand call which is a hack so the image doesn't get cached
function Base.show(io::IO, ::MIME"text/html", agif::AnimatedGif)
ext = file_extension(agif.filename)
write(io, if ext == "gif"
"<img src=\"$(relpath(agif.filename))?$(rand())>\" />"
elseif ext in ("mov", "mp4")
"<video controls><source src=\"$(relpath(agif.filename))?$(rand())>\" type=\"video/$ext\"></video>"
else
error("Cannot show animation with extension $ext: $agif")
end)
end
mp4 작성 후에 반환되는
AnimatedGif
는, 작성한 동영상의 패스를 보관 유지하고 있다.Jupyter 등으로 객체가 불리면(자), 그 형태에 맞는
Base.show
가 불린다. 위의 코드는 그때의 동작을 설명합니다. 요컨대, mp4 함수가 불려 가면 작성한 동영상을 Jupyter 상에 표시하는 것 같은 HTML 태그를 출력한다.Julia/Jupyter에서 이미지 표시 구현
htps : // 이 m / ㄹ리 my / ms / b5604b41247 8 7 00
주소에 난수를 부가하고 있는 것은, 캐시에 액세스 시키지 않고, 매회 직접 동영상 파일을 읽어들여 가게 하기 위한 테크닉인 것 같다.
Copyright (c) 2015: Thomas Breloff. ↩
Reference
이 문제에 관하여(Julia의 애니메이션 작동 방식), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Lirimy/items/8976bb4dcf5febad178e텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)