Convertir un SVG animé en film

21

J'ai un SVG animé et j'aimerais le transformer en film (une série d'images conviendrait également). L'animation se joue dans les navigateurs Webkit (Safari, Chrome) et dans le gribouillis de Batik . J'ai essayé de le capturer avec un capteur d'écran. mais le film se termine plutôt saccadé.

Y at-il un bon outil pour cela?

Voici un exemple d'animation:

<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
la source
2
Il existe un convertisseur SVG en APNG ( littlesvr.ca/apng/svg2png ). Un autre outil peut probablement être utilisé pour convertir l’APNG en film ou séparer les images.
kartikmohta
1
@kartikmohta: Ajoutez cela comme réponse.
Escargot mécanique

Réponses:

4

Avez-vous essayé d’utiliser squiggle pour exporter une série de cadres? J'ai trouvé difficile de faire passer votre ligne au même endroit que je le souhaitais pour pouvoir configurer correctement une série de cadres. Cependant, une fois que vous avez cela, vous pouvez utiliser imagemagick - apparemment ma réponse préférée cette semaine ;-) pour le transformer comme vous le souhaitez.

En supposant que vous enregistrez les images en tant que frame01.svg, frame02.svg, etc.

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

créera un seul gif animé à partir de vos images qui boucle en boucle, 5 ms entre les images.

convert convertira svg en, mais imagemagick ne traite pas la balise animateTransform, toute sortie est donc statique.

Mise à jour: j'ai trouvé le gribouillage si pénible (au moins, en essayant d'arrêter l'animation au bon endroit pour saisir une image, j'étais gêné de l'avoir même suggéré!

Voici un script bash utilisant imagemagick pour convertir votre svg en gif animé: Avant d'exécuter ce script, je scinde votre exemple svg en deux parties: bg.svg contient l'élément elipse et l'élément 'pit', et hand.svg contient uniquement l' élément 'sec' élément

`#!/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

~
Je suis sûr que quelqu'un de plus intelligent que moi pourrait comprendre comment fusionner le converti et le combiner en une étape sans faire pivoter le fichier bg.png, mais c'est ce que vous obtenez gratuitement ;-)

Aussi, je voulais garder cela simple, juste au cas où il devrait être réimplémenté en tant que fichier Windows bat.

I = i + 5 est un compromis entre l'aspect lisse de l'animation et la taille du fichier.

Remarque: Même avec -delay 1 (1 ms entre les images), Firefox ne déplacerait pas la main dans un cercle complet en 5 secondes. C'était plus proche de 10 secondes.

Et voici ce que le script a produit

DaveParillo
la source
4

J'ai trouvé un moyen de créer la série d'images à l'aide de canvg . Pour exécuter la page suivante, vous devez utiliser un script modifié de canvg.js dans lequel la fonction de dessin est accessible.

Changements dans le script canvg.js (v1.0):

À la ligne 2321, changer de:

var draw = function() {

à:

svg.draw = function() {

Aux lignes 2361 et 2390, changement de:

draw();

à:

svg.draw();

Mon script de génération:

<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
la source
3

Si vous utilisez FireFox, vous pouvez essayer SVG Render Plug: http://adasek.cz/svgrender/

IOOI
la source
C'est une bonne suggestion. Mais je ne vois pas comment faire pour que la capture commence et se termine lorsque l'animation commence et se termine.
Posfan12