Manipulating Images on Web Pages with CamanJS

Share this article

A short time ago I was looking for an image manipulation library that I could use in a personal project. One library that I found and that appealed most to me was CamanJS, a JavaScript-based canvas manipulation library.

But wait… Since CSS supports basic image manipulation functionality out of the box you might be wondering why we’d want to use a JavaScript library for this. Well, besides browser support, Using CamanJS has a lot of advantages. It provides far more filters and options to manipulate images. You can create your own advanced filters and have control over every pixel in your image. You can use its built-in blend modes and layering system. And it enables you to manipulate cross-domain images and save the manipulated images.

Now, let’s start exploring the features that CamanJS offers!

Including Necessary Files

To start working with CamanJS simply include the library in your page. This minified CDN version that I am referencing here has all the plugins in addition to core functionality combined in a single file:

<script src="https://cdnjs.cloudflare.com/ajax/libs/camanjs/4.1.2/caman.full.min.js"></script>

The syntax for functions has changed a little from version 3 to 4 of CamanJS. so make sure you include a version greater than 4 when working following along with this tutorial.

Manipulating Images via HTML Attributes

CamanJS can be used to manipulate images using the data-caman attribute. The code below demonstrates you how to apply a brightness filter of strength “10” and contrast of strength “30” to an image:

<img data-caman="brightness(10) contrast(30)"
     src="yourimage.jpg">

Similar syntax is used for the other 18 filters that come prepackaged with the library. For example:

<img data-caman="love() hazyDays()"
     src="yourimage.jpg">

Manipulating Images via JavaScript

Alternatively, you can write a few lines of JavaScript to manipulate an image. The result when using JavaScript is no different from using the data-caman attributes.

Caman('#your-image-id', function () {
  this.brightness(40);
  this.contrast(-10);
  this.sinCity();
  this.render();
});

Implementing Controls for an Image Editor

Filters that don’t require much tweaking can be triggered on button click. Some filters like vintage(), lomo(), and sinCity() do not require a parameter. Other filters like contrast() and noise() need an integer value as a parameter. This value decides the strength of the filters.

Complex filters like tiltShift(), posterize(), and vignette() require more than one parameter. The code snippet below demonstrates how to work with three of these filters. Other filters can be coded likewise. Here is the HTML:

<canvas id="canvas"></canvas>
<button id="vintagebtn">Vintage</button>
<button id="noisebtn">Noise</button>
<button id="tiltshiftbtn">Tilt Shift</button>

Here is the JavaScript/jQuery to apply filters on button click:

var vintage = $('#vintagebtn');
var noise = $('#noisebtn');
var tiltshift = $('#tiltshiftbtn');

vintage.on('click', function(e) {
  Caman('#canvas', img, function() {
    this.vintage();
    this.render();
  });
});

noise.on('click', function(e) {
  Caman('#canvas', img, function() {
    this.noise(10);
    this.render();
  });
});

tiltshift.on('click', function(e) {
  Caman('#canvas', img, function() {
    this.tiltShift({
      angle: 90,
      focusWidth: 600
    }).render();
  });
});

tiltshift() also accepts additional parameters like startRadius and radiusFactor. vignette() takes two parameters size and strength. You can refer to the CamanJS documentation to gain a deeper understanding of all available filters.

Implementing Slider Controls

Filters like brightness, contrast, and hue that require comparatively more granular control over their values work perfectly with input range sliders. As you will see, implementation of slider controls differ slightly from button controls. You can use the following HTML to create range sliders:

<form id="silderInput">   
  <label for="hue">Hue</label>
  <input id="hue" name="hue" type="range" min="0" max="300" value="0">

  <label for="contrast">Contrast</label>
  <input id="contrast" name="contrast" type="range" min="-20" max="20" value="0">
</form>

This block of jQuery handles all the manipulating:

$('input[type=range]').change(applyFilters);

function applyFilters() {
  var hue = parseInt($('#hue').val());
  var cntrst = parseInt($('#contrast').val());

    Caman('#canvas', 'image.jpg', function() {
      this.revert(false);
      this.hue(hue);
      this.contrast(cntrst);
      this.render();
    });
}

The applyFilters() function is called whenever any of the input range sliders changes its value. This function stores the value of all range sliders in corresponding variables. These values are then passed as parameters to respective filters for editing the image.

I call this.revert(false) every time I apply these filters so that the canvas reverts back to its original state. Using revert makes sure that the filters are manipulating the original image and their effect is not compounding. The false passed as a parameter avoids a momentary flash of the original image during the reverting process.

Another noteworthy detail is that I apply all the filters again even if just one of them changes in value. This is because users don’t expect the contrast to reset when they are adjusting the value of hue or brightness.

Creating Custom Filters in CamanJS

One cool feature among many others of this library is that you can extend it by creating your own filters and plugins. There are two methods to create custom filters. You can combine built-in filters with appropriate values or you can create your own filter from scratch.

Here is the jQuery to create your own filter:

Caman.Filter.register('oldpaper', function() {
  this.pinhole();
  this.noise(10);
  this.orangePeel();
  this.render();
});

To create filters from scratch, you’ll need to do some extra work, due to a few existing bugs that you can read about in this open issue on the GitHub repo.

Layers and Blend Modes

Besides filters, CamanJS comes with an advanced layering system. This gives you much more image manipulation power and options. Unlike Photoshop, the layers in CamanJS can be nested. It uses blend modes to apply layers to their parents. The default blend mode is normal. CamanJS has ten blend modes in total, including common ones like multiply, exclusion, and overlay .

Below is the jQuery to create a custom filter using layers and blend modes:

Caman.Filter.register('greenTint', function() {
  this.brightness(-10);

  this.newLayer(function() {
    this.setBlendingMode("overlay");
    this.opacity(100);
    this.fillColor('#689900');
    this.filter.brightness(15);
    this.filter.contrast(10);
  });

  this.render();
});

Filters can be applied to both the original layer and new layer. Additionally, you can set several other properties like opacity and blend mode for the new layer. I have filled this layer with a solid color but you can fill it with another image by calling this.overlayImage('image.jpg').

Manipulating Cross-origin Images

If you need to manipulate images hosted on a different domain you can use the PHP proxy that comes with CamanJS. To enable this feature, you need to host this PHP script on your server. This script will proxy the image data from the remote source to your browser in order to circumvent the editing restrictions. Then you need to add following line to your JavaScript:

Caman.remoteProxy = Caman.IO.useProxy('php');

Saving the Edited Image

CamanJS has a built-in mechanism to save images after editing. With the current implementation, a call to this.save(png) will open a download file prompt but you will have to rename the file and add a png or jpg extension. This is because on calling this function browsers are redirected to base64 encoding of the image and they don’t know the file type. The code snippet given below saves the image:

this.render(function () {
  this.save('png');
});

Demo and Full Code

You can take a look at the demo of the image editor with all features in action in this CodePen demo, screen captured below:

CamanJS Demo

As an exercise you may attempt to improve the user experience by creating some kind of indication that filters are currently working on the image or modify the save button in such a way that it no longer requires renaming of the file.

As we’ve seen, CamanJS is an incredibly useful image manipulation library with many filters and continuously expanding functionality, and I have barely scratched the surface of its features in this tutorial.

Frequently Asked Questions (FAQs) about Manipulating Images on Web Pages with CamanJS

What is CamanJS and why is it used for image manipulation?

CamanJS is a powerful JavaScript library that is used for image manipulation on web pages. It allows developers to apply various effects and filters to images, such as brightness, contrast, saturation, and many more. The main advantage of using CamanJS is that it provides a simple and intuitive API, which makes it easy to use even for beginners. Moreover, it works directly in the browser, which means that you don’t need to install any additional software or plugins.

How can I install and use CamanJS in my project?

To use CamanJS in your project, you first need to include the CamanJS library in your HTML file. You can do this by adding a script tag with the source set to the CamanJS file. Once the library is included, you can start using it to manipulate images. You can select an image by its ID and then apply various effects and filters using the CamanJS API.

Can I use CamanJS to apply multiple filters to an image?

Yes, you can use CamanJS to apply multiple filters to an image. The library provides a chainable API, which means that you can apply multiple effects and filters in a single line of code. Each effect or filter is applied in the order they are specified, and the result is a composite of all the applied effects.

How can I create custom filters with CamanJS?

CamanJS allows you to create custom filters by defining a new filter function. This function takes an RGB object as input and returns a modified RGB object. You can use this function to manipulate the color values of the image in any way you want. Once the filter function is defined, you can apply it to an image using the filter method of the CamanJS API.

Is it possible to manipulate images dynamically with CamanJS?

Yes, it is possible to manipulate images dynamically with CamanJS. The library provides a set of event handlers that you can use to respond to user interactions, such as mouse clicks or keyboard events. You can use these event handlers to apply effects or filters to an image in response to user actions.

Can I use CamanJS with other JavaScript libraries or frameworks?

Yes, you can use CamanJS with other JavaScript libraries or frameworks. CamanJS is a standalone library, which means that it doesn’t have any dependencies on other libraries or frameworks. However, it can be easily integrated with other libraries or frameworks, such as jQuery or AngularJS, to create more complex image manipulation applications.

How can I save the manipulated image with CamanJS?

After manipulating an image with CamanJS, you can save the result by calling the save method of the CamanJS API. This method generates a data URL of the manipulated image, which can be used to display the image in a web page or download it to the user’s computer.

Can I use CamanJS to manipulate images on the server side?

CamanJS is primarily designed for client-side image manipulation. However, it can also be used on the server side with Node.js. To use CamanJS on the server side, you need to install the library using npm and then require it in your Node.js script.

What are the performance implications of using CamanJS for image manipulation?

CamanJS performs image manipulation operations directly in the browser, which can be computationally intensive. However, the library is optimized for performance and uses web workers to perform operations in the background, which helps to keep the user interface responsive. The performance of CamanJS also depends on the size and complexity of the images being manipulated.

Is CamanJS compatible with all browsers?

CamanJS is compatible with most modern browsers, including Chrome, Firefox, Safari, and Internet Explorer 10+. However, some features of the library, such as web workers, may not be supported in older browsers. It’s always a good idea to test your application in all the browsers you intend to support to ensure compatibility.

Monty ShokeenMonty Shokeen
View Author

Monty is a front-end developer who loves to learn about new JavaScript libraries and frameworks. He has been doing front-end development for three years now and likes to write about interesting libraries and tools that he comes across in his research.

'Image Manipulation'camanjscanvasimage editorLouisL
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week