¿Puedo convertir texto SVG a ruta pero reutilizar glifos?

14

Tengo un SVG con una gran cantidad de texto. Es un mapa de aparcamiento con números de espacio escritos en él. Muestro esto en un navegador web y, gracias a un pequeño error maravilloso en Firefox , el navegador muestra el texto incorrectamente. Abucheo.

Entonces convertí el texto a caminos. Estamos hablando de hasta 4000 etiquetas separadas. Tal vez 15,000 nuevas formas ahora son vectores. Son 4MB. Normalmente podría argumentar que esto se prestaría a la compresión, pero tengo que alinear este SVG en el HTML . Estoy agregando alteraciones CSS de forma dinámica y esta es la única forma en que tengo la posibilidad de compatibilidad con navegadores cruzados. De todos modos, la salida cruda —incluso fregada— de esto es demasiado grande para ser útil.

Lo que me sorprende aquí es que todos estos números espaciales comparten glifos comunes. De cero a nueve. ¿Por qué incluyo una definición de forma para cada instancia de cada número? ¿Puedo desduplicar estos?

Estoy usando Inkscape pero estoy abierto a sugerencias.

Oli
fuente
¿Hay alguna posibilidad de que pueda compartir el archivo SVG para que podamos experimentar con él?
JohnB
1
¿Qué es exactamente el error (captura de pantalla) y cómo lo exporta y carga en un navegador? Existe una buena posibilidad de que pueda solucionarlo con solo un poco de estilo CSS o un pequeño script en la página para corregir / reemplazar los elementos de texto. Si se trata de una visualización de mapa dinámica, es posible que desee convertirla en un mapa real: la mayoría de las bibliotecas de mapeo del navegador (y muchas basadas en datos) tienen un gran soporte para el etiquetado.
Brichins
1
Lo sentimos, el SVG no es mío para compartir (pertenece a un cliente) pero se conoce el error . Esencialmente significa que las fuentes en el SVG no se reducirán más allá de un punto ... Lo cual es un problema grave si te alejas completamente en un mapa con miles de espacios de estacionamiento numerados. Deben ser (por ejemplo) ~ 0.08pt y en realidad son 13pt.
Oli
1
Tiene el número de error incorrecto, en realidad está buscando este
Robert Longson, el
Es posible que desee probar esto en un subconjunto, pero ¿puede path|simplifyayudarlo? Una "s" en minúscula se convierte en una ruta de 28 puntos, simplifica la srops a 17, y superpone las versiones simplificadas y no simplificadas incluso con zoom para que una "s" llene la pantalla no hay diferencia.
Chris H

Respuestas:

6

El <use>elemento le permite reutilizar objetos definidos en otra parte del documento. Por ejemplo, podría definir cada glifo como a <symbol>y luego reutilizarlos varias veces. He aquí un buen artículo al respecto: Estructuración, agrupamiento y hacer referencia en SVG - La <g>, <use>, <defs>y <symbol>Elementos .

Sin embargo, no sé cómo hacerlo directamente en Inkscape, especialmente no para un montón de texto que ya tienes como texto. Puede que tenga que escribir un script para procesar posteriormente el SVG y encontrar todas las rutas que se pueden reutilizar.

Rahul
fuente
El <use>era lo que estaba pensando cuando le pregunté esto, las secuencias de comandos es el cómo. Parece tonto que no haya nada ahí fuera para duplicar el marcado casi idéntico.
Oli
@Oli no había nada ni siquiera para deducir un marcado idéntico ; Tuve que escribir el mío (y por idéntico me refiero al byte; los cifré y comparé los hashes)
Chris H
Pensé durante el almuerzo, y me parece que un guión (python) dentro de inkscape sería el camino a seguir. El guión comenzaría con el texto como texto, y lo reemplazaría con referencias a la <symbol>s (o parece que podría tener <def>sus glifos de texto a ruta
Chris H
4

Hay algunas opciones de compresión disponibles que ofrecerán diversos grados de éxito. Para probarlos, creé un archivo de arte que solo tenía mucho texto repetido. Sin expandir, el tamaño del archivo es 13.8 KB. Ampliado, el tamaño del archivo es 1,42 MB .

Buena opción: usar SVGZ - 46.5 KB

Guardar la ilustración ampliada como SVGZ me dio un archivo de salida de 46,5 KB, que es significativamente más pequeño que el SVG estándar. Tenga en cuenta que el soporte puede variar .

Mejor opción: comprimir con Scour - 21.1 KB

Scour es una herramienta que eliminará y optimizará su archivo SVG por usted. Usando el comando de "compresión máxima" scour -i input.svg -o output.svgz --enable-viewboxing --enable-id-stripping --enable-comment-stripping --shorten-ids --indent=none, la ilustración ampliada se redujo a 21,1 KB. ¡No muy lejos del tamaño original del archivo sin expandir!

JohnB
fuente
3
El fregado no se comprime, solo elimina la basura y, si bien es bastante bueno para mí (dada la gran cantidad de objetos), mi "4MB" fue post-fregado. El contenido comprimido sería excelente, pero, y debería haber mencionado esto antes, tengo que alinear el SVG para los problemas de orientación del navegador (y también los requisitos de manipulación de la interfaz). Lo sé, lo sé, es doloroso, pero confía en mí cuando digo que me duele más en este momento D:
Oli
Debería haber dicho que la parte de fregar scourno se comprime. Puede también lanzar el archivo a través de gzip para usted, pero el ID y el espacio en blanco cosas minimización es su principal concierto.
Oli
@Oli bien, de ahí mi elección cuidadosa de la palabra "optimizar" :) Eso es una lástima que tu archivo ya esté registrado ... ¡ack!
JohnB
Me metí un poco en Illustrator un poco; su salida SVG respeta los símbolos. Aquí hay un ejemplo rápido . Tomaría un poco de esfuerzo, pero es posible que pueda crear un guión de Illustrator que separe su texto en caracteres individuales y los reemplace con símbolos. El mayor obstáculo que veo sería lidiar con la rotación. Si todo el texto es paralelo al eje X, no parece difícil, pero tratar el texto en ángulo puede ser un desafío. Por supuesto, todo eso no es muy útil si no tiene Illustrator disponible
JohnB
3

Esta es una solución en el navegador o en el servidor

Hay muchas formas diferentes de optimizar los archivos SVG. Parece que ya lo has hecho bastante.

Algunos recursos que he encontrado muy útiles son un artículo de css-tricks que se centra en detalles muy específicos. Y específicamente, la herramienta que usa SVGO .

Si tiene muchas rutas repetidas, consideraría usar javascript para crear las formas dinámicamente. Hay un ejemplo aquí . Una dirección sería tener una función definida para cada glifo, y simplemente tener cada ruta dentro del elemento svg creado por una solicitud para esa función. O tome una cadena completa, y / o una matriz de argumentos, para crear su svg en línea. Esto, por supuesto, espera que sus rutas sean más largas que la longitud del código requerido para solicitar dicha función (suposición bastante fácil).

Luke
fuente
1
Si bien esta respuesta presenta múltiples soluciones posibles, SVGO parece más interesante. También podría ejecutarse en un archivo .svg para optimizarlo. Sin embargo, actualmente no parece deduplicar la ruta. Si el autor de la pregunta termina haciendo secuencias de comandos personalizadas de todos modos, puede ser una buena idea hacerlo como una mejora de SVGO.
jpa
@jpa deducir antes (o mientras) la conversión a rutas sería el camino a seguir, seguramente. Reemplace todas las instancias del texto char "1" con <use xlink:href="#digit_one">where digit_oneis a path
Chris H
@ChrisH No puedo ver por qué no se puede deducir después igual de bien. Simplemente normalice todas las rutas al origen en el punto de partida, tome hash, use eso para encontrar si la ruta ya ha ocurrido. Claro, no es tan elegante, pero debería funcionar y podría ser más fácil de implementar que tener que volver a implementar / descubrir toda la lógica de diseño del texto.
jpa
@jpa podría, pero si la normalización del origen introduce errores de redondeo, el hash no coincidiría. El guión en el que estoy pensando llamaría el texto a ruta de inkscape para diseñar las rutas de los personajes, pero luego las reemplazaría con referencias a un conjunto de maestros.
Chris H
@jpa y los errores de redondeo son reales. En un ejemplo de juguete, la primera curva cuadrática de un cero difiere en 1 en el sexto lugar decimal, suficiente para arruinar el hashing
Chris H
2

Aquí en un nivel muy alto es lo que debe hacer su script. Siéntase libre de usar su idioma y entorno preferidos, este es solo un punto de partida para una lógica que debería darle lo que está buscando.

  • Recorra todos los elementos de texto en el xml del SVG y para los que tienen texto numérico (los puntos de estacionamiento, no especifica si hay más texto en su svg), cambie la identificación creada automáticamente por Inkscape a una cadena con ese estacionamiento número del spot. Inkscape solo necesita ID únicos, genera ID no descriptivos, pero respetará y no cambiará las ID creadas por otro software o creadas o cambiadas manualmente por el usuario.
  • En una tabla, almacene las coordenadas x e y del elemento de texto de cada lugar de estacionamiento.
  • Ya sea en Inkscape o mediante secuencias de comandos, convierta todo el texto del lugar de estacionamiento en caminos.
  • Para los dígitos 0-9, agregue al archivo SVG una <defs>sección apropiada que defina la información de ruta para cada dígito.
  • Pase por todos los <g>espacios de estacionamiento y reemplácelos con un<use xlink:href="#digit" x=x y=y />
  • Lucro

Puedo prever algunas complicaciones con las que tendrás que lidiar, y buena suerte con ellas.

  • El bucle necesitará dividir la cadena de lugares de estacionamiento con 2 dígitos o más y el espacio apropiado entre el primer dígito y los dígitos posteriores puede ser complicado; esto dependerá en gran medida de las fuentes que esté utilizando.
  • No especifique en qué orientación están los lugares de estacionamiento ni si están incluso en configuraciones curvas. Debido a las compensaciones manuales x, y para números de 2 dígitos y mayores, es posible que necesite una lógica adicional para descubrir la 'orientación' de un lugar de estacionamiento y cómo espaciar correctamente las diferentes rutas de dígitos individuales desde el primero.

Espero que esto ayude. Buena suerte.

botwhytho
fuente