Wednesday, February 10, 2010

Georacing, démonstrateur de télévision interactive sur mobile

Dans le cadre du projet de recherche Georacing, nous avons mis en oeuvre un démonstrateur de télévision interactive sur mobile.
Georacing, c'est d'abord la capture en temps réel de la position de tous les coureurs d'une course cycliste. C'est ensuite l'exploitation, toujours temps réel, de ces données pour produire des images ou fournir des services.
Au sein de Telecom Paristech, nous avons proposé de diffuser tout ou partie de ces données en même temps que la vidéo de la course, vers des mobiles, afin de permettre à chacun d'avoir une vision personnalisée de la course en train de s'accomplir. Pour cela, nous avons étudié le potentiel de DIMS, MPEG-4 et SVG pour mettre en oeuvre des interactions graphiques sur de la télévision sur mobile.

Voici une vidéo de démonstration (la qualité est meilleure si on va la voir sur le site de Vimeo):

Démonstrateur du projet de recherche Georacing from moissinac on Vimeo.

Plus d'informations ici
eng.trimaran.com/Ingeneering/R-D/GeoRacing


Thursday, December 10, 2009

Manipulate SVG 2D Graphics programmatically with GPAC

If you publish a scientific work based on GPAC thank you to mention in the article, mentioning "GPAC: open source multimedia framework" (DOI: 10.1145/1291233.1291452)


GPAC is a framework, focused on multimedia development, developed by Telecom ParisTech. GPAC is an Open Source project hosted on sourceforge.

GPAC has excellent SVG support. (look at the Show grid implementations of SVG).

This note is a start point for a series on the use of the GPAC library for manipulating SVG documents programmatically. The first note is about creating a SVG scene by C program and its backup as a file.

Create SVG

Create a scenegraph

Basically, a SceneGraph? is the object used by the Gpac library to manipulate a graphic scene. The same object is used for MPEG-4 BIFS, Laser, SVG.

Declaration:

GF_SceneGraph * sg;

Object creation:

sg = gf_sg_new ();

Now we are ready to put things in the sg object.

Create the root of the SVG document

SVG elements are handled in the GPAC type SVG_Element. We will create such an element, which we call root as the root SVG document.

Declaration

SVG_Element * root;

Creation:

root = (SVG_Element *)gf_node_new(sg, TAG_SVG_svg);

Here, we show that we create the element in the scene graph sg created earlier and that the element created must be of type TAG_SVG_svg. The constants used are defined in the file nodes_svg.h. The constants name is constructed with the prefix TAG_SVG_ followed by the name of the corresponding SVG element. For example, TAG_SVG_circle for the element circle, TAG_SVG_text for the text element.

The object is created. As it is the root of our SVG document, this particular role must be reported to GPAC by the following call:

gf_sg_set_root_node(sg, (GF_Node *)root);

In addition, each object created should be recorded at its parent (we shall see later that this is useful in the reuse of objects). As the root has no parent, we pass NULL as parameter. The call is:

gf_node_register ((GF_Node *) root, NULL);

Finally, the root element of an SVG document must have at least one attribute that associates the SVG namespace.

setAttributeNS(root, NULL, "xmlns", "http://www.w3.org/2000/svg");

This procedure is built on the DOM model. As we are not in an object language, we can not write root.setAttributeNS(...); we pass the object as first parameter of the procedure. The other parameters are similar to those of setAttributeNS DOM. The second is the namespace attribute, the third is the attribute name, the fourth is the attribute value. We will return later on the second parameter, the namespace; for the moment we use the default namespace by passing NULL.

Now, an empty SVG document is ready to receive content.

Add content into the document

We'll add a circle in the document.

For this, we declare a SVG_Element:

SVG_Element *circle;

then we create it:

circle = (SVG_Element *)gf_node_new(sg, TAG_SVG_circle);

like we created the element .

We must add it to the list of children of the root:

gf_node_list_add_child(&root->children, (GF_Node *)circle);

Then, as before, register it with its parent:

gf_node_register((GF_Node *)circle, (GF_Node *)root);

Finally, we create a set of attributes that will define the circle

setAttributeNS (circle, null, "cx", "200");
setAttributeNS(circle, NULL, "cy", "100"); setAttributeNS (circle, null, "cy", "100");
setAttributeNS(circle, NULL, "r", "50"); setAttributeNS (circle, NULL, "r", "50");

And here we have an SVG document with a circle.

Generate the corresponding file


To create the file, GPAC has a mechanism called dumper which produces an image of a scene graph.

We declare a dump object:

GF_SceneDumper *dumper;

Then we create the SVG dumper:

dumper = gf_sm_dumper_new(sg, "test", ' ', GF_SM_DUMP_SVG);

The first parameter is the SVG scene graph which we will dump. The second parameter is the name of file to generate. The third character is the character used for indentation. The fourth is the type of representation we want to generate, here we are concerned only with dump SVG specified by the constant GF_SM_DUMP_SVG.

Finally, we start writing the file:

gf_sm_dump_graph(dumper, 0, 0);

The first parameter is obviously the dump created just before. The other two parameters have no interest in the case of SVG backup.

Finish properly

Finally, we must free the memory occupied by the scene and objects within it. For this one call (provided that the objects be properly integrated into the scene):

gf_sg_del (sg);

To be continued

In the next few notes, we discuss the display of the created SVG document, the creation of more complex scenes with multiple levels of nested elements, then we'll create a scene with internal and external links.

Thursday, June 11, 2009

Manipuler du graphique 2D SVG par programme avec GPAC

Si vous publiez un travail scientifique qui s'appuie sur GPAC, merci de mentionner GPAC en citant cet article "GPAC: open source multimedia framework" (DOI: 10.1145/1291233.1291452)

GPAC est un environnement de travail sur des développements multimédia porté par Telecom ParisTech. GPAC est un projet Open Source hébergé sur sourceforge.

GPAC a un excellent support de SVG. Voir la grille des implémentations de SVG.

Je démarre avec ce billet une série concernant l'utilisation de la librairie GPAC pour manipuler des documents SVG par programme. Ce premier billet porte sur la création par programme C d'une scène SVG et sa sauvegarde sous forme de fichier.

Créer un SVG



Créer un SceneGraph



A la base, l'objet manipulé par la librairie GPAC pour représenter une scène graphique est un SceneGraph. Ce même objet est utilisé pour du MPEG-4 BIFS, du Laser, du SVG.

La déclaration:
GF_SceneGraph *sg;

La création de l'objet:
sg = gf_sg_new();

Maintenant, nous sommes prêt pour mettre des choses dans l'objet sg.

Créer la racine du document SVG



Les éléments SVG manipulés dans GPAC sont de type SVG_Element. Nous allons créer un tel élément, que nous nommerons root, en tant que racine du document SVG.
La déclaration
SVG_Element *root;

La création:
root = (SVG_Element *)gf_node_new(sg, TAG_SVG_svg);

Ici, nous indiquons que nous créons l'élément dans la scène graphique sg créée précédemment et que l'élément créé doit être de type TAG_SVG_svg. Les constantes utilisées sont définies dans le fichier nodes_svg.h. Le nom des constantes est construit avec la racine TAG_SVG_ suivi du nom de l'élément SVG concerné. Par exemple, TAG_SVG_circle pour l'élément circle, TAG_SVG_text pour l'élément text.


L'objet est créé. Comme c'est la racine de notre document, ce rôle particulier doit être indiqué à GPAC par l'appel suivant:
gf_sg_set_root_node(sg, (GF_Node *)root);

En plus, chaque objet créé doit être comptabilisé au niveau de son parent (nous verrons plus tard que cela est utile dans des réutilisations d'objets). Comme la racine n'a pas de parent, on passe NULL comme paramètre. L'appel est donc: gf_node_register((GF_Node *)root, NULL);

Enfin, l'élément <svg> racine d'un document SVG doit posséder au moins un attribut qui lui associe le namespace SVG.
setAttributeNS(root, NULL, "xmlns", "http://www.w3.org/2000/svg");

Cette procédure est construite sur le modèle DOM. Comme nous ne sommes pas dans un langage objet, nous ne pouvons pas écrire root.setAttributeNS(...); nous passons l'objet comme premier paramètre de la procédure. Les autres paramètres sont similaires à ceux du setAttributeNS DOM. Le deuxième est le namespace de l'attribut, le troisième est le nom de l'attribut, le quatrième est la valeur de l'attribut. Nous reviendrons plus tard sur le deuxième paramètre, le namespace, pour l'instant nous utilisons le namespace par défaut en passant la valeur NULL.

Maintenant, un document SVG vide est prêt à recevoir du contenu.

Ajouter du contenu dans le document



Nous allons ajouter un cercle dans le document.
Pour cela, nous déclarons un SVG_Element:
SVG_Element *circle;

puis nous le créons:
circle = (SVG_Element *)gf_node_new(sg, TAG_SVG_circle);
à la façon dont nous avons créé l'élément <svg>.

Nous devons l'ajouter dans la liste des enfants de la racine:
gf_node_list_add_child(&root->children, (GF_Node *)circle);

Puis, comme précédemment, l'enregistrer auprès de son parent:
gf_node_register((GF_Node *)circle, (GF_Node *)root);

Enfin, nous créons un ensemble d'attribut qui vont définir le cercle: setAttributeNS(circle, NULL, "cx", "200");
setAttributeNS(circle, NULL, "cy", "100");
setAttributeNS(circle, NULL, "r", "50");

Et, voilà, nous avons un document SVG avec un cercle.

Générer le fichier correspondant



Pour créer le fichier, GPAC dispose d'un mécanisme nommé dumper qui permet de sauver une représentation d'une scène graphique.
Nous déclarons un objet dumper:
GF_SceneDumper *dumper;

Puis, nous créons l'objet:
dumper = gf_sm_dumper_new(sg, "test", ' ', GF_SM_DUMP_SVG);

Le premier paramètre est la scène pour laquelle nous créons un dumper. Le deuxième paramètre est le nom du fichier à générer. Le troisième caractère est le caractère utilisé pour l'indentation. Le quatrième est le type de représentation que nous souhaitons générer; ici, nous ne sommes concernés que par le dump SVG, spécifié par la constante GF_SM_DUMP_SVG.

Enfin, nous déclencons la sauvegarde proprement dite:
gf_sm_dump_graph(dumper, 0, 0);

Le premier paramètre est de façon évidente le dumper créé juste avant. Les deux autres paramètres n'ont pas d'intérêt pour le cas de la sauvegarde SVG.

Finir proprement



Enfin, nous devons libérer la mémoire occupée par la scène et les objets qui la composent. Pour cela, un appel suffit (pourvu que les objets aient correctement incorporés dans la scène):
gf_sg_del(sg);

A suivre



Dans les prochains billets, nous évoquerons l'affichage de la scène créée, la création de scènes plus complexe, avec plusieurs niveaux d'imbrication d'éléments, puis nous créerons une scène avec des liens internes et externes.

Tuesday, November 18, 2008

<use>, SVG and Opera

Une version française de cet article est disponible:
http://svgmpeg4.blogspot.com/2008/11/use-svg-et-opera.html

I'm currently testing the advanced possibilities of SVG. For my tests, I'm using mainly GPAC, Firefox and Opera; Safari also sometimes. You can find a comparison of implementations at this link, which is based on the test suite for SVG 1.2 defined by the W3C. Moreover, there is a state of the implementation of SVG in Firefox here. There is an equivalent for Opera here.

The <use element on an external link is an interesting possibility for animation, user interfaces, patterns ...

For example, you define a widget with id 'mywidget' in a svg named s1.svg. Then you can use it in another svg with the line:

This is a simple way to develop projects gradually in a structured way.

We will quickly find situations where there is a complex document with an external <use> which itself contains a <use>. For example, you run a widget with a <use>, as above, and this widget itself is defined with a <use> pointing to another file.

Following is an example used for testing, based on the structure of a cartoon-type svg: a scene uses a background, itself constructed from various elements.

Main.svg file:
<svg
xmlns: xlink = 'http://www.w3.org/1999/xlink'
xmlns: svg = 'http://www.w3.org/2000/svg'
xmlns = 'http://www.w3.org/2000/svg'
width ='800 'height ='600'
>
<use id='decor' xlink:href="decor.svg#decor"/>
</ svg>

File decor.svg (resume the previous tag svg)
<svg ...>
<use id='decor' xlink:href="bulle.svg#circ"/>
</ svg>

Bulle.svg file:
<svg ... >
<circle id='circ' cx='100' cy='100' r='50' fill='red'/>
</ svg>

This test works well in GPAC, but not in Firefox 3.0.1, or Opera 9.62.

For Firefox, the status page above said about <use>: "Only works for internal document references (bug 269482).", So the external references are not yet supported.

For Opera, the first level of external <use> works, contrary to what is said on the Opera site "Note: External references, eg, are not supported."

It appears that the lack of common support for external <use> prevents the time when we will systematically structure SVG scenes with <use>.

I think I will continue to structure scenes with use and make a xslt transformation seeking use in a document to replace the content. To be continued ...

Use, SVG et Opera

An english version of this article is available:
http://svgmpeg4.blogspot.com/2008/11/svg-and-opera.html

Actuellement, je teste des possibilités assez avancées de SVG. Pour mes tests, j'utilise principalement GPAC, Firefox et Opera et quelquefois aussi Safari. On peut trouver un comparatif des implémentations à ce lien; ce comparatif repose sur la suite de tests pour SVG 1.2 définie par le W3C. Par ailleurs, on peut trouver un état de l'implémentation de SVG dans Firefox ici. On trouve une page équivalente pour Opera ici.

L'utilisation de l'élément <use> portant sur un lien externe est une possibilité intéressante pour les animation, les interfaces utilisateurs, les schémas...

Par exemple, vous définissez une sorte de widget avec un id 'monwidget'dans un svg nommé s1.svg. Ensuite, vous pouvez l'utiliser dans un autre svg avec la ligne:
<use xlink:href="s1.svg#monwidget" />
Cela constitue une façon simple de développer des projets peu à peu de façon structurée.

On imagine bien qu'assez vite on va se retrouver dans des situations où on construit un document complexe avec un <use> externe qui lui-même contient un <use>. Par exemple, vous exploitez un widget avec un <use>, comme ci-dessus, et ce widget lui-même est défini avec un <use> pointant vers un autre fichier.

Voilà un exemple utilisé pour les tests, basé sur une structuration de type dessin animé: une scéne utilise un décor, lui-même construit à partir de divers éléments.

Fichier main.svg:
<svg
xmlns:xlink='http://www.w3.org/1999/xlink'
xmlns:svg='http://www.w3.org/2000/svg'
xmlns='http://www.w3.org/2000/svg'
width='800' height='600'
>
<use id='decor' xlink:href="decor.svg#decor"/>
</svg>

Fichier decor.svg (reprendre la balise svg précédente)
<svg ...>
<use id='decor' xlink:href="bulle.svg#circ"/>
</svg>

Fichier bulle.svg:
<svg ... >
<circle id='circ' cx='100' cy='100' r='50' fill='red'/>
</svg>

Ce test fonctionne bien dans GPAC, mais ni dans Firefox 3.0.1, ni dans Opera 9.62.

Pour Firefox, la page de status mentionnée plus haut dit au sujet de use: "Only works for internal document references (bug 269482).", donc les références externes ne sont pas encore supportées.

Pour Opera, le premier niveau de <use> externe fonctionne, contrairement à ce qui est dit sur le site d'Opera "Note: External references, e.g. <use xlink:href="http://www.mydomain.com/util.svg#rects">, are not supported."; il semble que Opera ne sait pas cascader les use, ce qui, concrètement, empêche pour l'instant d'en avoir un usage systématique pour la structuration des scènes.

Je crois que je vais continuer à structurer les scènes avec des use et faire une transformation xslt qui cherche les use dans un document pour les remplacer par le contenu correspondant. A suivre...

Wednesday, November 12, 2008

Link and animation

We discuss here about links from a SVG page to another page.

Une version française de cet article se trouve à http://svgmpeg4.blogspot.com/2008/11/lien-sur-animation.html.

The basic method is to surround a set of graphics primitives by <a ...>, a similar tag to html tag <a ...>. This allows for example to move from one page to another on a click on any part of the group by the primitive surrounded by <a>.

But, we would like to go further: a click on an element triggers an animation and, at the end of this animation, we go to another SVG page.

There is no simple way to do that.

Combined with the animated element which has the 'anim1' id, I'll add the following:
<ev:listener target='anim1' event='endEvent' handler='#toOtherSVG' />

So when the endEvent will be generated for the animation, the handler named 'toOtherSVG' will be executed.

The handler can be defined as follows:
<handler xml:id='toOtherSVG' type="application/ecmascript">
gotoLocation ( 'otherPage.svg');
</ handler>

There is potentially another method that would be feasible in the future. It is syntactically correct, but its operation is not specified by the current standard (even in the draft Tiny 1.2). As a result, SVG viewers may have a different behavior.

Suppose we have the following line
<ev:listener event="'endEvent'" handler="'#toOtherSVG'">

as before. But the element with id 'toOtherSVG', is not a classic handler but:
<a id="'toOtherSVG'" href="'otherPage.svg'">
This syntax is correct in SVG Tiny 1.2, but the behavior of the tag <a> as a target of the event is not defined. It would suffice to establish that if <a> tag is the target of an event, we follow the link defined by the tag.

Perhaps for a coming release of the SVG specification?

Lien sur animation

La question abordée ici est celle des liens d'une page SVG vers une autre page.

An english version of this article is available:
http://svgmpeg4.blogspot.com/2008/11/link-and-animation.html

La méthode de base est d'entourer un ensemble de primitives graphiques par une balise <a ...>, analogue à la balise <a ...> du html. Cela permet par exemple de passer d'une page à une autre sur un clic sur n'importe quelle partie du groupe de primitives ancadrées par le <a>.

Mais, cherchons à aller plus loin: un clic sur un élément déclenche une animation et, à la fin de cette animation, on passe à une autre page SVG.

Rien ne permet cela de façon directe.

Associé à l'élément animé d'id 'anim1', je vais ajouter l'élément suivant:
<ev:listener target='anim1' event='endEvent' handler='#versAutreSVG' />

Ainsi, quand l'évènement de fin d'animation va être généré, le handler nommé 'versAutreSVG' va être exécuté.

Le handler peut être défini ainsi:
<handler xml:id='versChambre' type="application/ecmascript">
gotoLocation('autrePage.svg');
</handler>

Il y a potentiellement une autre méthode qui serait envisageable dans le futur. Elle est correcte syntaxiquement, mais son fonctionnement n'est pas spécifié par la norme actuelle (même dans le projet Tiny 1.2). Peut-être pourra-t-on l'introduire par la suite. Il en résulte que des afficheurs SVG différents pourraient avoir un comportement différent.

Supposons qu'on a
<ev:listener event='endEvent' handler='#versAutreSVG' />

comme précédemment. Mais que l'objet d'id versAutrePage, n'est pas un handler classique mais:
<a id='versAutrePage' xlink:href='autrePage.svg' />
Cette syntaxe est correcte dans SVG Tiny 1.2, mais le comportement de la balise <a> en tant que cible de l'évènement n'est pas défini. Il suffirait de définir que si une balise a est la cible d'un évènement, on suit le lien défini par la balise.

Peut-être pour une prochaine version de la spécification SVG?

Thursday, October 25, 2007

SVG dans Google Maps

Je viens de découvrir avec surprise que sur un téléphone P990i de Sony Ericsson, l'application Google Maps utilise une applet qui déclare utiliser le produit Tinyline.

Et qu'est-ce que Tinyline: un player SVG.

J'en conclue que Google Maps, au moins sur mobile, s'appuie sur SVG. Une grande bonne nouvelle pour cette excellente technologie.

Monday, June 25, 2007

Comment GZIP traite vos SVG?

Je vous présente ici quelques résultats assez paradoxaux sur l'exploitation de GZIP combinée à du SVG. Ces résultats peuvent surement être transposés pour toute combinaison de GZIP avec une représentation XML.

GZIP et SVG

GZIP peut être utilisé de plusieurs façons pour comprimer du SVG.

D'abord, le support de GZIP est encouragé pour les players SVG 1.1 et requis pour les players SVG 1.2 Tiny; ces players doivent pouvoir lire un document SVG zippé, le décompresser, puis l'interpréter comme s'il n'avait pas été compressé.

La deuxième méthode fonctionne pour des documents SVG auxquels le player accède via le Web. Il est possible de régler le serveur pour qu'il comprime en GZIP certains types de fichiers lorsqu'il les envoie à un client qui supporte la compression GZIP. Cela est alors indépendant de la norme SVG et peut s'appliquer à de nombreux types de fichiers.

Optimiser la taille d'un SVG

L'exploitation de GZIP assure une compression et permet donc d'optimiser la quantité de données transmises.

On peut être tenté d'optimiser la taille du fichier au niveau du SVG avant le passage par GZIP. On peut par exemple éliminer des espaces. Et, là commencent les surprises!

Par exemple, j'ai pris le fichier SVG qui figure ici. Il fait 274 Ko. En l'ouvrant avec Inkscape, puis le sauvant en GZIP, il passe à 106 Ko. En supprimant des décimales sur de nombreuses coordonnées, l'apparence du SVG ne change pas pour une utilisation plein écran et le fichier passe à 244 Ko. En ouvrant ce dernier avec Inkscape et en le sauvant en GZIP, on obtient un fichier de 115 Ko!!!

Ainsi, en optimisant la taille de la source SVG, on obtient un plus mauvais résultat en GZIP.

Comment optimiser la compression d'un SVG en GZIP? Avez-vous des idées?