What I'm trying to do is draw svg image on canvas and then create a PNG image of this canvas.
Here is an example of what I do:
var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = function () {
ctx.drawImage(this, 0, 0, this.width, this.height);
var url = canvas.toDataURL("image/png");
}
img.crossorigin = "Anonymous"; //not sure this affects anything...
img.src="some image url"
When I set a source of png/jpeg image it works fine but then the src is of a svg image I get "Uncaught Error: SECURITY_ERR: DOM Exception 18" when calling "canvas.toDataURL("image/png")".
I don't understand what's the difference?
The same happens when I take an inline svg and render it inside the canvas and then try to create the png image. I don't have the code right now with me - I'll add it later if necessary.
I found a solution. Apparently canvas has another function to draw svgs "drawSvg" so I used it and it works.
Related
Currently, I have an async function that pulls in an image from a remote URL, to then draw it on a canvas. I made sure that the canvas is the same size of the listing image. Below is the code that is not working:
async function loadAndprocessListingImage(listingImageURL){
const listingImage = await loadImage(listingImageURL);
const width = listingImage.width;
const height = listingImage.height;
const canvas = createCanvas(width, height);
const context = canvas.getContext('2d');
context.drawImage(listingImage, width, height); <=== (Code fails here)
return canvas.toDataURL();
}
I can't get any error logs either, I just get a timeout. I am running a NodeJS lambda.
Canvas is being pulled in a layer.
I can write to the canvas, but I cannot draw the image onto the canvas.
I am trying to read a image and the result i want to get is the same when you use a HTML canvas "Uint8ClampedArray"? var imageData = ctx.getImageData(0, 0, width, height); I found a NPM lib canvas but i cant get it to install.
So is there a another way to go without using Canvas?
To strictly answer the question:
So is there a another way to go without using Canvas?
The issue is that, even if we can load an image binary data, we need to be able to parse its binary format to represent it as raw pixel data (ImageData/Uint8Array objects).
This is why the canvas module needs to be compiled when installed: it rely on and links to libpng, libjpeg and other native libraries.
To load a Uint8Array representing pixel raw data from a file, without canvas (or native library wrapper), will requires decoders running only in Javascript.
For e.g. there exist decoders for png and jpeg as third-party libraries.
Decoding PNG
Using png.js:
const PNG = require('png-js');
PNG.decode('./image.png', function(pixels) {
// Pixels is a 1d array (in rgba order) of decoded pixel data
});
Decoding JPEG
Using inkjet:
const inkjet = require('inkjet');
inkjet.decode(fs.readFileSync('./image.jpg'), function(err, decoded) {
// decoded: { width: number, height: number, data: Uint8Array }
});
https://github.com/gchudnov/inkjet
Do not realy know what i did to get canvas to work. I used pixel-util to set image data.
var pixelUtil = require('pixel-util'),
Canvas = require('canvas');
var image = new Canvas.Image,
pixelUtil.createBuffer('http://127.0.0.1:8080/image/test.jpg').then(function(buffer){
image.src = buffer;
canvas = new Canvas(image.width, image.height);
var ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0);
runImage(ctx.getImageData(0, 0, canvas.width, canvas.height));
});
After much struggling, I've managed to get node-canvas installed on Windows.
When I try to read in the image size of a GIF, however, it just gives me back 0 for the width and height.
var FileSystem = require('fs');
var Canvas = require('canvas');
FileSystem.readdir(baseDir, function(err, files) {
files.forEach(function(filename) {
var path = Path.join(baseDir, filename);
FileSystem.readFile(path, function(err, buf) {
var img = new Canvas.Image;
img.src = buf;
console.log(path, img.width, img.height);
});
});
Is it not supposed to be able to read GIFs?
You must install giflib and reinstall node-canvas like is said in here https://github.com/LearnBoost/node-canvas/wiki/Installation---OSX and then you will be able to manipulate your gif file (retrieve width/height). But beware, the image processed with canvas will stop being animated.
I'm using the following code to try to see if I can load a canvas from a json string then generate a dataURL png for it:
var fabric=require('fabric');
var canvas = new fabric.fabric.Canvas();
var jsonStr='{"objects":[],"background":"rgba(0, 0, 0,0)","backgroundImage":"http://entropy.tmok.com/~gauze/canvas/any.gif","backgroundImageOpacity":1,"backgroundImageStretch":true,"overlayImage":"http://entropy.tmok.com/~gauze/canvas/frame.png","overlayImageLeft":0,"overlayImageTop":0}';
canvas.loadFromJSON(jsonStr);
img=canvas.toDataURL('png');
it errors on the toDataURL() line with:
/root/node-v0.8.16-linux-x86/node_modules/canvas/lib/canvas.js:190
return prefix + this.toBuffer().toString('base64');
^
which tells me 'this' (which is a Canvas according to console.log) doesn't have a .toBuffer() method. am I doing something wrong or is this a bug in fabric's node module?
thanks.
never mind I missed : .createCanvasForNode()
cant wait for documentation of this :P
I have seen SVG images on wikipedia which you can open in notepad and find the code written inside it. My question is if I make a circle in raphael, can I display it as an svg image in the browser?
var p = paper.circle(10,10,10).attr({fill:'blue'});
then display it as a svg image in my browser. How can I achieve it?
This would only work on browsers that support SVG. I think it fails on IE9 too because it doesn't provide support for .serializeToString() (though there are shims for this).
window.onload = function () {
var paper = Raphael("container", 100, 100);
var p = paper.circle(10,10,10).attr({fill:'blue'});
var textarea = document.getElementById("code")
var serializer = new XMLSerializer();
textarea.value = serializer.serializeToString(paper.canvas);
};
See demo here: http://jsfiddle.net/BvWkU/
window.onload = function () {
var paper = Raphael("container", 100, 100);
var p = paper.circle(10,10,10).attr({fill:'blue'});
var textarea = document.getElementById("code")
var serializer = new XMLSerializer();
textarea.value = serializer.serializeToString(paper.canvas);
};