Simple photo filters with VintageJS and Cordova

This post is more than 2 years old.

A quick demo today of something I ran into via StackOverflow. VintageJS is a JavaScript library that adds simple camera fitlers, like sepia and vignettes, to pictures. As long as your browser supports canvas, you can make use of the library rather easily. Here is one example, stolen from their docs.


var img = document.getElementById('yourImage');
var options = {
    onError: function() {
        alert('ERROR');
    }
};
var effect = {
    vignette: 0.6,
    sepia: true
};
new VintageJS(img, options, effect);

The library also integrates well with AngularJS, which is a plus for me as I'm trying to do most everything in Cordova with AngularJS now. (Well, most things past simple demos like the one I'm showing today.) I whipped up a quick demo to see how well it worked with the device camera, and unsurprisingly, it worked just fine. I began by creating a new project to base camera demos off of - "basic_camera". A while ago I set up a GitHub repo for my demos and I thought a basic camera example would be something I'd use often. You can find the source for that project here: https://github.com/cfjedimaster/Cordova-Examples/tree/master/basic_camera. It literally just uses two buttons and lets you source images from either the camera or the device library.

Using that as a base I simply added the VintageJS demo code to my success handler. Here is my entire JavaScript file.

document.addEventListener("deviceready", init, false);
function init() {

	function onSuccess(imageData) {
		console.log('success');
		var image = document.getElementById('myImage');
		image.src = imageData;

		var options = {
			onError: function() {
				alert('ERROR');
			}
		};

		var effect = {
			vignette: 0.6,
			sepia: true
		};

		new VintageJS(image, options, effect);

	}

	function onFail(message) {
		alert('Failed because: ' + message);
	}	

	//Use from Camera
	document.querySelector("#takePicture").addEventListener("touchend", function() {
		navigator.camera.getPicture(onSuccess, onFail, { 
			quality: 50,
			sourceType: Camera.PictureSourceType.CAMERA,
			destinationType: Camera.DestinationType.FILE_URI
		});

	});

	//Use from Library
	document.querySelector("#usePicture").addEventListener("touchend", function() {
		navigator.camera.getPicture(onSuccess, onFail, { 
			quality: 50,
			sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
			destinationType: Camera.DestinationType.FILE_URI
		});

	});

}

And here is one result from the iOS Simulator:

And here is an example running from my Nexus 7. My UI isn't optimized so forgive me for that. Also, I'm sorry my face is so scary. ;)

Pretty cool, and pretty simple. I put this version up in my GitHub repo as well: https://github.com/cfjedimaster/Cordova-Examples/tree/master/camera_vintagejs

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Dan Moore posted on 9/24/2014 at 12:20 PM

Hi Raymond,

I was wondering if you could expand on the comment about wanting to do most of your Cordova development on AngularJS? What is your reason for that?

Thanks,
Dan

Comment 2 by Raymond Camden posted on 9/24/2014 at 2:36 PM

If you don't read my blog regularly, then you may not know I spend a *lot* of time on Ionic (well, lately anyway). I'm a huge fan of it. Heck, see the blog post I wrote after this one for one reason why.

Comment 3 by David Normington posted on 9/27/2014 at 12:22 PM

Hi Raymond,

How did you find the performance? What size was the image?

I wrote something like this (but to edit brightness and contrast) and the performance was ok on a tablet but very poor on my mobile device.

Dave

Comment 4 by Raymond Camden posted on 9/27/2014 at 2:16 PM

I did *not* test it heavily - I just played with it a few times. It certainly seemed pretty quick.

Comment 5 by Travis posted on 10/9/2014 at 5:01 AM

What kind of performance did you observe on the device itself?

I was checking out http://camanjs.com/ and really like the design of the API, but noticed alot of complaints about filters taking a long time to render when using Cordova.

Comment 6 by Raymond Camden posted on 10/9/2014 at 6:16 PM

See my previous comment. :) A few tests, nothing terribly deep.

Comment 7 by Ifthaker Hossain posted on 5/2/2016 at 12:52 PM

Hello sir!
But the picture that has been taken from the camera is not being saved in the gallery. How to save such picture??

Comment 8 (In reply to #7) by Raymond Camden posted on 5/2/2016 at 12:54 PM

If you go to the docs for the Camera plugin, you will see there is an option you can use to save the image to the gallery. See here: https://www.npmjs.com/packa...

Comment 9 (In reply to #8) by Ifthaker Hossain posted on 5/2/2016 at 1:04 PM

Sir I am really sorry to disturb you, but I got caught up! What line of code should I add and where? Can you please tell if possible.
Thanks

Comment 10 (In reply to #9) by Raymond Camden posted on 5/2/2016 at 1:05 PM

Go to the docs as I said - it describes how you pass options to the Camera plugin when taking a picture. You will see the option I'm talking about.

Comment 11 (In reply to #10) by Ifthaker Hossain posted on 5/2/2016 at 6:50 PM

Hello sir,
I used this code to save the data saveToPhotoAlbum:true

It works! But only when i take the photo without sephia effect. It doesnt save the photo after it got the effect, it only saves the raw file.

Comment 12 (In reply to #11) by Raymond Camden posted on 5/2/2016 at 8:35 PM

Ah - you would need to get the image data by copying it to canvas and then getting the binary data. If you Google for that you should be able to find some examples. (Not saying go away, just saying this is something that has been done. :)