HTML & CSS
Article

Build a Simple Image Editor with CSS Filters and jQuery

By Vikas Lalwani

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!

Comments
131studios

Very informative article, thanks. How would you go about saving the edited version of this image?

Vikas_Lalwani

Hey! Thanks for reading my article and I am glad you liked it smile

Saving is difficult with current code because we are not changing the original pixels of the base image. As mentioned my Christian Heilmann in the GitHub issue, to facilitate saving we need to move the functionality to canvas. I'll work on it and post the code on GitHub and also in this article's comment section.

One dirty way would be capture screenshot, but I would NOT recommend that. I'm planning to build something which will allow you to get new image of the size of the original.

You might find this very helpful in the meantime: https://github.com/meltingice/CamanJS/

Vikas_Lalwani

Hey Collins, thanks for taking out time to read the article smile

I've replied to the original comment with details. Please let me know if you need anything else. Happy to help!

mohammad_ali021

Hi !
I am looking for an image editor for my project this example is amazing and I like it; but the only problem with this project is; that we can't modify the original image.
I have used Html2Canvas to get screenshot of edited image but it also doesn't work and still it take the original image color after editing of any image trough this editor.
any idea to solve this problem?

Vikas_Lalwani

I am glad you like it Mohammad smile Here's the solution that you are looking for: http://camanjs.com/examples/ It modifies the original image. Hope it helps!

Moxet_Khan

Amazing! I just need a favor or clarifcation. Is it possible to render the final image via html2cavnas? I tried manually to use filters but failed.

Recommended
Sponsors
Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in Front-end, once a week, for free.