Build a Simple Image Editor with CSS Filters and jQuery

Vikas Lalwani
Share

CSS Filters are a powerful tool to manipulate images using just CSS. Once implemented in all browsers, you will be able to apply effects to images without any need for external software.

CSS filters constitute a huge topic in themselves and I am not going to discuss all the available filters here. What I am going to talk about is how you can use multiple filters to produce a complex effect – and make your own image editor.

If you want to dig deeper, feel free to check out Filters on MDN or Understanding CSS Filter Effects, on HTML5 Rocks, both of which cover the general topic of filters in more detail.

CSS Filter Syntax

To write a filter effect in your CSS, just use filter: and name of the filter (like grayscale, blur, etc.).

.example {
  filter: <filter-function> [<filter-function>];
}

Here’s how you would apply a 90% grayscale filter to an element:

.example {
  filter: grayscale(90%);
}

And in the case of webkit browsers, you’ll need a prefix:

.example {
  -webkit-filter: grayscale(90%);
}

The value of a filter’s property generally falls between 0 and 1, but there are a few exceptions. For example, the blur property uses pixel units and can be any whole number. Also, the hue-rotate filter value is a whole number with a ‘deg’ unit.

.example {
  filter: blur(10px);
}

.example-2 {
  filter: hue-rotate(90deg);
}

Combining Multiple Filters

You may combine any number of functions to manipulate the rendering. However, if you want to apply more than one filter effect, you can do so by space separating them in a single declaration. Here’s how you’d combine grayscale and blur:

.example {
  filter: grayscale(0.5) blur(10px);
}

Building the Image Editor

Our image editor will have two parts:

  1. A URL field and Image container, to allow loading an image through an external URL.
  2. Controls, which will be sliders to apply different effects on the loaded image.

URL Field and Image Container

We will use two form elements to ask for an image URL: A text input and a button. Then we will load the image present at the URL in our imageContainer div.

Here’s the HTML:

<!-- Form for collecting image URL -->
<form id="urlBox" class="center">
    <input class="url-box" type="url" id="imgUrl">
    <input id="go" type="button" value="Go">
</form>

<!-- container where image will be loaded-->
<div id="imageContainer" class="center">
    <img src="/default.png" alt="">
</div>

And here is the jQuery:

// adding an image via url box
function addImage(e) {
    var imgUrl = $('#imgUrl').val();
    if (imgUrl.length) {
        $('#imageContainer img').attr('src', imgUrl);
    }
    e.preventDefault(); 
}

// on click of go(submit) button, addImage() will be called
$('#go').click(addImage);

// on pressing return(enter), addImage() will be called
$('#urlBox').submit(addImage);

Controls

This is the heart of our application and this is where we will actually operate on our original image to convert it into something different.

To take values for different filters, we will use range selectors. This will allow us to see the effect of our changes instantaneously. Here’s the code to add two range selectors – one for grayscale and another for blur (for simplicity, there are only two examples here, but the original code has 9 options):

This is the HTML:

<!--Controls for CSS filters via range input-->
<form id="imageEditor">
    <p>
        <label for="gs">Grayscale</label>
        <input id="gs" name="gs" type="range" min="0" max="100" value="0">
    </p>

    <p>
        <label for="blur">Blur</label>
        <input id="blur" name="blur" type="range" min="0" max="10" value="0">
    </p> 
</form>

To apply the effects of the changes on the CSS filters whenever a slider value changes, here’s the jQuery:

// Editing image via css properties
function editImage() {
    var gs = $('#gs').val(); // grayscale
    var blur = $('#blur').val(); // blur

  $('#imageContainer img').css('-webkit-filter', 
                               'grayscale(' + gs + '%) blur(' + blur + 'px');
}

// When sliders change, image will be
// updated via the editImage() function     
$('input[type=range]').change(editImage).mousemove(editImage);

Whenever a slider is adjusted, the editImage() function is called. editImage() first stores the value of the slider in respective variables (gs and blur), and then applies those to the image.

An important point to keep in mind here is the units of the specific filter you are applying. As you can see in the above code, it’s “%” for the grayscale() filter and “px ” for the blur() filter.

Now you can build upon the above code to add all the filters and have your own tiny image editor.

Demo and Full Code

You can view the final image editor with all 9 filters in action here. Or download the full code of the demo on GitHub.

Image Editor with CSS Filters

Now that you are aware of all the power CSS provides you to manipulate an image, you should surely give the filter property a try in your next project. If you are interested, you can go ahead and try adding following functionalities to the current app and make it more useful:

  • Option to upload an image from desktop.
  • Option to download the modified image.

Feel free to fork and send a pull request. Happy to collaborate!