It’s no surprise that in-browser image-editing has become a common feature in many of the web apps we use every day. Before in-browser editing, users would have to take the time to fire up a desktop image-editing program (if they had one), adjust their image, save it, and then finally upload the edited image. That’s a lot of steps, especially if the user only wanted to do something simple, like crop an image before uploading it!

Fortunately, today we can leverage the power of JavaScript and the HTML5 Canvas element to allow users to upload images and adjust them all within a web app, creating a positive, streamlined experience. We’ve had a few requests to add this feature to our Acadia™ platform and—needless to say—we think it’s a great idea. 

I’ve started to prototype this new feature in Acadia™, but I wanted to take some time out to share some of the things I’ve learned so far—specifically some thoughts on getting started with in-browser image editing and choosing an “approach” that fits your needs. 

Pure Canvas

As noted above, JavaScript and canvas are the two technologies that make in-browser image-editing “go.” Rolling my own image-manipulation library based on those two was one of the first things I considered when I started thinking about Acadia’s image-manipulation feature. Canvas exposes a pretty rich API that allows developers to do just about anything they want to an image—even down to pixel-specific operations, like inverting colors or making a color-picker.

While all that control is great, working directly with canvas can be a bit low-level and challenging if you’re doing anything non-trivial. Rotating an image (or shape), for example seems like a pretty straightforward operation, but it requires a bit more effort with pure canvas. First, you’ll be dealing with radians, not degrees—which isn’t a huge issue, but it can be a pain point if you forget. Second, if you happened to want a rotation from the center of the image or shape in question, you’ve got still more work to do. Canvas handles rotation based on the origin—or center—of the canvas, so to rotate an image around its middle, you’ll first need to make sure you translate (or move) the canvas so that its origin is in the center of the object you’re rotating.

While the above example is somewhat trivial, the bottom line is this: if you want fine-grained control and are up for the challenge, working with canvas directly is the way to go, otherwise, read on!

Canvas Libraries

Luckily for developers looking for something with a lower learning curve, there are quite a few JavaScript libraries built on top of canvas that abstract away some of the craziness. Libraries like Fabric.js, CamanJS, and others simplify things a lot. Take, for instance, inverting the colors in an image. Using JavaScript and canvas directly, you’d end up with code that looks something like this:

var canvas = document.getElementById(‘canvas’);
var context = canvas.getContext(‘2d’);
var imageData, data, i;

context.drawImage(myImage, 0, 0);

imageData = context.getImageData(0, 0, canvas.width, canvas.height);
data = imageData.data;

for (i = 0; i < data.length; i += 4) {
    data[i] = 255 – data[i];
    data[i] = 255 – data[i+1];
    data[i] = 255 – data[i+2];
}

context.putImageData(imageData, 0, 0);

It’s not the craziest piece of code ever, but this is just scratching the surface. Anyway, compare that to the simplicity allowed by a library like CamanJS:

Caman(‘#image-element-id’, function() {
                this.invert().render();
});

Fabric.js can also accomplish color inversion in a similarly straightforward fashion:

fabric.Image.fromURL(‘my-image-url.jpg’, function(img) {
                img.filters.push(new fabric.Image.filters.Invert());

});

That’s it! And one of the best parts about canvas libraries is that they’re still built on top of canvas, so if you need direct access to the canvas API, you can still dig down and build your own functionality, too!

Final Thoughts and Resources

Ultimately, choosing one of the above approaches is all about understanding the use cases and needs of your users.  Working directly with canvas provides the most fine-grained control, but canvas libraries reduce the overhead of getting up and running, while still allowing for low-level customization. In either case, there are loads of great resources available on the web to help you get started once you’ve taken the first step and chosen a path.

If you’re going pure canvas, the Mozilla Developer Network has an excellent reference with tutorials and lots of examples.

If you’re looking for a library approach, Caman.js and Fabric.js are two of the most popular libraries I’ve found. Both libraries have pretty solid documentation and plenty of examples to help you get underway.