2010-11-18 25 views
8

Estoy tratando de convertir un archivo SVG generado por Raphael JS (y el usuario, ya que puede arrastrar y rotar las imágenes). Seguí este Convert SVG to image (JPEG, PNG, etc.) in the browser pero todavía no puedo conseguirlo.Problema al guardar como png un SVG generado por Raphael JS en un lienzo

Debe ser fácil, pero no puedo poner mi dedo en lo que me sale mal.

Tengo mi svg en un div con #ec como id y el del lienzo es #canvas.

function saveDaPicture(){ 
    var img = document.getElementById('canvas').toDataURL("image/png"); 
    $('body').append('<img src="'+img+'"/>'); 
} 
$('#save').click(function(){ 
    var svg = $('#ec').html(); 
    alert(svg); 
    canvg('canvas', svg, {renderCallback: saveDaPicture(), ignoreMouse: true, ignoreAnimation: true}); 
}); 

La alerta me da:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="600" height="512"> 
<desc>Created with Raphael</desc> 
<defs></defs> 
<image x="0" y="0" width="300" height="512" preserveAspectRatio="none" href="imageurl.jpg"></image> 
<rect x="168" y="275" width="52" height="70" r="0" rx="0" ry="0" fill="none" stroke="#000" stroke-dasharray="8,3" transform="rotate(21.91207728 194 310)" style="opacity: 1; display: none; " opacity="1"></rect> 
<circle cx="50" cy="50" r="50" fill="none" stroke="#000"></circle> 
<image x="358" y="10" width="39" height="138" preserveAspectRatio="none" href="imageurl2.png" style="cursor: move; "></image> 
<image x="397" y="10" width="99" height="153" preserveAspectRatio="none" href="imageurl3.png" style="cursor: move; "></image> 
<image x="184" y="286" width="10" height="10" preserveAspectRatio="none" href="imageurl4.png" style="cursor: pointer; opacity: 1; display: none; " opacity="1"></image> 
<image x="204" y="286" width="10" height="10" preserveAspectRatio="none" href="imageurl5.png" style="cursor: pointer; opacity: 1; display: none; " opacity="1"></image> 
<image x="170" y="277" width="48" height="66" preserveAspectRatio="none" href="imageurl6.png" style="cursor: move; opacity: 1; " r="50" opacity="1" transform="rotate(21.91207728 194 310)"></image> 
</svg> 

que es el xml del SVG y si creo canvg documentation, es bueno.

De todos modos, con este código, la variable img, que debería tener los datos de imagen convertidos, obtuvo los datos de un png vacío con las dimensiones de la svg.

La única cosa que supongo es que el SVG generado por JS Rafael no está bien formateado para canvg (como, href de image debería ser xlink:href si sigo the W3C recommandations)

Alguien tiene una idea sobre este problema? : D

+1

¿El lienzo de Canvg representa la imagen correctamente? ¿Puedes vincular un ejemplo en vivo con el que podría jugar? – jbeard4

+0

@Shikiryu ¿Encontró alguna solución? Tengo una [pregunta] similar (http://stackoverflow.com/questions/16556447/merge-images-from-raphael-svg) – vibskov

Respuesta

1

Trabajé con SVG - Edit y genere imágenes SVG, lo que hicimos fue instalar ImageMagic en el servidor (probablemente ya lo tenga instalado).

Una vez instalado, solo tiene que ejecutar un comando como "convertir foo.svg foo.png" en el terminal. Si está utilizando php, puede hacerlo:

shell_exec("convert image.svg image.png"); 

En php y hecho.

+0

Desafortunadamente, no tengo ImageMagick instalado en mi servidor, que se comparte, así que no puedo instalarlo tampoco. Sin embargo, es una buena pista si alguien tiene el mismo problema que el mío. +1 – Shikiryu

6

canvg acepta los datos SVG una ruta de archivo o una cadena de una sola línea

pero en su código, su están pasando el contenido HTML de la div #ec como

canvg('canvas', svg, {renderCallback: saveDaPicture, ignoreMouse: true, ignoreAnimation: true}); 

Tanto $.html() de jQuery y del DOM Los métodos innerHTML devuelven el contenido HTML de un elemento tal como está, por lo que probablemente se encuentre en varias líneas.

canvg interpreta esto de varias líneas de contenido HTML como una ruta de archivo,

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="600" height="512"> 

y trata de recuperar los datos desde la dirección URL incorrecta.

Así que el proceso de conversión de SVG a Canvas falló y esa es la razón por la que no obtiene la imagen como se esperaba.

Aquí está una versión actualizada que debe trabajar,

function saveDaPicture(){ 
    var img = document.getElementById('canvas').toDataURL("image/png"); 
    $('body').append('<img src="'+img+'"/>'); 
} 

$('#save').click(function(){ 
    var svg = $('#ec').html().replace(/>\s+/g, ">").replace(/\s+</g, "<"); 
          // strips off all spaces between tags 
    //alert(svg); 
    canvg('canvas', svg, {renderCallback: saveDaPicture, ignoreMouse: true, ignoreAnimation: true}); 
}); 
+0

Puede ser esto, ahora que lo señalas. ¿No hay forma de que JS haga una línea múltiple en una sola línea? – Shikiryu

+0

por supuesto, puedes convertir multilínea en línea simple, estoy actualizando mi respuesta –

2

svgfix.js va a resolver este error. echa un vistazo a esta publicación de blog Export Raphael Graphic to Image

+2

¡Hola Ignacio! Aquí en Stack Overflow, [las respuestas de solo enlace no se consideran respuestas] (http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers/8259 # 8259). A menos que lo complemente con algún código, su respuesta corre el riesgo de borrarse en la sección [faq # eliminación] en la eliminación, especialmente "* Las respuestas que no responden fundamentalmente a la pregunta pueden ser eliminadas. Esto incluye respuestas que son ... apenas más que un enlace a un sitio externo * " – jadarnel27

+2

que es una lástima, porque esta es la mejor respuesta – Homer6

+1

Solo un FYI, esto requiere un elemento' 'que no es generado por Raphael y no funciona en navegadores anteriores. Sin duda hay soluciones, pero tenlo en cuenta. – Terry