I am currently using http://paperjs.org to create an HTML5 canvas drawing app. I want to let users upload images into the canvas. I know I need to make a login and signup but is there an easier way? I have seen the HTML5 drag and drop upload.
5 Answers
I assume you mean, to load an image into the canvas and not uploading the image from the canvas.
It'd probably be a good idea to read through all the canvas articles they have over here https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Using_images
But basically what you want to do is create an image in javascript, and set the image.src = to whatever the file location is. In the case of loading images from the user on their end, you're going to want to use the File System API.
Threw together a brief example here: http://jsfiddle.net/influenztial/qy7h5/
function handleImage(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img,0,0);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}

- 1,551
- 1
- 17
- 27

- 3,886
- 2
- 23
- 24
-
2IE10+ with FileReader -- http://caniuse.com/filereader -- But a polyfill exists apparently, https://github.com/Jahdrien/FileReader – Cory Mawhorter May 27 '13 at 05:56
-
1How would you run the code without a button? Whats does the "e" refer to in the example? – Waltari Mar 07 '16 at 10:48
-
1@Waltari the 'e' variable is the file handle event using the FileReader API, you won't be able to do this without using a File Input or dropzone because you can't just go programmatically running through the user's file system (as far as I know). – DerekR Mar 30 '16 at 05:00
-
The canvas isn't updated after I choose a photo from my PC in the example from the jsfiddle link. I use Windows 10 and Chrome 70.0.3538.77 – TheLogicGuy Nov 11 '18 at 23:11
-
@TheLogicGuy should be fixed now. Apparently that fiddle was using MooTools for some reason and that library stopped working. – DerekR Nov 13 '18 at 15:59
One doesn't need a FileReader*, it is better to use the URL.createObjectURL method, which will create a symlink directly to the File on disk. This will incur less memory usage, and will have the added benefit to have only one async event to wait for (the one of the img.onload
).
document.getElementById('inp').onchange = function(e) {
var img = new Image();
img.onload = draw;
img.onerror = failed;
img.src = URL.createObjectURL(this.files[0]);
};
function draw() {
var canvas = document.getElementById('canvas');
canvas.width = this.width;
canvas.height = this.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(this, 0,0);
}
function failed() {
console.error("The provided file couldn't be loaded as an Image media");
}
<input type="file" id="inp">
<canvas id="canvas"></canvas>
*IIRC only a few versions of Chrome did support FileReader while not yet supporting URL.createObejctURL, so if you target these very versions, you might need FileReader..

- 123,334
- 13
- 219
- 285
-
-
2@AbhinavRavi you usually do the other way around: resize the canvas so that the image fits in. But if you really want to change the size of your image, then simply use the third and fourth params of drawImage: `ctx.drawImage(img, x, y, width, height)`. – Kaiido Sep 03 '18 at 04:47
-
-
2
-
2
-
@Kaiido is there an updated answer since new Chrome version have issues with this approach? – Crashalot Jan 05 '22 at 01:44
-
@Crashalot I am not aware of any issues with this solution, I'd also like very much the ones reporting such issue to be clearer about what they experienced. I suspect they had some CSP rules preventing the `blob://` URL to be accessed. This solution is the de-facto standard way. A more experimental one is to use the ImageBitmap constructor. (will post it as a separate answer btw, it's now supported by all major browsers). – Kaiido Jan 05 '22 at 01:47
-
Modified answer by @kaiido to create a new canvas
element each time and append it to a wrapper. Useful when you don't know how many canvases you may need.
Note: There is no new Canvas()
constructor, therefore we must use createElement()
.
document.getElementById('inp').onchange = function(e) {
let img = new Image();
img.onload = draw;
img.onerror = failed;
img.src = URL.createObjectURL(this.files[0]);
};
function draw() {
let canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
canvas.width = this.width;
canvas.height = this.height;
ctx.drawImage(this, 0, 0);
document.getElementById('gallery').append(canvas);
}
function failed() {
console.error("The provided file couldn't be loaded as an Image media");
}
/* entirely decorative */
#gallery {
display: flex;
gap: 1em;
margin: 1em;
}
#gallery canvas {
height: 100px;
border-radius: .5em;
aspect-ratio: 1/1;
object-fit: cover;
}
<input type="file" id="inp">
<div id='gallery'></div>

- 2,041
- 25
- 19
The most optimal way of creating an image consumable by the canvas is to create an ImageBitmap out of the File you get from the input.
This will use an optimized path to produce just what the browser needs to render that image, and will store the bitmap data in the GPU, allowing for fast drawing when asked to.
Given this is a quite recent feature (Safari added support only last year), you may want to use a polyfill like this one of mine.
document.querySelector("input").oninput = async (evt) => {
try {
const file = evt.target.files[0];
const bitmap = await createImageBitmap(file);
const canvas = document.querySelector("canvas");
canvas.width = bitmap.width;
canvas.height = bitmap.height;
const ctx = canvas.getContext("2d");
ctx.drawImage(bitmap, 0, 0);
}
catch(err) {
console.error(err);
}
};
<!-- createImageBitmap polyfill for old browsers --> <script src="https://cdn.jsdelivr.net/gh/Kaiido/createImageBitmap/dist/createImageBitmap.js"></script>
<input type="file">
<canvas></canvas>

- 123,334
- 13
- 219
- 285
<script>
window.onload = function() {
var canvas=document.getElementById(“drawing”); // grabs the canvas element
var context=canvas.getContext(“2d”); // returns the 2d context object
var img=new Image() //creates a variable for a new image
img.src= “images/vft.jpg” // specifies the location of the image
context.drawImage(img,20,20); // draws the image at the specified x and y location
}
</script>
Check Demo

- 1,927
- 4
- 21
- 27
-
1The number of downvotes on this question made me curious. It's this line: img.src= “images/vft.jpg”. The question is asking how to solve this dynamically, based on what user uploads (any filename!), you only solve it statically for that file. – HoldOffHunger Jun 26 '18 at 16:36
-
2@HoldOffHunger and they are not waiting for the image has loaded before trying to draw it on the canvas, which will probably fail every time for an user provided image, since that image will normally not be in *cache*. – Kaiido Nov 21 '18 at 12:34
-
1