svg - batik jar
Imagen SVG en JavaFX 2.2 (3)
Soy nuevo en JavaFX 2.2 y hasta ahora no pude encontrar una manera de mostrar imágenes SVG en mi aplicación JavaFX 2.2. Eché un vistazo a Batik, pero no funcionó para mí, ya que se convierte en BufferedImages
y no en javafx.ImageView
.
¿Hay alguna manera de mostrar una imagen SVG en una aplicación JavaFX? ¿O puede al menos exportar una imagen SVG desde JavaFX? ¿La función Node.snapshot()
ayuda allí de alguna manera?
¿Hay alguna manera de mostrar una imagen SVG en una aplicación JavaFX?
Aquí hay algunas opciones:
- Cree una vista WebView y load la imagen svg en WebEngine de WebView.
- El proyecto e(fx)clipse incluye un convertidor svg a fxml (link now dead :().
- Este complemento de NetBeans también convierte svg en fxml (link now dead :().
- Puede usar una biblioteca basada en awt como Batik o svgsalamander y convertir la imagen Buffered resultante en una imagen JavaFX.
- JavaFX 2.2 de forma nativa incluye soporte para algunas cadenas de SVGPath mínimas (no la especificación completa de SVG).
- Puede escribir un convertidor que presente svg usando los comandos JavaFX Canvas GraphicsContext .
- FranzXaver proporciona un SVGLoader, cuyo uso se demuestra en la respuesta a: Cargue el archivo SVG en un botón en JavaFX
¿O puede al menos exportar una imagen SVG de javafx?
Esta característica suena como un convertidor JavaFX SceneGraph a svg. Si bien es teóricamente posible, no soy consciente de que alguien haya creado una herramienta de este tipo.
¿La función Node.snapshot () ayuda allí de alguna manera?
Node.snapshot() no ayudará con la exportación de una imagen svg desde un gráfico de escena JavaFX ya que svg es un formato basado en vectores y una instantánea de nodo es un formato de mapa de bits.
Eché un vistazo a Batik, pero no funcionó para mí, ya que se convierte en BufferedImages y no en javafx.ImageView.
Puede convertir fácilmente entre awt BufferedImages y javafx images usando SwingFXUtils .
En términos de rendimiento, ¿de qué manera recomendarías?
Para svg''s complejos, en lugar de renderizar desde fxml, probablemente obtendrás una mejor representación de rendimiento en una imagen de mapa de bits o contexto de gráficos canvas. Esto se debe a que su gráfico de escena terminará siendo mucho más simple, con muchos menos nodos, lo que significa que el tiempo de ejecución de javafx tendrá mucho menos trabajo por hacer. Para svgs simples (<1000 nodos generados), probablemente no importará demasiado.
Está convirtiendo un SVG a un FXML sobre la creación de instancias de javafx.scene.shape.SVGPath?
Parcialmente. La especificación SVG completa cubre mucho más terreno que las formas básicas. Además, los degradados, efectos, animaciones, etc. pueden ser realizados por un SVG. Entonces, si la imagen SVG de origen incluye esos elementos adicionales, entonces también deben convertirse a FXML (de la mejor manera posible, habrá algunos aspectos de SVG, como los scripts, que serían difíciles de traducir a FXML).
Supongo que el tamaño y la complejidad de la especificación SVG es uno de los motivos por los que actualmente no se ofrece soporte directo para el sistema de imagen SVG completo en la API central de JavaFX y, en cambio, solo se ofrece funcionalidad limitada limitada, como SVGPath. La implementación de SVG de forma nativa en la API central de JavaFX habría tenido un alto costo por una recompensa relativamente pequeña en comparación con otros elementos deseables.
Si ese es el caso, ¿los # 2 (y # 3) y # 5 no serían iguales?
No. Las herramientas NetBeans y Eclipse mencionadas en los n. ° 2 y n. ° 3 eran más funcionales que las SVGPath mencionadas en n. ° 5, ya que esas herramientas convertían aspectos adicionales de la especificación SVG a equivalentes FXML (p. Ej. Gradientes, efectos y transformaciones).
JavaFX + Batik + transcodificador personalizado
Dado que no he encontrado en ningún lado un ejemplo completo del uso de Batik junto con JavaFX, les proporciono una solución completa a continuación.
Tenga en cuenta que eliminé el manejo de excepciones (por ejemplo, para la excepción TranscoderException
) por brevedad.
Puede acceder al código completo aquí: https://gist.github.com/ComFreek/b0684ac324c815232556
Para convertir un archivo SVG con Batik en una
BufferedImage
, debe implementar un transcodificador personalizado:/** * 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; } }
Use el transcodificador para generar un objeto
BufferedImage
: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);
Convierta el objeto
BufferedImage
a un objetoImage
(desde JavaFX):// Use WritableImage if you want to further modify the image (by using a PixelWriter) Image img = SwingFXUtils.toFXImage(trans.getBufferedImage(), null);
Finalmente, asigna el objeto recibido previamente a tu
ImageView
:imgView.setImage(img);
Utilicé la clase de transcodificador anterior para crear un pequeño proyecto en github que agrega soporte SVG a JavaFX (JavaFX 8): javafxsvg
Después de llamar
SvgImageLoaderFactory.install();
puede usar imágenes SVG en cualquier parte de su código Java o CSS al igual que cualquier otro tipo de imagen admitida.