Image SVG dans JavaFX 2.2

Je suis nouveau sur JavaFX 2.2 et à partir de Maintenant je n'ai pas pu trouver un moyen d'Afficher des Images SVG dans mon application JavaFX 2.2. J'ai regardé Batik, mais ça n'a pas fait l'affaire pour moi car il se transforme en BufferedImages et non en javafx.ImageView .

est-il possible d'afficher une image SVG dans une application JavaFX? Ou pouvez-vous au moins exporter une image SVG depuis JavaFX? La fonction Node.snapshot() y aider d'une façon quelconque?

22
demandé sur SpaceCore186 2012-09-15 13:44:04

3 réponses

est-il possible d'afficher une image SVG dans une application JavaFX?

voici quelques options:

  1. créer un WebView et charger l'image svg dans le WebEngine de WebView.
  2. Le e(fx)clipse projet inclut une svg pour fxml converter (lien mort :().
  3. Ce plugin NetBeans convertit également svg pour fxml (lien mort :().
  4. vous pouvez utiliser une bibliothèque basée sur awt comme Batik ou svgsalamander et convertir le BufferedImage résultant en une Image JavaFX.
  5. JavaFX 2.2 inclut nativement le support de quelques chaînes minimales SVGPath (pas la spécification SVG complète).
  6. vous pourriez écrire un convertisseur qui rend le svg en utilisant les commandes JavaFX Canvas GraphicsContext .
  7. FranzXaver fournit un SVGLoader, dont l'usage est démontré dans la réponse à: charger le fichier SVG dans un bouton sur JavaFX

ou pouvez-vous au moins exporter une image SVG à partir de javafx?

cette fonctionnalité ressemble à un JavaFX Scène graphique svg converter. Bien que cela soit théoriquement possible, Je ne sais pas si quelqu'un a créé un tel outil.

fait le noeud de fonction.instantané() y aider d'une façon quelconque?

Node.snapshot () n'aidera pas à exporter une image svg à partir d'un graphique de scène JavaFX car svg est un format vectoriel et un snapshot de noeud est un format de mappage de bits.

I j'ai regardé Batik, mais ça n'a pas fait l'affaire pour moi car il se transforme en BufferedImages et pas en javafx.ImageView.

vous pouvez facilement convertir entre BufferedImages awt et des images javafx en utilisant SwingFXUtils .

en termes de performance - quelle voie recommanderiez-vous?

pour les svg complexes, plutôt que de rendre à partir de fxml, vous obtiendrez probablement mieux le rendu de performance à une image bitmapée ou le contexte graphique de toile. C'est parce que votre graphe de scène finira beaucoup plus simple, avec beaucoup moins de nœuds, ce qui signifie que javafx, auront beaucoup moins de travail à faire. Pour les SVG simples (<1000 noeuds générés), cela n'aura probablement pas trop d'importance.

convertit un SVG en FXML pour créer des instances de javafx.scène.forme.SVGPath?

partiellement. Plein spécification SVG couvre beaucoup plus de terrain que les formes de base. En outre, les gradients, effets, animations, etc. peuvent être exécutés par un SVG. Donc, si L'image SVG source inclut ces éléments supplémentaires, ils doivent aussi être convertis en FXML (du mieux qu'ils peuvent être, il y aura certains aspects de SVG tels que les scripts qui seraient difficiles à traduire en FXML).

à mon avis, la taille et la complexité de la spécification SVG font partie des raisons pour lesquelles aucune prise en charge directe du système D'image SVG complet n'est actuellement incluse dans L'API JavaFX core et, au lieu de cela, seule une fonctionnalité similaire limitée comme SVGPath est offerte. La mise en œuvre de SVG nativement dans L'API JavaFX core aurait été très coûteuse pour relativement peu de récompense par rapport à d'autres éléments souhaitables.

si c'est le cas, est-ce que #2 (et #3) et #5 ne seraient pas identiques?

Pas de. NetBeans et les outils Eclipse mentionnés aux numéros 2 et 3 étaient plus fonctionnels que les installations SVGPath mentionnées au numéro 5, car ces outils convertissaient d'autres aspects de la spécification SVG en équivalents FXML (par exemple, gradients, effets et transformations).

39
répondu jewelsea 2017-05-23 10:31:16

j'ai utilisé la classe de transcodeur ci-dessus pour créer un petit projet sur github qui ajoute le support SVG à JavaFX (JavaFX 8 cependant): javafxsvg 151940920"

après avoir appelé

SvgImageLoaderFactory.install();

vous pouvez utiliser SVG images n'importe où dans votre code Java ou CSS comme n'importe quel autre type d'image supporté.

20
répondu Jan Gassen 2015-04-14 13:47:41

JavaFX + Batik + Custom Transcoder

comme je n'ai trouvé nulle part un exemple complet d'utilisation de batik en conjonction avec JavaFX, je propose une solution complète ci-dessous.

noter que j'ai supprimé la manipulation d'exception (par exemple pour le TranscoderException ) pour la brièveté.

Vous pouvez accéder au code complet ici: https://gist.github.com/ComFreek/b0684ac324c815232556

  1. pour convertir un fichier SVG avec Batik en un BufferedImage , vous devez implémenter un transcodeur personnalisé:

    /**
     * Many thanks to bb-generation for sharing this code!
     * @author bb-generation
     * @link http://bbgen.net/blog/2011/06/java-svg-to-bufferedimage/
     * @link In case the link above is still down: https://web.archive.org/web/20131215231214/http://bbgen.net/blog/2011/06/java-svg-to-bufferedimage/
     */
    
    public class BufferedImageTranscoder extends ImageTranscoder {
    
        private BufferedImage img = null;
    
        @Override
        public BufferedImage createImage(int width, int height) {
            BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            return bi;
        }
    
        @Override
        public void writeImage(BufferedImage img, TranscoderOutput to) throws TranscoderException {
            this.img = img;
        }
    
        public BufferedImage getBufferedImage() {
            return img;
        }
    }
    
  2. utilisez le transcodeur pour générer un BufferedImage objet:

    BufferedImageTranscoder trans = new BufferedImageTranscoder();
    
    // file may be an InputStream.
    // Consult Batik's documentation for more possibilities!
    TranscoderInput transIn = new TranscoderInput(file);
    
    trans.transcode(transIn, null);
    
  3. Convertissez l'objet BufferedImage en un objet Image (de JavaFX):

    // Use WritableImage if you want to further modify the image (by using a PixelWriter)
    Image img = SwingFXUtils.toFXImage(trans.getBufferedImage(), null);
    
  4. attribuez finalement l'objet reçu précédemment à votre ImageView :

    imgView.setImage(img);
    
9
répondu ComFreek 2015-09-15 13:52:54