i have 2 canvases and i´m drawing on one of them.
Then i want to parse path from canvas one and paste in to canvas two.
How can i parse path from canvas one to JSON format in fabric.js ?
Thank you for all advices!
From the fabric.js docs the canvas can be serialized and deserialized:
var canvas1 = new fabric.Canvas('c');
var canvasJSON = JSON.stringify(canvas1);
var canvas2 = new fabric.Canvas();
canvas2.loadFromJSON(canvasJSON)
Related
var img, imageData,width,height;
var c = canvasEle.getContext("2d");
width = canvasEle.width;
height = canvasEle.height;
img = document.getElementById("id");
c.drawImage(img,0,0);
imageData = c.createImageData(width, height);
After I draw the image onto the context, then create an imageData array, the values of the array are all 0.
I have been struggling with this for hours and couldn't find any solution. The image is shown on the canvas after I draw it, but the imageData of the context says all the pixels are white. This doesn't make any sense to me.
With createImageData you are creating new image data for an empty image. Please use getImageData to get the image data from an already existing canvas
I have this
function doFirst(){
var x = document.getElementById('canvas');
var canvas = x.getContext('webgl') || x.getContext("experimental-webgl");
}
And I want to draw a image 'sheep.png' on the canvas. I use this but it is not working:
var pic = new Image();
pic.src = "images/sheep.png";
pic.addEventListener("load", function() { canvas.drawImage(pic,0,0,0)}, false);
drawImage is only for use with the 2D context, you can't use it in a webgl context.
In order to use it in webgl, you'll need to build a mesh with your image used as the texture.
If you're not familiar with webgl, you might want to look at three.js as an alternative that's easier to use.
drawImage()
takes only 3 arguments I guess.
See this demo.
and this reference
I am trying to copy part of a fabricjs canvas to another canvas.I am not sure if fabric has a method suitable for doing it (please let me know if that's the case) and after some searching I decided to do it without using fabric. But the canvas was already created using fabricjs. new fabric.Canvas(). Now when I try to copy a part of this canvas using context.drawImage(), I get a TypeError. I tried replacing the canvas with a img or a canvas created without using fabric and that works. So, I am guessing I may have to use the fabric canvas object a bit differently.
If you want to copy a rectangular zone from the canvas in order to export it as an image you could use the following:
canvas.deactivateAll();
canvas.renderAll();
var ctx = canvas.getContext("2d");
var myImageData = ctx.getImageData(box.x, box.y, box.w, box.h);
var buffer = document.createElement('canvas');
var bufferCtx = buffer.getContext("2d");
buffer.width = box.w;
buffer.height = box.h;
bufferCtx.putImageData(myImageData, 0, 0);
window.open(buffer.toDataURL('image/png'));
I can capture a full canvas with .todataurl without a problem. But I do not see or know if there is anyway to capture only a portion of the canvas and save that to image.
e.i. Mr. Potatohead script draws hats, hands feet faces etc etc. mixed all over the canvas and you can drag and drop them onto the mr potato in the center of the canvas. Press a button save the image of mr potato looking all spiffy to jpg for you. Without all the extra hats/feet/faces in the image.
I have resigned myself to the fact that this is impossible based on everything I've read. But you folks have proven to be smarter than google (or atleast google in my hands) a few times so i am taking a shot.
Sorry no code to post this time... unless you want this:
var canvas = document.getElementById("mrp");
var dataUrl = canvas.toDataURL();
window.open(dataUrl, "toDataURL() image", "width=800, height=600");
But that is just the example of dataurl i am working off of.. and it works outside of the fact it doesnt cap just the mr potato
My fallback is to pass the image to php and work with it there to cut out everything i dont want then pass it back.
EDIT
tmcw had a method for doing this. Not sure if its the way it SHOULD be done but it certainly works.
document.getElementById('grow').innerHTML="<canvas id='dtemp' ></canvas>";
var SecondaryCanvas = document.getElementById("dtemp");
var SecondaryCanvas_Context = SecondaryCanvas.getContext ("2d");
SecondaryCanvas_Context.canvas.width = 600;
SecondaryCanvas_Context.canvas.height = 600;
var img = new Image();
img.src = MainCanvas.toDataURL('image/png');
SecondaryCanvas_Context.drawImage(img, -400, -300);
var du = SecondaryCanvas.toDataURL();
window.open(du, "toDataURL() image", "width=600, height=600");
document.getElementById('grow').innerHTML="";
grow is an empty span tag, SecondaryCanvas is a var created just for this
SecondaryCanvas_Context is the getcontext of SecondaryCanvas
img created just to store the .toDataURL() of the main canvas containing the Mr. PotatoHead
drawImage with negative (-) offsets to move image of MainCanvas so that just the portion i want is showing.
Then cap the new canvas that was just created and open a new window with the .png
on and if you get an error from the script saying security err 18 its because you forgot to rename imgTop to img with the rest of the variables you copy pasted and chrome doesnt like it when you try to save local content images like that.
Here's a method that uses an off-screen canvas:
var canvas = document.createElement('canvas');
canvas.width = desiredWidth;
canvas.height = desiredHeight;
canvas.getContext('2d').drawImage(originalCanvas,x,y,w,h,0,0,desiredWidth, desiredHeight);
result = canvas.toDataURL()
Create a new Canvas object of a specific size, use drawImage to copy a specific part of your canvas to a specific area of the new one, and use toDataURL() on the new canvas.
A bit more efficient (and maybe a cleaner) way of extracting part of the image:
// x,y are position in the original canvas you want to take part of the image
// desiredWidth,desiredHeight is the size of the image you want to have
// get raw image data
var imageContentRaw = originalCanvas.getContext('2d').getImageData(x,y,desiredWidth,desiredHeight);
// create new canvas
var canvas = document.createElement('canvas');
// with the correct size
canvas.width = desiredWidth;
canvas.height = desiredHeight;
// put there raw image data
// expected to be faster as tere are no scaling, etc
canvas.getContext('2d').putImageData(imageContentRaw, 0, 0);
// get image data (encoded as bas64)
result = canvas.toDataURL("image/jpeg", 1.0)
you can give left,top,width and Height parameters to toDataURL function.. Here is the code to get data image depending on the object on canvas.
mainObj = "your desired Object"; // for example canvas._objects[0];
var image = canvas.toDataURL({ left: mainObj.left, top:mainObj.top,
width: mainObj.width*mainObj.scaleX, height: mainObj.height*mainObj.scaleY});
I have a Uint32Array I am trying to convert to a texture for WebGL. To do this I'm writing the array as RGBA values on a Canvas and getting a base64 encoded PNG from the canvas to send as a texture.
Whenever I set a pixel value to have an alpha of 0, the corresponding RGB channels are also zeroed upon conversion to a PNG. Is this an implementation detail? If I were to create PNGs in some other non-HTML5 program could I have an (RGBA) quadruplet of (255,255,255,0)? I tried using an alpha value of 1 and all other channels remain intact, so this is not an issue of premultiplied alpha.
Here is some javascript code to reproduce this effect:
var img = new Image();
var canvasObj = $('<canvas width="1" height="1"></canvas>');
var context = canvasObj[0].getContext('2d');
var imgd = context.getImageData(0,0,1,1);
var pix = imgd.data;
pix[0]=255; pix[1]=255; pix[2]=255; pix[3]=0;
context.putImageData(imgd,0,0);
img.src = canvasObj[0].toDataURL("image/png");
context.drawImage(img,0,0);
var imgd2 = context.getImageData(0,0,1,1);
var pix2 = imgd2.data;
pix2 will be all 0s.
Thanks!
It appears to be part of the PNG specification (http://www.libpng.org/pub/png/spec/1.2/png-1.2-pdg.html).
...fully transparent pixels should all be assigned the same
color value for best compression.
I couldn't find a direct source, but it seems like this particular implementation sets all the channels to zero.