Converter SVG animado para filme

20

Eu tenho um SVG animado e gostaria de transformá-lo em um filme (uma série de imagens também faria). A animação é reproduzida nos navegadores Webkit (Safari, Chrome) e no rabisco do Batik. Eu tentei capturá-lo com um capturador de tela. mas o filme acaba muito espasmódico.

Existe uma boa ferramenta para isso?

Veja 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>
    
por Benjamin Wohlwend 29.09.2009 / 16:36

3 respostas

3

Você já tentou usar o rabisco para exportar uma série de quadros? Eu achei um rabisco chato conseguir colocar sua linha exatamente onde eu queria que fosse para configurar corretamente uma série de quadros. No entanto, uma vez que você tem isso, você pode usar imagemagick - aparentemente minha resposta favorita esta semana ;-) para transformá-lo como quiser.

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

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

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

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

Atualização: Eu achei o rabisco tão doloroso de trabalhar (pelo menos tentando parar a animação no ponto certo para pegar uma imagem, fiquei envergonhada por ter até sugerido isso!

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

'#!/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 que alguém mais esperto do que eu poderia descobrir como mesclar o convertido e combinar tudo em um passo sem também rodar o bg.png, mas é isso que você ganha de graça; -)

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

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

Nota: Mesmo com -delay 1 (1 ms entre frames), 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

    
por 29.09.2009 / 23:27
4

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

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

Na linha 2321, mude de:

var draw = function() {

para:

svg.draw = function() {

Na linha 2361 e 2390, mude de:

draw();

para:

svg.draw();

Meu roteiro de 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>
    
por 02.11.2011 / 16:16
2

Se você estiver usando o FireFox, poderá testar o SVG Render Plug: link

    
por 25.02.2013 / 08:49

Tags