How to use Fabric.js to save a canvas as an image
Asked Answered
S

4

7

I have a Fabric.js prototype where people can load photos, text, and maps into the canvas. When they're done, I want them to be able to save the canvas as an image. I've tried using the standard:

canvasURL = canvas.toDataURL();
var image = new Image();
image.src = canvas.toDataURL("image/png");
$('#canvasContainer').replaceWith(image);

but it says that the canvas is tainted - I think because of the images (the method above works when it's just text). The error is:

Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. 

I can use Fabric's built-in method to save as SVG:

var canvasSVG = canvas.toSVG();
$('#canvasContainer').replaceWith(canvasSVG);

But I'd rather have a PNG/JPG. Any ideas?

Here's the Fabric.js documentation on serialization of the canvas.

http://fabricjs.com/fabric-intro-part-3/#serialization

Sanskritic answered 15/4, 2014 at 16:12 Comment(0)
K
4

The following must be true:

  1. Your cross-domain <img> elements must contain a crossorigin attribute.
  2. The server hosting the images must return an Access-Control-Allow-Origin header in the response with either a wildcard, or your specific domain as the value.
  3. The browser must support CORS on HTMLMediaElements, specifically HTMLImageElements. This is only currently possible in Chrome, Firefox, and Opera 15+
Kodok answered 15/4, 2014 at 16:23 Comment(1)
Note: This might be possible as well in Safari 7 as well.Kodok
I
3

This works well for me

function convertToImagen() {
  canvas.deactivateAll().renderAll();  
  window.open(canvas.toDataURL('png')); 
}
Illusionary answered 13/8, 2015 at 21:28 Comment(0)
C
2

As a side note, remember that if you're developing on your local computer rather on a server, you will probably see this security error message.

Corpsman answered 11/6, 2016 at 19:47 Comment(1)
I couldn't comment because of my reputation.Corpsman
C
-2

I faced the same issue, solved it by first passing the image url in an ajax call to a php file that would convert the image and return a data url

<?php
$content=file_get_contents($_POST['imageurl']);
echo "data:image/png;base64,". base64_encode($content);
?>

make sure to set the async:false for the ajax call

you can use the returned data to create your image object and load it on canvas.

Cloistered answered 21/4, 2014 at 9:47 Comment(3)
This is potentially dangerous advice. There is no reason to make this a synchronous call. Doing so opens up the the possibility of locking up the entire browser if this request takes a noticeable amount of time. Please consider changing your answer.Kodok
i have been working on an application where in images can be dragged and dropped from folders,browsers, or can be searched for from dropbox accounts or gdrives, i firstly identify the samedomain flag and pass the images for conversion if from a different domain, yes there is a average delay of 3.5 secs depending on the image size considering an average of 2mb with a download speed of 512kbps, but I also proportionately scale own the image to a reasonable size.This has worked well for me so far.please let me know your viewsCloistered
The bottom line is, never use synchronous Ajax requests in the browser outside of web workers. Nothing you are doing requires a synchronous call.Kodok

© 2022 - 2024 — McMap. All rights reserved.