Converter SVG animado em filme

21

Eu tenho um SVG animado e gostaria de transformá-lo em um filme (uma série de fotos também faria). A animação é reproduzida em navegadores webkit (Safari, Chrome) e na do Batik squiggle ). Tentei capturá-lo com um capturador de tela. mas o filme acaba bem irregular.

Existe uma boa ferramenta para isso?

Aqui está um exemplo de animação:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%">
    <rect id="BB" x="0" y="0" height="100%" width="100%" fill="white"/>
    <g id="firstone" stroke="black">
        <g id="g3" fill="none" stroke-width="2">
            <animateTransform attributeName="transform" type="rotate" dur="5s" from="360 100 100" to="0 100 100" repeatCount="indefinite"/>
            <g id="g2">
                <ellipse id="g1" cx="100" cy="100" rx="75" ry="75">
                </ellipse>
                <g id="sec">
                    <line x1="100" y1="100" x2="45" y2="45" style="stroke: rgb(99, 99, 99); stroke-width: 6;"/>
                </g>
            </g>
        </g>
        <g id="pit">
            <line x1="100" y1="175" x2="100" y2="200" style="stroke: red; stroke-width: 6;"/>
        </g>
    </g>
</svg>
Benjamin Wohlwend
fonte
2
Existe um conversor SVG para APNG ( littlesvr.ca/apng/svg2png ), provavelmente alguma outra ferramenta pode ser usada para converter do APNG em um filme ou separar os quadros.
kartikmohta
1
@kartikmohta: adicione isso como resposta.
Caracol mecânico

Respostas:

4

Você já tentou usar o squiggle para exportar uma série de quadros? Percebi que era difícil fazer com que sua linha ficasse exatamente onde eu queria que fosse para configurar corretamente uma série de quadros. No entanto, depois de ter isso, você pode usar o imagemagick - aparentemente minha resposta favorita esta semana ;-) para transformá-lo da maneira que quiser.

Supondo que cada um deles salve os quadros como frame01.svg, frame02.svg, etc. Então, isso:

convert -delay 5 -loop 0 frame??.svg animated.gif

criará um único gif animado a partir de seus quadros que fará um loop para sempre, 5 ms entre os quadros.

convert converterá svg para, mas o imagemagick não processa a tag animateTransform, portanto, qualquer saída é estática.

Atualização: achei o rabisco tão doloroso de se trabalhar (pelo menos, tentando parar a animação no local certo para capturar uma imagem, fiquei com vergonha de ter sugerido isso!

Aqui está um script bash usando o imagemagick para converter seu svg em um gif animado: Antes de executar este script, divido seu exemplo svg em 2 partes: bg.svg contém o elipse e o elemento 'pit' e hand.svg contém apenas o 'sec' elemento

`#!/bin/bash`

rm *.png
rm anim.gif

convert bg.svg -crop 200x200+0+0 +repage bg.png
convert hand.svg -crop 200x200+0+0 +repage -transparent white hand.png

for ((i=1; i<=359; i=i+3))
do
  convert hand.png -gravity center -rotate $i tmp.png
  n=`printf "%03d" $i`
  composite -gravity center tmp.png bg.png hand${n}.png
  rm tmp.png
done

convert -delay 1  -loop 0 hand*.png anim.gif

~
Tenho certeza de que alguém mais esperto do que eu poderia descobrir como mesclar o converso e combinar tudo em uma única etapa sem também girar o bg.png, mas é isso que você ganha de graça ;-)

Além disso, queria manter isso simples, apenas no caso de precisar ser reimplementado como um arquivo bat do Windows.

O i = i + 5 é um compromisso entre a aparência da animação e o tamanho do arquivo.

Nota: Mesmo com o atraso 1 (1 ms entre os quadros), o Firefox não moveria a mão em um círculo completo em 5 segundos. Foi mais perto de 10 segundos.

E aqui está o que o script produziu

DaveParillo
fonte
4

Eu encontrei uma maneira de criar a série de imagens com a ajuda do canvg . Para executar a página a seguir, você deve usar um script modificado de canvg.js, para que a função draw esteja acessível.

Alterações no script canvg.js (v1.0):

Na linha 2321, mude de:

var draw = function() {

para:

svg.draw = function() {

Nas linhas 2361 e 2390, mude de:

draw();

para:

svg.draw();

Script da minha geração:

<html>
<head>
<script type="text/javascript" src="rgbcolor.js"></script> 
<script type="text/javascript" src="canvg.js"></script> 
<script type="text/javascript">

loadSVG = function() {
  canvg('canvas', '<animated SVG>', { ignoreMouse: true, ignoreAnimation: true });
}

function RenderNext(delta) {
    var c = document.getElementById("canvas");
    var svg = c.svg;

    for (var i=0; i<svg.Animations.length; i++) {
        svg.Animations[i].update(delta);
    }
    svg.draw();
}

function CreateImage(imgStr) {
    var oImg=document.createElement("img");
    oImg.setAttribute('src', imgStr);
    return oImg;
}

function start() {
    var c = document.getElementById("canvas");
    var result = document.getElementById("resultDiv");
    var maxDur = 5; // seconds
    var framerate = 5; // imgages per second

    for (var i = 0; i < framerate * maxDur; i++) {
        RenderNext(1000 / framerate);

        var oImg = CreateImage(c.toDataURL('image/png'));
        result.appendChild(oImg);
    }
}

</script>
</head>
<body onload="loadSVG()">

<canvas id="canvas" width="30px" height="30px"></canvas> 

<p>
<input type="button" id="start" value="Start" onclick="start()" /> 
</p>

<div id="resultDiv">
</div>

</body>
</html>
Manni
fonte
3

Se você estiver usando o FireFox, poderá experimentar o SVG Render Plug: http://adasek.cz/svgrender/

IOOI
fonte
Essa é uma boa sugestão. Mas não consigo descobrir como fazer com que a captura comece e termine quando a animação real começar e terminar.
posfan12