Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capturing only a portion of canvas with .todataurl Javascript/HTML5

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.

like image 372
Noname Provided Avatar asked Dec 24 '12 05:12

Noname Provided


3 Answers

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()
like image 55
Charlie Avatar answered Nov 08 '22 03:11

Charlie


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.

like image 10
tmcw Avatar answered Nov 08 '22 03:11

tmcw


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)
like image 1
mPrinC Avatar answered Nov 08 '22 03:11

mPrinC