how to save canvas as png image? - javascript

I have a canvas element with a drawing in it, and I want to create a button that when clicked on, it will save the image as a png file. So it should open up the save, open, close dialog box...
I do it using this code
var canvas = document.getElementById("myCanvas");
window.open(canvas.toDataURL("image/png"));
But when I test it out in IE9, a new window opens up saying "the web page cannot be displayed"
and the url of it is:
data:image/png;base64,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
Anyone know how to fix this?

try this:
var canvas = document.getElementById("alpha");
var dataURL = canvas.toDataURL("image/png");
var newTab = window.open('about:blank','image from canvas');
newTab.document.write("<img src='" + dataURL + "' alt='from canvas'/>");
This shows image from canvas on new page, but if you have open popup in new tab setting it shows about:blank in address bar.
EDIT:- though window.open("<img src='"+ canvas.toDataURL('image/png') +"'/>") does not work in FF or Chrome, following works though rendering is somewhat different from what is shown on canvas, I think transparency is the issue:
window.open(canvas.toDataURL('image/png'));

FileSaver.js should be able to help you here.
var canvas = document.getElementById("my-canvas");
// draw to canvas...
canvas.toBlob(function(blob) {
saveAs(blob, "pretty image.png");
});

To accomodate all three points:
button
save the image as a png file
open up the save, open, close dialog box
The file dialog is a setting in the browser.
For the button/save part assign the following function, boiled down from other answers, to your buttons onclick:
function DownloadCanvasAsImage(){
let downloadLink = document.createElement('a');
downloadLink.setAttribute('download', 'CanvasAsImage.png');
let canvas = document.getElementById('myCanvas');
let dataURL = canvas.toDataURL('image/png');
let url = dataURL.replace(/^data:image\/png/,'data:application/octet-stream');
downloadLink.setAttribute('href', url);
downloadLink.click();
}
Example on Codepen
Another, somewhat cleaner, approach is using Canvas.toBlob():
function DownloadCanvasAsImage(){
let downloadLink = document.createElement('a');
downloadLink.setAttribute('download', 'CanvasAsImage.png');
let canvas = document.getElementById('myCanvas');
canvas.toBlob(function(blob) {
let url = URL.createObjectURL(blob);
downloadLink.setAttribute('href', url);
downloadLink.click();
});
}
Example on Codepen
Neither solution is 100% cross browser compatible, so check the client

I used this solution to set the file name:
HTML:
Download!
<canvas id="canvas"></canvas>
JavaScript:
function download(){
document.getElementById("downloader").download = "image.png";
document.getElementById("downloader").href = document.getElementById("canvas").toDataURL("image/png").replace(/^data:image\/[^;]/, 'data:application/octet-stream');
}

I had this problem and this is the best solution without any external or additional script libraries:
In Javascript tags or file create this function:
We assume here that canvas is your canvas:
function download(){
var download = document.getElementById("download");
var image = document.getElementById("canvas").toDataURL("image/png")
.replace("image/png", "image/octet-stream");
download.setAttribute("href", image);
}
In the body part of your HTML specify the button:
<a id="download" download="image.png"><button type="button" onClick="download()">Download</button></a>
This is working and download link looks like a button. Tested in Firefox and Chrome.

I maybe discovered a better way for not forcing the user to right click and "save image as". Live draw the canvas base64 code into the href of the link and modify it so the download will start automatically. I don't know if it's universally browser compatible, but it should work with the main/new browsers.
var canvas = document.getElementById('your-canvas');
if (canvas.getContext) {
var C = canvas.getContext('2d');
}
$('#your-canvas').mousedown(function(event) {
// feel free to choose your event ;)
// just for example
// var OFFSET = $(this).offset();
// var x = event.pageX - OFFSET.left;
// var y = event.pageY - OFFSET.top;
// standard data to url
var imgdata = canvas.toDataURL('image/png');
// modify the dataUrl so the browser starts downloading it instead of just showing it
var newdata = imgdata.replace(/^data:image\/png/,'data:application/octet-stream');
// give the link the values it needs
$('a.linkwithnewattr').attr('download','your_pic_name.png').attr('href',newdata);
});
You can wrap the <a> around anything you want.

Submit a form that contains an input with value of canvas toDataURL('image/png') e.g
//JAVASCRIPT
var canvas = document.getElementById("canvas");
var url = canvas.toDataUrl('image/png');
Insert the value of the url to your hidden input on form element.
//PHP
$data = $_POST['photo'];
$data = str_replace('data:image/png;base64,', '', $data);
$data = base64_decode($data);
file_put_contents("i". rand(0, 50).".png", $data);

Try this:
jQuery('body').after('<a id="Download" target="_blank">Click Here</a>');
var canvas = document.getElementById('canvasID');
var ctx = canvas.getContext('2d');
document.getElementById('Download').addEventListener('click', function() {
downloadCanvas(this, 'canvas', 'test.png');
}, false);
function downloadCanvas(link, canvasId, filename) {
link.href = document.getElementById(canvasId).toDataURL();
link.Download = filename;
}
You can just put this code in console in firefox or chrom and after changed your canvas tag ID in this above script and run this script in console.
After the execute this code you will see the link as text "click here" at bottom of the html page. click on this link and open the canvas drawing as a PNG image in new window save the image.

Full Working HTML Code. Cut+Paste into new .HTML file:
Contains Two Examples:
Canvas in HTML file.
Canvas dynamically created with Javascript.
Tested In:
Chrome
Internet Explorer
*Edge (title name does not show up)
Firefox
Opera
<!DOCTYPE HTML >
<html lang="en">
<head>
<meta charset="UTF-8">
<title> #SAVE_CANVAS_TEST# </title>
<meta
name ="author"
content="John Mark Isaac Madison"
>
<!-- EMAIL: J4M4I5M7 -[AT]- Hotmail.com -->
</head>
<body>
<div id="about_the_code">
Illustrates:
<ol>
<li>How to save a canvas from HTML page. </li>
<li>How to save a dynamically created canvas.</li>
</ol>
</div>
<canvas id="DOM_CANVAS"
width ="300"
height="300"
></canvas>
<div id="controls">
<button type="button" style="width:300px;"
onclick="obj.SAVE_CANVAS()">
SAVE_CANVAS ( Dynamically Made Canvas )
</button>
<button type="button" style="width:300px;"
onclick="obj.SAVE_CANVAS('DOM_CANVAS')">
SAVE_CANVAS ( Canvas In HTML Code )
</button>
</div>
<script>
var obj = new MyTestCodeClass();
function MyTestCodeClass(){
//Publically exposed functions:
this.SAVE_CANVAS = SAVE_CANVAS;
//:Private:
var _canvas;
var _canvas_id = "ID_OF_DYNAMIC_CANVAS";
var _name_hash_counter = 0;
//:Create Canvas:
(function _constructor(){
var D = document;
var CE = D.createElement.bind(D);
_canvas = CE("canvas");
_canvas.width = 300;
_canvas.height= 300;
_canvas.id = _canvas_id;
})();
//:Before saving the canvas, fill it so
//:we can see it. For demonstration of code.
function _fillCanvas(input_canvas, r,g,b){
var ctx = input_canvas.getContext("2d");
var c = input_canvas;
ctx.fillStyle = "rgb("+r+","+g+","+b+")";
ctx.fillRect(0, 0, c.width, c.height);
}
//:Saves canvas. If optional_id supplied,
//:will save canvas off the DOM. If not,
//:will save the dynamically created canvas.
function SAVE_CANVAS(optional_id){
var c = _getCanvas( optional_id );
//:Debug Code: Color canvas from DOM
//:green, internal canvas red.
if( optional_id ){
_fillCanvas(c,0,255,0);
}else{
_fillCanvas(c,255,0,0);
}
_saveCanvas( c );
}
//:If optional_id supplied, get canvas
//:from DOM. Else, get internal dynamically
//:created canvas.
function _getCanvas( optional_id ){
var c = null; //:canvas.
if( typeof optional_id == "string"){
var id = optional_id;
var d = document;
var c = d.getElementById( id );
}else{
c = _canvas;
}
return c;
}
function _saveCanvas( canvas ){
if(!window){ alert("[WINDOW_IS_NULL]"); }
//:We want to give the window a unique
//:name so that we can save multiple times
//:without having to close previous
//:windows.
_name_hash_counter++ ;
var NHC = _name_hash_counter ;
var URL = 'about:blank' ;
var name= 'UNIQUE_WINDOW_ID' + NHC;
var w=window.open( URL, name ) ;
if(!w){ alert("[W_IS_NULL]");}
//:Create the page contents,
//:THEN set the tile. Order Matters.
var DW = "" ;
DW += "<img src='" ;
DW += canvas.toDataURL("image/png");
DW += "' alt='from canvas'/>" ;
w.document.write(DW) ;
w.document.title = "NHC"+NHC ;
}
}//:end class
</script>
</body>
<!-- In IE: Script cannot be outside of body. -->
</html>

I really like Tovask's answer but it doesn't work due to the function having the name download (this answer explains why). I also don't see the point in replacing "data:image/..." with "data:application/...".
The following code has been tested in Chrome and Firefox and seems to work fine in both.
JavaScript:
function prepDownload(a, canvas, name) {
a.download = name
a.href = canvas.toDataURL()
}
HTML:
Download
<canvas id="canvasId"></canvas>

My solution via vue and async support
async downloadImage () {
const canvas = this.$refs.canvas
const blob = await new Promise(resolve => canvas.toBlob(resolve))
const downloadLink = document.createElement('a')
downloadLink.href = window.URL.createObjectURL(blob)
downloadLink.download = 'mycanvasimage.png'
downloadLink.click()
}

var canvasId = chart.id + '-canvas';
var canvasDownloadId = chart.id + '-download-canvas';
var canvasHtml = Ext.String.format('<canvas id="{0}" width="{1}" height="{2}"></canvas><a id="{3}"/>',
canvasId,
chart.getWidth(),
chart.getHeight(),
canvasDownloadId);
var canvasElement = reportBuilder.add({ html: canvasHtml });
var canvas = document.getElementById(canvasId);
var canvasDownload = document.getElementById(canvasDownloadId);
canvasDownload.href = chart.getImage().data;
canvasDownload.download = 'chart';
canvasDownload.click();

Related

How to save canvas on Right-Click dialog as jpg

I'm using this code to capture images as canvas from a video URL in my site:
var videoId = 'video';
var scaleFactor = 0.55; // increase or decrease size
var snapshots = [];
/**
* Captures a image frame from the provided video element.
*
* #param {Video} video HTML5 video element from where the image frame will be captured.
* #param {Number} scaleFactor Factor to scale the canvas element that will be return. This is an optional parameter.
*
* #return {Canvas}
*/
function capture(video, scaleFactor) {
if(scaleFactor == null){
scaleFactor = 1;
}
var w = video.videoWidth * scaleFactor;
var h = video.videoHeight * scaleFactor;
var canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, w, h);
var uniq = 'img_' + (new Date()).getTime();
canvas.setAttribute('id', uniq);
return canvas ;
}
/**
* Invokes the <code>capture</code> function and attaches the canvas element to the DOM.
*/
function shoot(){
var video = document.getElementById(videoId);
var output = document.getElementById('output');
var canvas = capture(video, scaleFactor);
snapshots.unshift(canvas);
output.innerHTML = '' ;
for(var i=0; i<10; i++){
output.appendChild(snapshots[i]);
}
}
My two problems:
1 - Currently, browsers treat <canvas> like they they treat a <div> and this make it impossible to save any generated canvas as an image because when I right-click on each and everyone, it always opens the windows dialog here I have to choose Save image as....
2 - The windows right-click dialog always opens by default the option to save image as transfer.png and I would like to save the image with their ID attribute (var uniq) and a jpg extension.
Example of what I need:
The output canvas is like this: <canvas width="352" height="198" id="img_1575807516362"></canvas>.
I want the right-click to open the windows dialog offering to save image like this img_1575807516362.jpg.
Alternatively, it would be nice tho have a download button for each canvas to export the canvas as an image like this transfer.jpg.
Is it possible to make this work with this code?
Apologies in advance. It took me some time, but I wanted to make sure that I got it working properly. I am not sure if there is a way to do a windows dialog to save to file (Where it pulls up the save as... prompt), but you can definitely create a download button to do this.
Downloading the Image
First, we need to create a download button:
<button onmousedown="download()">Download</button>
Second, we can create a function to download the image with a key.
The easiest way to do this is creating a downloadable <a> tag:
var download = function(){
var link = document.createElement('a'); //Creates an 'a' element
var thisCanvas = document.getElementsByTagName('canvas')[0]; //gets the first canvas element on the page, assuming the canvas you want to download is this element.
link.download = `${thisCanvas.id}.jpeg`; //Gives the download an output link
link.href = thisCanvas.toDataURL("image/jpeg") //Gives the data to the link
link.click(); //Clicks the 'a' element we created
}
If you wanted to ask for user input whether or not they want to download, you can use:
var download = function() {
if (window.confirm("Would you like to download this frame?")) {
var link = document.createElement('a'); //Creates an 'a' element
var thisCanvas = document.getElementsByTagName('canvas')[0]; //Gets the canvas
link.download = `${thisCanvas.id}.jpeg`; //Gives the download an output link
link.href = thisCanvas.toDataURL("image/jpeg") //Gives the data to the link
link.click(); //Clicks the 'a' element we created
}
}
You can always change the name of the image file as well with link.download = imageName + ".jpeg"
Creating A Button in JS
EDIT: If you want to create the button in javascript instead of html, you can do the following:
var createbutton = function() {
var b = document.createElement('button'); //Creates the button
b.onmousedown = function() { //Creates an onmousedown event for the button
download(); //This is the download function above
}
b.innerHTML = "Download"; //Gives the button Text
//Here, you can insert button styles using: b.style
document.body.appendChild(b); //Appends the button to the body
}
You can call this function whenever you need to create the download button. This function creates a button at the end of the body, but you can change the location:
//Where it says document.body.appendChild(b); , replace it with:
document.getElementById(`myCustomId`).appendChild(b);
//This places the button in any element on the page with 'myCustomId'
Canvas onmousedown events, and downloading all images
EDIT (2):
If you have multiple canvases that are created within snapshots, then you can do the following to download all the snapshots:
var download = function(){
var link = document.createElement('a'); //Creates an 'a' element
snapshots.forEach(snap => {
link.download = `${snap.id}.jpeg`; //Gives the download an output link
link.href = snap.toDataURL("image/jpeg") //Gives the data to the link
link.click(); //Clicks the 'a' element we created
});
}
If you want to download one image at a time, you can give them an onmousedown event when you add them. Let's edit the download function to support this:
var download = function(canvas){
var link = document.createElement('a'); //Creates an 'a' element
link.download = `${canvas.id}.jpeg`; //Gives the download an output link
link.href = canvas.toDataURL("image/jpeg") //Gives the data to the link
link.click(); //Clicks the 'a' element we created
}
//We also need to edit the shoot() function
function shoot(){
var video = document.getElementById(videoId);
var output = document.getElementById('output');
var canvas = capture(video, scaleFactor);
canvas.onmousedown = function() {
download(canvas);
}
snapshots.unshift(canvas);
output.innerHTML = '' ;
for(var i=0; i<10; i++){
output.appendChild(snapshots[i]);
}
}
This way whenever you append all of the snapshots, each canvas comes with it's own mousedown event, so clicking on it will return the image. You can even add a confirm box or check if right mouse is clicked here.
Question 2: It doesn't matter where the functions go, only where you call them.
If you have any questions, let me know!

Browser scroll bar shift after adding an image with javascript

I have an event creation page with image upload. After I select an image, the image is previewed in the browser. When I scroll after the image is added, I see bottom scroll bar stays in the middle of the screen until I focus on an input element. e.g When I focus on description text-area the scroll bar in the middle disappears.
Working version is in jsbin, try selecting an image multiple times. The issue in jsbin:
https://jsbin.com/wigawededo/1/edit?html,css,js,output
Issue on my computer:
When an image is selected I preview it with this code:
function showImage() {
var imageSelector = document.getElementById("image");
var image = document.getElementById("image").files[0];
var reader = new FileReader();
reader.onload = function(e) {
const prevImage = document.querySelector("#previewImage");
if (prevImage) prevImage.parentNode.removeChild(prevImage);
const prevImageLabel = document.querySelector("#previewImageLabel");
if (prevImage) prevImageLabel.parentNode.removeChild(prevImageLabel);
var newImage = document.createElement("img");
newImage.style.maxHeight = "300px";
newImage.style.maxWidth = "300px";
newImage.id = "previewImage";
newImage.src = e.target.result;
var imageLabel = document.createElement("p");
imageLabel.innerHTML = "Preview image:";
imageLabel.id = "previewImageLabel";
imageSelector.parentNode.insertBefore(
imageLabel,
imageSelector.nextSibling
);
imageSelector.parentNode.insertBefore(
newImage,
imageSelector.nextSibling.nextSibling
);
};
if (image) reader.readAsDataURL(image);
else {
const prevImage = document.querySelector("#previewImage");
if (prevImage) prevImage.parentNode.removeChild(prevImage);
const prevImageLabel = document.querySelector("#previewImageLabel");
if (prevImage) prevImageLabel.parentNode.removeChild(prevImageLabel);
}
}
The file selector input has #image id. Note, this code deletes the preview image if there is no file selected.
I am just wondering why this happens. Can you think of a solution? Thanks.
Note: I am using chrome on ubuntu linux
Some of your content must go out of the screen. Try using overflow: hidden or try to decrease width of input/other elements.

How to download the screenshot automatically by using html2Canvas

I have a canvas which shows a graph and I'm trying to take a screenshot of the canvas using html2canvas() with the code below :
<div class="chartContainer" id="chart1"></div>
<div id="displayCanvas" style="display:none;" class="stx-dialog"></div>
html2canvas($('#chart1'),{onrendered:function(canvas1)
{$('#displayCanvas').append(canvas1)}});
Here when the chart container is loaded the it uses the div with the id "displayCanvas" and appends the screenshot of the canvas.
How can I download the screenshot of the canvas which is displayed?
I have already tried using something like below to download the image:
var link = document.createElement('a');
link.download = stx.chart.symbol+".png";
link.href = stx.chart.canvas.toDataURL("png");
link.click();
but it only downloads the data on the canvas as an image without the background (it does not download the screenshot but only the data) which when opened after downloading shows a black screen with data in it. Can anyone help me on how to download the image directly of the screenshot taken from the html2Canvas()?
TRY THIS:
In the HTML:
Give the element that you want to screenshot, an ID of "capture".
Give the button/element that you would need to click to take the screenshot, an ID of "btn".
Load the html2canvas.min.js file.
In the Javascript:
Create the capture() function.
Bind the capture() function to whatever event you are using—in this case it's on the btn click event.
DONE! Watch the magic happen when you click on the btn.
HTML:
<h1 id="capture">Hellooooo</h1>
<button id="btn">Capture</button>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
Javascript:
function capture() {
const captureElement = document.querySelector('#capture') // Select the element you want to capture. Select the <body> element to capture full page.
html2canvas(captureElement)
.then(canvas => {
canvas.style.display = 'none'
document.body.appendChild(canvas)
return canvas
})
.then(canvas => {
const image = canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream')
const a = document.createElement('a')
a.setAttribute('download', 'my-image.png')
a.setAttribute('href', image)
a.click()
canvas.remove()
})
}
const btn = document.querySelector('#btn')
btn.addEventListener('click', capture)
Here's the JSFiddle
💡 QUICK TIP: If you want to capture the whole document/webpage, then just add the "capture" ID to the <body> tag.
If there is black background at image your chart must be visible on screen. Because html2canvas like a taking screenshot. If you want converting data
to canvas, you must be sure data is appear in screen.
In case someone is using React, here is some code you can copy:
async function download() {
const canvas = await html2canvas(document.querySelector("#screenshot"));
canvas.style.display = "none";
document.body.appendChild(canvas);
const image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
const a = document.createElement("a");
a.setAttribute("download", `info.png`);
a.setAttribute("href", image);
a.click();
}
<a href="#" onClick={() => download()}>Download</a>
This worked for me:
HTML
<div id="canvasDiv">
<canvas id="canvas" height="100" width="100">
Your browser does not support the HTML canvas tag.
</canvas>
</div>
<button onclick="screenShot()" type="button">Take a screenshot</button>
Javascript
function screenShot(){
html2canvas(document.querySelector("#canvasDiv")).then(canvas => {
var dataURL = canvas.toDataURL( "image/png" );
var data = atob( dataURL.substring( "data:image/png;base64,".length ) ),
asArray = new Uint8Array(data.length);
for( var i = 0, len = data.length; i < len; ++i ) {
asArray[i] = data.charCodeAt(i);
}
var blob = new Blob( [ asArray.buffer ], {type: "image/png"} );
saveAs(blob, "photo.png");
});
}
I just used the code provided in html2canvas site, then i used this code to download the screenshot.

Is an event triggered when an HTML link element (<a/>) containing base64 data as href is ready?

I have created a webpage that basically displays 2 images side by side.
It has a "download" button, which triggers a vanilla Javascript function, which creates a <canvas> HTML element and concatenates the two images inside of it. It then creates a link with the base64-encoded result image as href and clicks on it:
<a download="image.png" id="dllink" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAAAMnCAYAAABhnf9DAAAgAElEQVR4nOzdR48kD3rn96j03pfv6qo21dVd3qT3JryP9Jll281..."></a>
Here is what the function I'm using looks like:
/**
* Create canvas, draw both images in it, create a link with the result
* image in base64 in the "href" field, append the link to the document,
* and click on it
*/
function saveImage() {
// Get left image
var imgLeft = new Image();
imgLeft.setAttribute('crossOrigin', 'anonymous');
imgLeft.src = "imgleft/" + idxImageShownLeft + ".jpg";
imgLeft.onload = function() {
// Once the left image is ready, get right image
var imgRight = new Image()
imgRight.setAttribute('crossOrigin', 'anonymous');
imgRight.src = "imgright/" + idxImageShownRight + ".jpg";
imgRight.onload = function() {
// Once the right image is ready, create the canvas
var canv = document.createElement("canvas");
var widthLeft = parseInt(imgLeft.width);
var widthRight = parseInt(imgRight.width);
var width = widthLeft + widthRight;
var height = imgLeft.height;
canv.setAttribute("width", width);
canv.setAttribute("height", height);
canv.setAttribute("id", "myCanvas");
canv.setAttribute('crossOrigin', 'anonymous');
var ctx = canv.getContext("2d");
// Draw both images in canvas
ctx.drawImage(imgLeft, 0, 0);
ctx.drawImage(imgRight, widthLeft, 0);
// Create PNG image out of the canvas
var img = canv.toDataURL("image/png");
// Create link element
var aHref = document.createElement('a');
aHref.href = img;
aHref.setAttribute("id", "dllink");
aHref.download = "image.png";
// Append link to document
var renderDiv = document.getElementById("render");
renderDiv.replaceChild(aHref, document.getElementById("dllink"));
// Click on link
aHref.click();
}
}
}
My problem is that this works fine on Firefox, but not on Chrome.
After a bit of investigating, I realized that by setting a breakpoint before the aHref.click(); line in Chrome, it worked fine. I think that it means that the aHref.click(); is called before the <a href="data:image/png;base64,...></a> is ready to be clicked, but I don't know for sure.
I couldn't find a duplicate of this topic. What keywords should I use just to be 100% sure?
Am I investigating in the right direction?
Is there an event I could rely on in order to call aHref.click(); only when it is ready?
You could wrap it in an init function that gets called when the window completes loading.
function init() {
aHref.click();
}
window.onload = init;
Its similar to the vanilla equivalent of jQuery's .ready() method.
aHref , document.getElementById("dllink") appear to be same element ? Though "dllink" has not yet been appended to document when .replaceChild called ?
Try substituting
renderDiv.appendChild(aHref);
for
renderDiv.replaceChild(aHref, document.getElementById("dllink"));

open image in canvas via url

I have been trying to open an image in canvas using a web url. Perhaps i am not using something well, what i have done is:
<script>
function Draw_url_to_canvas(url1,name_of_canvas){
var myCanvas = document.getElementById(name_of_canvas);
var img3 = new Image;
var ctx2 = myCanvas.getContext('2d');
img3.onload = function(){
ctx2.drawImage(img3,0,0); // Or at whatever offset you like
}
console.log(url1);
img3.src = url1;
}
</script>
<input type="text" name="url-pass" id = "url-pass"></input>
<button type="button" onclick = "Draw_url_to_canvas(document.getElementById('url-pass').value,'drawCanvas')">Pass url-photo to canvas</button>
I am trying to use this weburl: https://drive.google.com/file/d/0B8Fw3rEXlvPTZnBINU5odWdXSUU/view?usp=sharing which i guess is valid for this work, though it has not worked till now. Any ideas?

Categories