Skip to: Navigation | Content | Sidebar | Footer

Weblog Entry


October 07, 2010

It occurs to me that I should finally mention here a project I’ve been working on over the past month or so. Much to my surprise, what started out as a simple foray into the canvas element’s pixel manipulation APIs quickly evolved into a full-fledged Javascript library called PaintbrushJS.

It’s basically a set of image filters that render in the browser. Greyscale, sharpening gaussian blur and more on the web, no ImageMagick or GD required. It allows you to take an image like this:

And using a simple class and a couple of HTML5 data-* attributes, render it in a number of different ways:

I skipped the jQuery and went full Javascript on this one, but it ought to play nice alongside most other Javascript libraries out there. More on how to use it, and there’s a real-time demo page you can play around with. (works best in Safari and Chrome, thanks to their speedy Javascript engines and support for the HTML5 range form input)

Since I’m using canvas to pull this off I’m automatically excluding IE8 and lower from the equation (it works great in the IE9 beta), which meant that I could also save out the images as dataURLs. The upshot? You can use the output images the same way you would any other image within a web page; as a CSS background, as source for a canvas animation, and if you really want, you can even Right Click -> Save As to save the filtered image to your hard drive.

(And this blog template is really starting to show its age. In a fit of irony worthy of an entire extra verse by Alanis, I had to pre-render the effects above and save them as separate images instead of showing them rendering realtime, because the HTML5-friendly PaintbrushJS doesn’t play nice with an XHTML doctype.)

October 07, 16h


FWIW, when I tried viewing/reading this entry in my feed reader (Google Reader), the images all showed your don’t-hotlink pic.

“Hi there.

“I see you’re attempting to use images
directly off my server. Since I pay for the
bandwidth, I’ve decided not to give you a
free ride.

“Please feel free to link to the page on my
site where you found this image, at least
that way at least I get some credit for
creating the image.


Kadir says:
October 07, 16h

I have to say it works very well in the new Firefox 4 pre beta7. But it’s a bit disappointing that the sliders are browser-specific :/

October 08, 06h

Images are working fine from Google Reader for me, so maybe it’s already been fixed. =)

The demo is great. I’ve played around with it in Firefox and Chrome, and the sliders are definitely a better experience.

One quick note: In Chrome, when you set the slider to a different value, the original image flashes before the newly filtered image replaces it. That didn’t happen on Firefox when I was setting values via text.

Do any of you know if it’s possible to copy an arbitrary element to the canvas? e.g., let’s say I have a div with three different images, some borders, a background color, more child elements, etc. and I wanted to copy that entire div to the canvas, then apply a transform. A friend wants a gaussian blur effect over a div like that which has elements that are scrolling sideways. If it was possible to copy an arbitrary element to the canvas and modify PaintbrushJS to use web workers and/or WebGL calls, it might just be fast enough to do in real-time. As far as I can tell, currently you can only insert images and other canvas elements into the canvas element, but maybe a few years from now this would be possible! For now, she’ll probably have to fake it by making a pixel perfect layout and making a (or several) large, pre-blurred image that scrolls by. Eww.

October 08, 07h

It looks like the scenario in my previous comment is possible in Firefox with their drawWindow extension to the canvas element; however, it’s only allowed for code running with Chrome privileges (e.g. extensions) because of several potential security vulnerabilities:

// We can’t allow web apps to call this until we fix at least the
// following potential security issues:
// – rendering cross-domain IFRAMEs and then extracting the results
// – rendering the user’s theme and then extracting the results
// – rendering native anonymous content (e.g., file input paths;
// scrollbars should be allowed)

Ah well. =)

Dave S. says:
October 08, 08h

@Kevin - Not sure why you’re seeing the hotlinked image swap thing, Google Reader works fine on this end.

@Kadir- when Firefox supports input type range, it’ll get the sliders too. Sadly that didn’t happen for beta 4.

@Nate Bundy - not sure if I care enough about the original image flashing to fix it, it’s just a demo page and not the main thrust of the library.

With regards to your question though, a) web workers are definitely on the horizon, and b) there seem to be plans to allow web content other than images into canvas – – but it’s awfully browser-spcific at the moment. There’s also this, which theoretically PaintbrushJS could use as the source image –

Markus Stange says:
October 08, 08h

@Nate Bundy: Firefox supports SVG filters on HTML elements, which you can use to get your gaussian blur:

Matt Stapleford says:
October 28, 02h

This is really cool. The added effects are really nice and excellent news that it also works in IE9. I do not blame you for excluding IE8 and lower as am not sure how this would function in the dated IE browsers with all the problems they cause. Cool that you can also save the images to data URLs also.

November 10, 03h

Nice work. Always interesting to see HTML5 / CSS3 demos (the next thing in my ‘must learn’ pile).

That said, I suspect it will be a while until we can write off making sites which work in IE8, considering how long IE6 is taking to die.

Out of interest, does your demo demonstrate mostly all image manipulation you can do with CSS3, or are there any other filters you have not used?

November 12, 04h

Great article and great effects. I do all of my own image manipulation and so this one will definitely get saved into my “useful” folder. Thanks!

November 12, 14h

This is really slick, Dave. And I already have a feature request! For the Color Tint filter, would it be possible to add the option to multiply the tint color on top of the image (a la a Color Overlay layer effect with Multiply blend mode in Photoshop)? I’ll confess I have a specific usage in mind for this, but I think it would be a good addition in general. As always, keep up the good work.