Upload to and edit in canvas

Ever needed to make an app were the user has to upload an image and edit it before saving? Like upload, crop and scale your profile picture.

A few years ago you would start by uploading the image to your server. Then wait. And wait a bit more, because they just got themselves a new 11 mega-pixel camera an now they are trying to upload it straight to your server as their new profile picture because they rule. When you were finally done with their damned huge picture, you would show a scaled low quality image in the next screen and used some js library to show what you would do with there picture. This was a pretty nifty way of dealing with all the limitations of the pre-html5 time.

Since html5  we are not obliged to follow that road anymore.

The fileAPI and the Canvas element gives us the opportunity to upload and manipulate an raster-based image. And above all, we can export our result to png, jpg, bmp and send it our server.

The following code will show a quick example of this techniec.

Upload to Canvas

Lets start with the html:

<input id="imageLoader" name="imageLoader" type="file" />

<canvas id="imageCanvas" width="400" height="200"></canvas>

We listen for a change on input and fire handleImage() when we select an image in de file input.

    var imageLoader = document.getElementById('imageLoader');

        imageLoader.addEventListener('change', handleImage, false);

    var canvas = document.getElementById('imageCanvas');

    var ctx = canvas.getContext('2d');

We will use the fileReader api for downloading the image to our dom.

    function handleImage(e){

        var reader = new FileReader();

        reader.onload = function(event){

            var img = new Image();

            img.onload = function(){

                ctx.drawImage(img,0,0);

            }

            img.src = event.target.result;

        }

        reader.readAsDataURL(e.target.files[0]);     

    }
Schermafbeelding 2014-01-16 om 10.54.10

Our input field and the canvas element below

Manipulate the image

There are a lot of nice js libraries out there for manipulating an images. The best raster-based image manipulator I know of is fabric.js

Changing a few lines to add fabric js gives us the amazing ability to manipulate our image.

    var imageLoader = document.getElementById('imageLoader');

        imageLoader.addEventListener('change', handleImage, false);

    var canvas = new fabric.Canvas('imageCanvas',{backgroundColor: 'rgb(240,240,240)'});



    function handleImage(e){

        var reader = new FileReader();

        reader.onload = function(event){

            var img = new Image();

            img.onload = function(){

                var imgInstance = new fabric.Image(img)

                canvas.add(imgInstance);

            }

            img.src = event.target.result;

        }

        reader.readAsDataURL(e.target.files[0]);     

    }
Schermafbeelding 2014-01-16 om 10.57.28

thanks to fabric js we have nice intuitive handles for manipulating our image

Save our image

Add a link to save our image.

<button>Save image</button>
var imageSaver = document.getElementById('imageSaver');

    imageSaver.addEventListener('click', saveImage, false);



function saveImage(e){

    this.href = canvas.toDataURL({

      format: 'jpeg',

      quality: 0.8

    });

    this.download = 'test.png'

}
Schermafbeelding 2014-01-16 om 10.52.27

Upload & Manipulate images

Test the demo on JSfiddle