Problems calling drawImage() with svg on a canvas context object in Firefox - javascript

I basically want to transform my SVG into a PNG image. So I turn the SVG into an SVG image and try to draw that on a canvas to be able to get it as a PNG via the toDataURL() method. This works fine in Chrome, but in Firefox it produces a very uninformative error: NS_ERROR_NOT_AVAILABLE
After searching and experimenting a bit, I tried a different SVG source and all of a sudden everything worked fine. Any ideas what could cause the method to work fine for the first SVG string but fail for the second one? How can I change my SVG so that it will work?
Fiddle: http://jsfiddle.net/3AXwb/
var image = new Image();
image.src = 'data:image/svg+xml,' + escape(xml);
image.onload = function () {
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext('2d');
document.getElementById('container').appendChild(canvas);
context.drawImage(image, 0, 0);
}

Add a width attribute to the outer <svg> element. E.g. width="450"
The first case has width and height, the second only height and Firefox currently required both width and height to be present.

Related

how to redraw modified image using canvas

let me explain you what I do. I need to draw bigg image near to 5000px to 2688px. So I can't draw whole image because in browser it's too long. I decided to add scroll bar to see whole image. The following script allows me to draw a part of canvas
var img = new Image();
img.onload = function(){
canvasW = 5376
canvasH = 2688
ctx.drawImage(img, 0,0, canvasW, canvasH);
};
img.src = "image.png";
Now imagine I want to apply effects like blur or brigthness, contrast etc, My canvas will change, so how can I redraw modified canvas (with effect and not the first one.
I tried to check on stackoverflow but the examples is to redraw image from the first one. I mean the drawing is not from a modifed canvas.
I tried to store base64 of my canvas and redraw by using base64 :
var image = new Image()
image.addEventListener('load', function() {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.drawImage(image, canMouseX, canMouseY, canvasW, canvasH);
})
image.src = bases64[bases64.length - 1]
It doesn't work because by storing base64 there is just a part of canvas that is redraw. If you want more details clone my repo on : https://github.com/wyllisMonteiro/draggingScroll/tree/master
I want to find a solution to redraw a modified canvas

Loading image into canvas - image scaled

I'm having a problem with loading image into canvas - the image is somehow scaled.
Background: I've got several canvases on my web page, I want to load images into them. When constructing, I'm not sure about the dimension, because the size depends on the screen size.
So I create div and canvas, use css to have it in the size that I want it to have and print an image onto the canvas. There would couple more things to do with the image (i.e. decide based on the ratio if I need to center it vertically or horizontally), but those are not really important at this point. The problem is that the image is rendered "zoomed".
Example: the javascript piece is here:
$("canvas").each(function() {
var context = $(this)[0].getContext('2d');
var img = new Image;
img.src = 'http://i67.tinypic.com/n38zdv.jpg';
$(img).load(function() {
context.drawImage(this, 0, 0);
});
//img will print 400 (correct, thats the width of the img)
//canvas will print based on the screen size (correct)
//img displayed in the canvas shows 300px out of 400px, it's zoomed (not correct)
$(this).parent().append(
'img width: '+img.width+
', canvas width: '+$(this).width());
});
I put the whole example with HTML and CSS to https://jsfiddle.net/7zdrfe58/11/.
I'm trying on Mac. Safari and Chrome work the same (i.e. with the zoom).
I would very appreciate help with this!! Thanks a lot
drawImage lets you specify the width and height of the image. You can get the canvas width like so:
$("canvas").each(function() {
var canvas = this;
var context = canvas.getContext('2d');
var img = new Image;
img.src = 'http://i67.tinypic.com/n38zdv.jpg';
$(img).load(function() {
context.drawImage(this, 0, 0, canvas.width, canvas.height);
});
});
Check out your working code here:
https://jsfiddle.net/ucxdLsq9/
The documentation of the drawImage signatures can be found here:
https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/drawImage
Give proper width and height to drawImage.
context.drawImage(this, 0, 0 ,300 ,160);
Updated Fiddle

canvas.toDataURL() gives "Security Error" in IE 11

I'm working on the browser-based tool for media distributors that require some manipulation with video.
I have HTML5 video player with video loaded from another domain (ex. http://video.com). Domain returns the following headers for the video (tries ...-Origin with * and with specific domain name):
Access-Control-Allow-Methods: GET
Access-Control-Allow-Origin: *
The video tag is like this:
<video crossorigin="anonymous" src="http://video.com/video.mp4"></video>
JS I run is the following:
// meida is a reference to <video> tag
var
imgData,
width = media.videoWidth,
height = media.videoHeight,
canvas = document.createElement("canvas"),
context = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;
context.fillRect(0, 0, width, height);
context.drawImage(media, 0, 0, width, height);
imgData = canvas.toDataURL('image/png'); // line where IE throws DOMException named 'Security error'
The code works in all browsers except IE family. I've tried it on IE 11.
I understand that in this case canvas becomes tainted while it should not.
Does anybody know any way to make it work? I saw some workarounds for images but it doesn't work in my case with video.
PS: I've seen the answer Canvas.toDataURL() working in all browsers except IE10 but it is quite old and is related to images. I hope things changed since then.
I was trying to export pdf of page which includes highcharts.
I was getting same problem with IE when trying to load svg data on canvas, same security error.
I fixed this issue using canvg.js
just include canvg library files,
Add canvas on html page,
<canvas id="canvas" width="1000px" height="600px"></canvas>
use below method,
canvg(document.getElementById('canvas'), xml);
It worked for me in all browsers including IE.
By using fabric js "Security Error" in IE 11 will be gone.
var
imgData,
width = media.videoWidth,
height = media.videoHeight,
canvas = document.createElement("canvas"),
fabCanvas = new fabric.Canvas('c'),
context = fabCanvas.getContext('2d');
canvas.width = width;
canvas.height = height;
fabCanvas.fillRect(0, 0, width, height);
fabCanvas.drawImage(media, 0, 0, width, height);
imgData = fabCanvas.toDataURL({format: "png"});

JavaScript Canvas Disappears After Changing Width

After running this code:
var inventoryCanvas = document.getElementById("inventoryCanvas");
inventoryCanvas.width = width2;
it executes properly, however the canvas disappears when I run it.
Does anyone know the reason for this?
There is no way to stop this as it is expected behavior, I had a similar problem and solved it by creating a hidden buffer canvas. Before resize you can copy your original canvas to this buffer, resize the old canvas then redraw from the buffer.
Heres a quick fiddle demonstrating it:
http://jsfiddle.net/5keo7g2r/
var canvas = document.getElementById('canvas'),
buffer = document.getElementById('buffer'),
context = canvas.getContext("2d"),
bufferContext = buffer.getContext("2d");
bufferContext.drawImage(canvas, 0, 0); //Make a copy of the canvas to hidden buffer
canvas.width = 50; //Resize
context.drawImage(buffer, 0, 0); //Draw it back to canvas

Canvas drawImage() dimensions from video and image / mask

I've got a container with a video element and a mask image over it, that looks like the following:
<div id="container">
<img id="mask" src="/images/mask.png" width="1078" height="1508" />
<video autoplay="" id="video"></video>
</div>
As you guys can see the mask image is 1078px width and 1508px height. The video element is also 1078px width, but just 807px height (it doesn't have to be longer).
The canvas element haves the same width and height. When I try taking a snapshot of the video and draw that snapshot and a copy of the mask image to the canvas both elements are stretched way outside the canvas bounding.
var context = canvas.getContext('2d');
// Draw video
context.drawImage(video, 0, 0);
// Get mask image and draw mask
maskObj.src = document.getElementById("mask").src;
context.drawImage(maskObj, 0, 0);
I know I can pass more parameters trough the drawImage() function, but I do not know what that other parameters are exactly for. This article says you can just pass width and height as a integer. But if I do the following:
context.drawImage(video, 0, 0, 1078, 807);
context.drawImage(maskObj, 0, 0, 1078, 1508);
It is still draws the elements way outside the canvas bounding.
Can't really find out what I'm doing wrong so all the help is appreciated.
Example;
The only way it should happen is if you set the size of your canvas with css. Try to change the size of your canvas with the html attributes, or maybe add this :
canvas.width = 1078;
canvas.height = 1508;
var context = canvas.getContext('2d');
The resolution of a canvas only depends on those attributes. The css width and height just stretches it.
all you got to do is to get the video dimensions and set your canvas width and height to those values like below:
var video = document.getElementById('video');
canvas.height = video.videoHeight;
canvas.width = video.videoWidth;
var context = canvas.getContext('2d');
context.drawImage(video, 0, 0, canvas.width, canvas.height);

Categories