Capturing camera/picture data without PhoneGap

Two years later and this blog post is still highly popular. If you like this content, be sure to subscribe to the blog to get the latest updates. You may also want to check out my Apache Cordova book and the JavaScript videos I have available.

As people know, I'm a huge fan of PhoneGap and what it allows me to do with JavaScript, HTML, and CSS. But I think it is crucial to remember that you don't always need PhoneGap. A great example of that is camera access. Did you know that recent mobile browsers support accessing the camera directly from HTML and JavaScript? Let's look at an example.

Over a year ago I wrote a blog post in which I created an application called "Color Thief." This application made use of PhoneGap's Camera API and a third party JavaScript library called Color Thief. I loved this example because it demonstrated how you could combine the extra power that PhoneGap provides along with existing JavaScript libraries.

This morning I watched an excellent Google IO presentation (https://www.youtube.com/watch?v=EPYnGFEcis4&feature=youtube_gdata_player) on Mobile HTML. It was an overview of some of the exciting stuff you can now do with mobile HTML and JavaScript. To be clear, this was all without using wrappers like PhoneGap.

In one of the examples the presenters discussed the new "capture" support for the input/file field type. This is rather simple to implement:

<input type="file" capture="camera" accept="image/*" id="takePictureField">

If supported (recent Android and latest iOS), the user can then use their camera to select a picture. I decided to rebuild my old demo to skip PhoneGap completely and just make use of this feature. Here's the code:

For the most part, this is pretty similar to the last version. I no longer wait for the deviceready event, but instead just listen for the document itself to load. Instead of listening for a button click, I've switched to an input field using type=file. I now listen for the change event, and on that, I see if I have access to a file. If I do, I can then use the URL object to create a pointer to the source and then simply add it to my DOM. After that, Color Thief takes over.

The only tricky part I ran into was that in iOS the URL object is still prefixed. You can see how I get around that in the startup code. To be fair, this isn't 100% backwards compatible, I could add a few checks in here to ensure that things will work and gracefully let people on older phones know they can't use this feature.

But the end result is nearly the exact same functionality in a web page - no PhoneGap, no native code.

Archived Comments

Comment 1 by Tarek posted on 5/20/2013 at 8:38 PM

when i scan QR the app, Adobe phonegap build is openning on ios6 but the application is not installed.

Comment 2 by Raymond Camden posted on 5/20/2013 at 9:53 PM

What are you talking about? This is not a PhoneGap application.

Comment 3 by Anas posted on 5/21/2013 at 9:36 AM

Good Article
Thanks :)

Comment 4 by Tarek posted on 5/21/2013 at 2:12 PM

cheers !!

Comment 5 by tim posted on 5/21/2013 at 11:47 PM

Tried this on my android phone running 4.2.1, didn't work, just went to the usual select a file dialog. Do you have a video of it working on android?

Comment 6 by Raymond Camden posted on 5/21/2013 at 11:59 PM

I just tried with an Android emulator using 4.1.2 and it worked. Does your device have a camera?

Comment 7 by tim posted on 5/22/2013 at 12:17 AM

K, so I tried viewing the same code in chrome (non-stock browser) and it works. The problem is that there is no way to change which browser handles the webview in phonegap so I am stuck with the stock browser which has yet to support this feature :(

Comment 8 by Raymond Camden posted on 5/22/2013 at 12:22 AM

Well to be clear, this whole blog post is about *not* using PhoneGap. You get that, right?

Comment 9 by tim posted on 5/22/2013 at 12:30 AM

I get that but technically I wasn't using phonegap, non of the api's at least. It would be the equivalent of just using android's stock browser and browsing to the html since the webview is the same thing. I am wondering if 4.2 supports this in its stock browser.

Comment 10 by Raymond Camden posted on 5/22/2013 at 12:52 AM

I'd imagine the stock browser is not going to add anything. In fact,it shouldn't. It should just die probably. Mobile Chrome is the future.

Comment 11 by John Brown posted on 5/22/2013 at 2:42 AM

Thanks. I actually have been meaning to research this ever since I noticed that I could access my mobile photos via Wordpress on my mobile device. I was like cool!

How about video captured from your mobile device? Possible?

Comment 12 by Raymond Camden posted on 5/22/2013 at 6:48 AM

If you watch the video I linked to (it is short, 40 minutes), they show an example using getUserMedia. Different API, bit less support, but where it does work, it is pretty darn easy. (I've blogged on it before.)

Comment 13 by Andrew posted on 5/22/2013 at 2:56 PM

I would love to be able to record audio this way. Is this or will this be possible?

Comment 14 by Raymond Camden posted on 5/22/2013 at 3:10 PM

According to spec, yes:

http://www.w3.org/TR/html-m...

ctrl-f for audio and you will see an example. I haven't tested this yet though. You should be able to get access to the binary bits which you could them store someplace (remember that XHR2 lets you upload files via AJAX).

Comment 15 by Raymond Camden posted on 5/22/2013 at 3:16 PM

Also know that getUserMedia can do this. It is a different spec.

Comment 16 by Raymond Camden posted on 5/22/2013 at 3:25 PM

I did a quick test w/ accept="audio/*" and it worked on my Android simulator, but not the iOS Simulator. However, the failure on iOS may be more the simulator then iOS. I'll test with my iPhone a bit later.

Comment 17 by Andrew posted on 5/22/2013 at 4:28 PM

Thanks. I don't suppose there is any way of saving locally on the phone (e.g. if there is no network connection)?

Comment 18 by Raymond Camden posted on 5/22/2013 at 7:48 PM

Unfortunately, file system access is only enabled in PhoneGap. In theory, one day, mobile devices will support IndexedDB, which allows you to store binary bits as well. That would be a way to store the value.

Comment 19 by John Brown posted on 5/22/2013 at 11:06 PM

Thanks. Will watch the video. Starting to browse your older posts. Great stuff.

Comment 20 by Andrea Giammarchi posted on 5/24/2013 at 9:04 PM

you can save images offline already in all browsers via WebSQL, falling back into IndexedDB, falling back into localStorage.

The trick is to create a canvas, draw the image file on it, and use canvas.toDataURL() to obtain the base64 string you can save or reuse whenever you want.

To dig more into this possibilities without PhoneGap, I've experimented with camera too ending up falling back into animated gifs created on the fly to simulate a vine app for web.

http://webreflection.blogsp...

Comment 21 by Matt Porter posted on 5/29/2013 at 11:21 PM

Works on my Nexus and iPhone in Chrome mobile... Crome mobile is the future!

Comment 22 by Joe Milton posted on 6/12/2013 at 10:25 PM

As always Ray, very well done and very helpful.

Comment 23 by Hazel Planchart posted on 6/13/2013 at 10:23 PM

It works on the iPad but it never renders the captured picture.

It only shows the thumbnail on the top of the page.

It doesn't work on several Android phones and tablets that I tried it on; all have cameras.

Testing on iPhone 5 ...

Comment 24 by Raymond Camden posted on 6/13/2013 at 10:30 PM

Hazel, it could be a number of things. Lets focus on iPad. Can you please try the remote debugger via Safari and tell me what you see?

Comment 25 by Raymond Camden posted on 6/13/2013 at 10:36 PM

I just tested in my iPad and it worked fine. Try this URL. Maybe you forgot something when you tried my code.

http://www.raymondcamden.co...

Comment 26 by Hazel Planchart posted on 6/13/2013 at 10:43 PM

Your site works!

I simply copied the HTML code and pasted it in a file to test at the web server.

It does everything except rendering the big picture and filling in the color scheme below.

Thanks!

Comment 27 by Hazel Planchart posted on 6/13/2013 at 10:48 PM

I'm missing the scripts. That's the reason. :(

Comment 28 by Raymond Camden posted on 6/13/2013 at 11:00 PM

So... I'm confused. Is it working for you now?

Comment 29 by Hazel Planchart posted on 6/14/2013 at 12:33 AM

After I placed the js scripts it works perfect.

I was misled by the over-simplicity.

Thanks!

Comment 30 by Don Stewart posted on 6/17/2013 at 4:29 AM

I want to capture video from iPad using a browser without downloading an app.
Your article says this works on latest iOS.
I am using iPad with os 6.1.3 (just updated) and I cannot get it to work.
Does anyone have a link to a sample that does work. The end goal is to build a cross platform video chat / desktop sharing website with absolute minimum setup for the end users.

Comment 31 by Raymond Camden posted on 6/17/2013 at 4:32 AM

I don't believe I said it works in video - just pictures. You want to look at WebRTC for video. Not sure if it is supported on iPad yet though. (caniuse.com is failing me.)

Comment 32 by Don Stewart posted on 6/17/2013 at 5:31 AM

Ahh yes... Sorry, I had "webcam access" on the mind. It's always dangerous to combine rushed reading with too much wishful thinking. Even still, this is a step forward, do you have a link to a working example of this? Thanks for the quick reply btw..

Comment 33 by Olivier posted on 6/17/2013 at 6:51 AM

Really Exciting!
I am Working on a Phonegap/Jquery Mobile app that would requiers a custom camera overlay. Since it appears quite complicated to write a complete phonegap plugin to do so, i am exploring using this technique. However, Do you know if it is possible to get to the camera stream directly in the Html, without opening the camera UI like in your example? Thank you and great work.

Comment 34 by Olivier posted on 6/17/2013 at 6:56 AM

Might be answering my own question here ;)
It looks like that would requiers using the getUserMedia/Stream API which is not yet available on mobile device.

Comment 35 by Raymond Camden posted on 6/17/2013 at 4:13 PM

Found the right caniuse search term:

http://caniuse.com/#feat=st...

Comment 36 by Raymond Camden posted on 6/17/2013 at 7:25 PM

Actually, looking at this:

http://mobile.dzone.com/art...

They show support for video, but, I believe it is just as a file. WIll test after my presentation in a bit. This would still give you (if it works) the ability to upload a video, you just couldn't stream it.

Comment 37 by Raymond Camden posted on 6/17/2013 at 10:51 PM

So - video does work. It just gets attached to the input file field and - in theory - should be available if you POST the form (or use XHR).

In theory.

Comment 38 by akeem posted on 6/24/2013 at 1:19 PM

@Raymond: it works also with videos (iphone + htc android), i just tested it. the problem then remains the different video-codecs of the files uploaded ;) i suppose one has to process them all with ffmpg server-side to have useful user-input...

Comment 39 by Raymond Camden posted on 6/24/2013 at 2:11 PM

You could use something like ZenCoder to handle processing the input.

Comment 40 by akeem posted on 6/24/2013 at 2:39 PM

Shure ZenCoder is one option (ffmpeg is free), although this is not the place to talk about that - it's simply fantastic that this access to the camera works. Thanks for your post - great work!!

Comment 41 by Steph posted on 6/25/2013 at 6:13 PM

Hi,

Working on Android 4.2.2 but when taking a picture, orientation is bad... there is only one position on the phone that take a picture on the good orientation, all others take it 90° or 180° wrong... any way to make sure the picture is ok?

Comment 42 by Raymond Camden posted on 6/25/2013 at 7:23 PM

Once you set the DOM img tag to the source of the new image, you could check the H/W properties and try to determine orientation there. But no - that won't work because I may be taking a landscape picture.

You can - in theory - read the EXIF data using JavaScript. That contains orientation data.

Comment 43 by Steph posted on 6/25/2013 at 10:21 PM

Ok I'll try to find a script to read the orientation... And an other to rotate :-(
And is there a way to upload the photo to the server then?
Thanks

Comment 44 by Steph posted on 6/26/2013 at 3:51 PM

I have big difficulties to convert the format img src=blob:into file to upload :-((

Comment 45 by Raymond Camden posted on 6/26/2013 at 5:17 PM

Steph - why do you need to convert it? If you submit the form it should just upload, right?

Comment 46 by Steph posted on 6/26/2013 at 5:24 PM

No... It uploads the texte blob:http://xxxxx/fdsfdsf-dsf-sdfsdf and I don't know what do to with that stuff...

Comment 47 by Raymond Camden posted on 6/26/2013 at 5:27 PM

Odd - well - I'll test - but I'm on the road so it may be a day or two.

Comment 48 by Steph posted on 6/26/2013 at 5:28 PM

Cool! Thanks

Comment 49 by Raymond Camden posted on 6/26/2013 at 7:55 PM

So I just tested and it worked for me. But note - don't forget to give your file input field a name. My example above just uses an ID. You also need a proper form tag too.

Comment 50 by Steph posted on 6/26/2013 at 7:57 PM

Can't get it work... Could you post the code you user to get it please?

Comment 51 by Raymond Camden posted on 6/26/2013 at 7:58 PM

To be clear, I added this:

<form enctype="multipart/form-data" method="post">

and changed my file input field:

<input type="file" capture="camera" accept="image/*" id="takePictureField" name="filetest">

added a submit button - and that was it. I tested on my ColdFusion server where I just dumped out the form fields. The file was uploaded successfully.

Comment 52 by Steph posted on 6/26/2013 at 7:59 PM

Yes, ok, but on the server side?

Comment 53 by Steph posted on 6/26/2013 at 8:02 PM

Did you dump file string (blob:xxxxxx)? Or the file itself? Because I'm ok to upload file string, but after I don't know how to manage it to make a real image file...

Comment 54 by Raymond Camden posted on 6/26/2013 at 8:03 PM

Let me confirm the file really really uploaded.

Comment 55 by Raymond Camden posted on 6/26/2013 at 8:07 PM

I have confirmed. The file uploaded fine to my CF server.

Comment 56 by Steph posted on 6/26/2013 at 8:08 PM

Could you post the whole code here please?

Comment 57 by Steph posted on 6/26/2013 at 8:09 PM

Oh, sorry, perhaps an important thing: I'm trying to upload via jquery/ajax not a simple html form...

Comment 58 by Raymond Camden posted on 6/26/2013 at 8:16 PM

Ah - don't forget that "regular" AJAX can't do file uploads. XHR2 can, and frankly, has even better support then what I used here. Just hit up html5rocks.com - they have a few blogs posts on XHR2.

Comment 59 by Steph posted on 6/26/2013 at 8:18 PM

And With the use of canvas.toDataURL it is possible? Cause I can get the picture from the base64 encoding url...

Comment 60 by Raymond Camden posted on 6/26/2013 at 8:19 PM

You don't need to do this though. Again, check out the XHR2 stuff.

Comment 61 by Steph posted on 6/26/2013 at 9:04 PM

Can't find a solution with xhr2 too... :-(

Comment 62 by Raymond Camden posted on 6/26/2013 at 11:28 PM

Sorry, what do you mean? You can find the link? Try: http://www.html5rocks.com/e...

Comment 63 by Steph posted on 6/27/2013 at 12:03 AM

Yes, I found it, but I don't understand anything, it's too complicated for me... I've tryeid several solutions and couldn't get anything from...

Comment 64 by Raymond Camden posted on 6/27/2013 at 1:41 AM

Ah, are you new to JavaScript? Trying to understand where the breakdown is.

Comment 65 by Steph posted on 6/27/2013 at 2:08 AM

Yes, I'm new...

Comment 66 by Raymond Camden posted on 6/27/2013 at 3:26 AM

Well, best I can recommend is to at least give it a try. I can't write the code for you. Consider this an opportunity to learn. :)

Comment 67 by Arcayne posted on 7/10/2013 at 2:10 AM

Hi Raymond,

Thanks for this info, I am trying to use it together with parse.com but I came into some issues there, I saw in the past you were interested on using PG and parse.com for uploading images but wasn't really the easiest choice.

Anyway here it is my issue that hopefully is interesting for you:

http://stackoverflow.com/qu...

Comment 68 by Raymond Camden posted on 7/10/2013 at 3:15 PM

Fascinating. I wasn't aware their API had been updated to support this. I see it isn't working for you. I'll try and see if I can get my own demo to work.

Comment 69 by mark posted on 7/10/2013 at 3:29 PM

On safari on ios 6.0, the capture attribute is ignored. Good article though

Comment 70 by Raymond Camden posted on 7/10/2013 at 3:41 PM

Eh? I used iOS6 in my video above.

Comment 71 by Raymond Camden posted on 7/10/2013 at 4:49 PM

As an FYI Arcayne, you may want to post your question to the Parse forum instead of SO, may get a quicker response.

Comment 72 by Arcayne posted on 7/10/2013 at 5:06 PM

Make sense - https://www.parse.com/quest... -

BTW thanks for your great blog!

Comment 73 by Raymond Camden posted on 7/10/2013 at 5:12 PM

By the way - I just did a test and it worked fine as is. Here is my code (minus the real IDs). Note the html is just a file field and a button.

https://gist.github.com/cfj...

Comment 74 by Raymond Camden posted on 7/11/2013 at 2:20 AM

As just an FYI, I was able to make it work with PhoneGap just fine.

Comment 75 by Raymond Camden posted on 7/11/2013 at 3:12 AM
Comment 76 by Wilfo Derek posted on 7/15/2013 at 12:50 AM

Good work Raymond.I am trying to do it the same but with my android camera but get a mistake.

Does your project work for android capturing video on realtime?
logica_razon@hotmail.com

It's urgent...Thanks in advance.

Comment 77 by Raymond Camden posted on 7/15/2013 at 1:36 AM

Just pictures - not video afaik.

Comment 78 by muhaimin cs posted on 7/21/2013 at 10:41 PM

do u have any idea for snap a photo offline and when the internet is available, it will upload to the server..thanks

Comment 79 by Raymond Camden posted on 7/22/2013 at 12:14 AM

Well, the first part 'snap a photo' is already covered. As for knowing the Internet is available, try listening for the offline/online events. See here for more info:

https://developer.mozilla.o...

Comment 80 by muhaimin cs posted on 7/22/2013 at 4:54 AM

what i mean was how do i store the photo on cache/localStorage and later upload when the connection is ready. I dont know where to put the photo while mobile is offline. My targeted device is ipad mini

thanks ramden

Comment 81 by Raymond Camden posted on 7/22/2013 at 4:56 AM

If the web page is open, you don't have to store it per se - the file is still selected and you have access to it and can POST the form. Otherwise - not sure what to suggest. If you can convert to Base64 you can store it in WebSQL or localStorage.

Comment 82 by muhaimin cs posted on 7/22/2013 at 12:34 PM

consider if the page will be closed and what ever user input will upload when the connection is ready. The example you've shown here (http://www.raymondcamden.co... is pretty close to what i mean. but only photo support i curious to put it where

Comment 83 by Raymond Camden posted on 7/22/2013 at 3:40 PM

Then you would need to do what I suggested - converting it to base64 and storing it in WebSQL or localStorage.

Comment 84 by muhaimin cs posted on 7/23/2013 at 11:25 AM

is there any sample around this blog?

Comment 85 by muhaimin cs posted on 7/23/2013 at 11:39 AM

and associate it with content of user input

Comment 86 by Raymond Camden posted on 7/23/2013 at 3:13 PM
Comment 87 by greg baker posted on 7/28/2013 at 6:09 PM

Thank you for your blog and this post. The time that you take to help others, like myself, is greatly appreciated.

greg

Comment 88 by Jasper Grannetia posted on 8/2/2013 at 6:35 PM

Hi Ramond,

Do you have any pointers as to how to POST the images that are shot using this code? I Googled around a bit and learned quite a bit on object URLs, but that only leads me to suspect that there are no methods for turning these blob into anything that could be posted. Maybe this is because of security considerations?

Hope you can help me out (again :-D)!

Thnx in advance,

Jasper

Comment 89 by Raymond Camden posted on 8/2/2013 at 9:49 PM

Jasper: It just works. When you submit the form the image is attached just like any other form upload. As to how you handle it, it depends on your application server.

Comment 90 by Jasper Grannetia posted on 8/2/2013 at 9:57 PM

I tried posting the form I enclosed the file field in to CF10 and I cfdumped the form-scope, which did not contain a file field like I expected.

But if you say so, I'll have another look. :-)

Thnx, I will post back on my results.

Jasper

Comment 91 by Raymond Camden posted on 8/2/2013 at 9:58 PM

You need to ensure you add a name to the form field. My demo didn't need it, but you have to add it.

Comment 92 by Jasper Grannetia posted on 8/3/2013 at 12:39 AM

Hi,

Turns out it works just fine like you said. My problem was that I was working in a JQM site, which does things asynchonously, obviously (well, it's obvious now :-D)...

I'll work around the that somehow and enjoy this wonderful new feature. Thnx for pointing it out.

CU :-)

Jasper

Comment 93 by Raymond Camden posted on 8/3/2013 at 12:46 AM

Don't forget you can disable that in JQM pretty easily - either at the tag level for one form or globally. Also note that modern browsers, especially the ones that support this, also support XHR2, which allows for form uploads over AJAX. (Although it would still break in JQM as by default it would not be using that.)

Comment 94 by Matej Petek posted on 8/23/2013 at 10:45 PM

Great work!
This question is a little off topic but maybe you will know.
Is it possible to stream video directly from camera to DIV (or form). It will work like display on camera, capturing from back camera and show this in DIV?
Same functionality as photo app without recording images or video.

Comment 95 by Raymond Camden posted on 8/23/2013 at 10:57 PM

Nope, not yet. (At least not as far as I know.)

Comment 96 by mahima posted on 9/8/2013 at 11:54 AM

is it that we should work on webView to implement this code?

Comment 97 by Raymond Camden posted on 9/8/2013 at 3:56 PM

@Mahima: No idea what you mean. This works in the web browser on the mobile device.

Comment 98 by mahima posted on 9/9/2013 at 12:23 PM

I have been developing the android app using webview.is your code applicable in webview of android?

Comment 99 by Raymond Camden posted on 9/9/2013 at 2:25 PM

As the post says, it is supported in recent Android - so if the Android version supports it, then it should work.

Comment 100 by Danilo posted on 9/12/2013 at 12:36 AM

How do I get the picture that was taken? it doesn't return anything for me...

Comment 101 by Raymond Camden posted on 9/12/2013 at 1:22 AM

Are you on an older Android perhaps? Or older iOS? Obviously the support isn't 100%. You can write code to check for this and provide a message so that folks (like you) at least know why they can't use this particular feature.

Comment 102 by Jake posted on 9/13/2013 at 6:49 AM

How can I take a picture and upload it to my server? Sorry I didn't understand very well...I'm able to take the picture but how can I have access to this picture on my site...I would like to store it. I'm using an ipad 2.

Thanks for the help!

Comment 103 by Jake posted on 9/13/2013 at 6:53 AM

I added a submit button like you said but the "get" comes empty... $_FILES["picturename"] it comes back empty so I cant upload it any tips please? =/

Comment 104 by Raymond Camden posted on 9/13/2013 at 6:20 PM

I don't know PHP, but you should wrap my input field above with a form tag and ensure you use the right enctype for form uploads.

Comment 105 by Chris Lo posted on 9/27/2013 at 5:01 PM

Won't work on chrome on my Sony Xpedia z. It says failed to open file with the default camera app.

Works on Firefox tho?

Any ideas?

Comment 106 by Raymond Camden posted on 9/27/2013 at 5:02 PM

Sorry - no idea. Android browser?

Comment 107 by Alina posted on 9/29/2013 at 3:14 AM

That was SOOOOO helpful. Thanks!

Comment 108 by Ravi Kumar posted on 10/3/2013 at 10:06 PM

Hi,

I am developing an application and one requirement is that user can capture a new photo from camera or select existing photo from gallery. i am using html5 tag <input id="a-imagery-image" type="file" accept="image/*;capture=camera" style="display:none" multiple>.

the problem is when i opened in the iPad, its only giving option to select from gallery only. its not showing options like "take photo", "choose existing", "cancel" options.

i have tried in both chrome and safari.

iPad Details:
version: 7.0.2(11A501)
Model: MD371LL/A

Could you please help me in this issue

Thanks in advance.

Best Regards,
Ravi Kumar

Comment 109 by Raymond Camden posted on 10/3/2013 at 11:53 PM

What happens when you remove display:none?

Comment 110 by Ravi Kumar posted on 10/3/2013 at 11:57 PM

Hey Raymond,

I found out the issue. when i remove the "multiple" option from the input tag its working normally.

Con't we select multiple files at a time in iPad?

Thanks for the response.

Comment 111 by Raymond Camden posted on 10/4/2013 at 12:01 AM

I'm guessing no. Or it only allows for existing pics when multiple is true.

Comment 112 by Alina posted on 10/7/2013 at 5:11 AM

Hi,
the code doesn´t work for me :-(. I saved it to an HTML file and made sure the paths to the js-files are correct.

I get the following error:
ReferenceError: createPalette is not defined
var colorArr = createPalette($("#yourimage"), 5);

Please help!

Comment 113 by Raymond Camden posted on 10/7/2013 at 5:12 AM

It sounds like you didn't get the path right for quantize or color-theif. I'd double check those.

Comment 114 by Alina posted on 10/7/2013 at 5:28 AM

Yes, I figuered. But even when I go though the quantize or color-theif code I can´t find any createPalette ?!

Comment 115 by Raymond Camden posted on 10/7/2013 at 5:39 AM

It looks like his library was updated and the API changed. I believe it is getPalette now, not createPalette.

Comment 116 by Alina posted on 10/7/2013 at 6:10 AM

That´s a good point but unfortunately it still doesn´t solve my problem.
According to color thief I should use
getPalette(sourceImage[, colorCount, quality]
So in this case:
getPalette($("#yourimage"), 5,0); ?!

Still undefined!

Comment 117 by Raymond Camden posted on 10/7/2013 at 6:30 AM

If you have the latest JS and it still isn't working, then I'd check to ensure you didn't mess up the script src. This would be easier if it were online where I could see it.

Comment 118 by Alina posted on 10/7/2013 at 9:08 AM
Comment 119 by Raymond Camden posted on 10/7/2013 at 2:13 PM

I believe you want ColorTheif.getPalette.

Comment 120 by Raymond Camden posted on 10/7/2013 at 2:15 PM

Actually no - follow the lead you see here: https://github.com/lokesh/c....

ex:
var colorThief = new ColorThief();
colorThief.getPalette(sourceImage, 8);

Comment 121 by Alina posted on 10/7/2013 at 9:34 PM

No, I just don´t get it, sorry. Nothing works.
Is there any possibility you can post the old API with the code to make it work?

Comment 122 by Raymond Camden posted on 10/7/2013 at 9:47 PM

I don't have the time right now to rebuild it. I'll try sometime later, but no promises.

Comment 123 by Raymond Camden posted on 10/8/2013 at 7:58 PM

Please see this HTML:

https://gist.github.com/cfj...

There are two changes. First, you only need the color thief JS file, not the quantize one.

Second, lines 63-64 were modified to use the new API. I've confirmed it works for me.

Comment 124 by Alina posted on 10/8/2013 at 10:32 PM

You are awesome!Thanks so much! I just forgot to put the square brackets.

Comment 125 by Sukant posted on 10/14/2013 at 2:14 PM

Can it work on desktop?

Comment 126 by Raymond Camden posted on 10/14/2013 at 2:41 PM

What happened when you tried? :)

So - the spec here (http://dev.w3.org/2009/dap/..., is not covered at CanIUse.com. HTML5 Rocks has this listed for support (source http://www.html5rocks.com/e...

Android 3.0 browser - one of the first implementations. Check out this video to see it in action.
Chrome for Android (0.16)
Firefox Mobile 10.0
iOS6 Safari and Chrome (partial support)

So desktop looks a bit poor. I'd probably just WebRTC there instead.

Comment 127 by Thomas posted on 11/6/2013 at 4:34 PM

I didn't know this capture attribute, it's good. But since a simple input file doesn't work on Windows phone it can't be an entire multiplateform solution.

I think we have to use phonegap File API to make a picture upload works on Windows Phone, but maybe you know another solution without phonegap ?

Thank you

Comment 128 by Raymond Camden posted on 11/6/2013 at 5:55 PM

To be clear, Thomas, I didn't necessarily mean to imply that this would work as much as PG. I just wanted to point out that - at least eventually - PG wouldn't be needed for some of the things it does now. And that's a good thing. :)

Comment 129 by Thomas posted on 11/6/2013 at 6:11 PM

I agree with you, I'm not a huge fan of phone gap, I use to develop mobile apps with the strict minimum of Phone gap stuffs.

It's not your solution that I criticize, it's rather Windows phone to not support input file. They are late ... as usual. By the way a nice link about input file support (2012, but I think it's not moving fast ...) : http://viljamis.com/blog/20...

Comment 130 by Raymond Camden posted on 11/6/2013 at 8:11 PM

I love what Microsoft is doing designwise on mobile. I almost considered a Surface tablet. But - yeah - HTML5 support can be spotty on mobile.

Comment 131 by imal posted on 11/28/2013 at 8:18 PM

Hey Raymond, first of all thank you very much for this great post, it works perfectly on mobile browsers. but i'm having a little question i hope you can guide me, i wrote an application using your script + jquery mobile and it works perfectly in android and iphone as a mobile webpage but i wanted it to build as a mobile application, so i used http://seattleclouds.com/ to build for iphone and android and after building it works for iphone but not for android, nothing happens in android what can be the possible problem for this

i found that android webview is not supporting html5 unless you have activate it is that the problem

Thank you for your time
imal

Comment 132 by Raymond Camden posted on 11/29/2013 at 12:02 AM

Sorry, but as I don't use Seattleclouds, I can't really say. I'd suggest checking any debug options you may have with that platform. Or see if you can use Weinre with it.

Comment 133 by imal posted on 11/29/2013 at 12:22 AM

Thank you for the reply, did you tried building the above script to an apk? if you have, can you tell me was it success, so that i know i'm doing something wrong!

Comment 134 by Raymond Camden posted on 11/29/2013 at 12:33 AM

Since the point of this was about *non* PhoneGap apps, no, I didn't. :) If I were using PhoneGap, I'd probably just use the Camera API as is.

Comment 135 by Kevin Yilmaz posted on 12/3/2013 at 6:23 AM

Hi Raymond,
Sorry, where and how can I get the color-thief.js file?

(By the way: "you must enter a valid url" that's what I got when I entered www.husnu.me in 'Website' input field.)

Comment 136 by Raymond Camden posted on 12/3/2013 at 6:54 PM

Color Thief: http://lokeshdhakar.com/pro.... I linked to it in the blog post.

As for the URL, it was being anal and wanted http:// in front.

Comment 137 by Kevin Yilmaz posted on 12/3/2013 at 10:32 PM

Thank you Raymond.

Comment 138 by Ruben posted on 12/4/2013 at 5:20 PM

Hi Raymon, do you know, how can I send a image picked from ipad roll, this way, to my server? I need create a database with they.

Regards.

Comment 139 by Raymond Camden posted on 12/4/2013 at 6:04 PM

Just use the same HTML you would for a normal file upload. The right enctype for your form tag should be all that is required.

Comment 140 by Ruben posted on 12/4/2013 at 7:15 PM

Great Raymon, thx for help me.

Comment 141 by Oscar posted on 2/21/2014 at 7:35 AM

Hi Raymond, I came across this page and I am amazed at how you were able to access the camera on the device through an HTML page. Have you thought of or coded anything for reading a barcode throught the camera and then taking the barcode data and displaying the contents in a field?

very impressed

Oscar

Comment 142 by Raymond Camden posted on 2/21/2014 at 6:06 PM

No, I have not, but in theory, it is possible: http://badassjs.com/post/65...

Comment 143 by Eric Fickes posted on 3/5/2014 at 12:18 PM

I love you man

Comment 144 by AJAY AVHAD posted on 3/14/2014 at 9:26 PM

How record video in phone-gap in background?

Comment 145 by Raymond Camden posted on 3/14/2014 at 9:48 PM

See the docs on the Capture API.

Comment 146 by AJAY AVHAD posted on 3/15/2014 at 9:57 AM

I have done video recoding but i want in backgroud ?

Comment 147 by Raymond Camden posted on 3/15/2014 at 5:02 PM

You want to capture video in the background? Not sure how that would work - sorry.

Comment 148 by Meek posted on 3/19/2014 at 7:45 PM

Hey Raymond,

I need to use the take photos' API , your illustration is very clear and helpful to me.

It's surprise me that HTML 5 could use take photo function without using phonegap!

My APP will be successful by your help!

Very Thanks!

Comment 149 by Anand posted on 3/20/2014 at 10:19 AM

Nice Article. I need (Take Photo) option alone. No need of (choose existing) option..How I can do this? Thanks

Comment 150 by Raymond Camden posted on 3/20/2014 at 3:11 PM

I don't believe you can change that.

Comment 151 by Ofir posted on 3/24/2014 at 3:02 AM

Hi, I was wondering if there is a QR code reader implementation of this for mobile devices (iOS specifically, but all mobile browsers preferably).

In case there isn't, then I presume the only way to implement one is take a picture and upload it like in the demo, then analyze the picture.

q.
1. does the picture get uploaded to the server, or is it stored on the client?
2. could it be analyzed by the client, or would it have to be uploaded and analyzed by the server?

Comment 152 by Raymond Camden posted on 3/24/2014 at 5:26 AM

I'm not aware of any client-side only JS QR decoder, but it may exist.

1) "does the picture get uploaded to the server, or is it stored on the client"
It isn't sent to the server until you submit the form.

2) See my first thing - I'm not aware of a QR reader built in JS, but it may exist.

Oh wait - this may be it: https://github.com/LazarSof...

Comment 153 by Anand posted on 4/3/2014 at 2:19 PM

Hi..
Is it possible to find that the user use 'choose existing' option rather than 'take picture' ?

Comment 154 by Raymond Camden posted on 4/3/2014 at 2:29 PM

As far as I know, no. Maybe you could try to read the file's creation date and see if it is "too young" to be an existing picture, but that seems risky.

Comment 155 by Anand posted on 4/3/2014 at 3:14 PM

If the date is young that will be not be the problem. Do you know how to read the file's creation date? Because I have tried using JavaScript in many way. Please share if any.

Thanks

Comment 156 by Raymond Camden posted on 4/3/2014 at 5:51 PM

Oh sorry - I was thinking about this in terms of PhoneGap/Cordova where you have access to the file system. So - I think the answer is just no.

Comment 157 by Zim posted on 4/25/2014 at 4:13 PM

Hi Raymond, you say you can store in WebSQL once you have converted to base64 format (in one of your earlier comments). I'm having a lot of trouble with retrieving and displaying the image after storing. Any pointers?

Comment 158 by Raymond Camden posted on 4/25/2014 at 6:56 PM

Well I said "if" you can. ;) You say you have issues retrieving/displaying *after* storing. So lets focus on retrieving. You knew WebSQL enough to do an insert, but not how to get the value back?

Comment 159 by Zim posted on 4/25/2014 at 7:05 PM

I know how to retrieve simple text or number values using the SELECT statement, but in this case I can't just do image.val() to retrieve the image, because that wouldn't return anything most likely. Usually I would do something like $('#something').val(row['column1']); to put the value from the database into #something. Basically I can't get my head round the format

Comment 160 by Raymond Camden posted on 4/25/2014 at 7:06 PM

Wait - you said you stored it - but now you are saying you didn't store it? So you don't have a way to convert the image to base64 then, right? Try this - first result via Google search:

http://stackoverflow.com/qu...

Comment 161 by Zim posted on 4/25/2014 at 7:23 PM

I should have mentioned before I'm using PhoneGap API to take a picture using the device camera. I'm then using this code:

function onSuccess(imageData) {
var image = document.getElementById('camera');
image.src = "data:image/jpeg;base64," + imageData;
displayImage(image.src);
}

Does that convert it to base64? Or am I misunderstanding the documentation. I am then just inserting the image variable into the database conventionally

Comment 162 by Raymond Camden posted on 4/25/2014 at 7:29 PM

@Zim: You do know this entire post is about doing it *without* PhoneGap, right? The fact that you were using it is kind of an important detail, and we are now somewhat off topic.

That being said: You have the base64 string already. It is "imageData". You can store that easily enough in WebSQL. Please see the documentation on how to work with it.

Since you are using PG though, you can also write to the file system and store binary data. You would need to change from base64 image data to file names though. See the PhoneGap Camera API docs.

Comment 163 by Zim posted on 4/26/2014 at 2:01 PM

I'm not sure about the capacity of WebSQL on an iOS PhoneGap app. In some places I'm reading it's 5MB, in others I'm reading it's 50MB. Would it be wise to store base64 images in WebSQL given the storage limitations, or would it be better to write to the file system?

Comment 164 by Raymond Camden posted on 4/26/2014 at 5:36 PM

@Zim: If you are using PhoneGap, then just use the file system. If you have further questions about this, please use the contact form (or StackOverflow, I try to check the Cordova tag there daily) as it is *not* on topic for this blog post.

Comment 165 by Pedro posted on 4/29/2014 at 12:48 AM

Hi Raymond,

Thank you for the post!! Very Nice!

I would like to know if it's possible to take a picture and auto save into the picture library.

Thanks

Comment 166 by Shaifee Setia posted on 4/29/2014 at 7:31 PM

Hi Raymond,

Its really an awesome post.Thank you for your post!!

Thanks,
Shaifee

Comment 167 by Raymond Camden posted on 4/29/2014 at 7:56 PM

I think (stress think) pictures are always saved anyway, right? Did you check?

Comment 168 by Shaifee Setia posted on 4/30/2014 at 6:17 PM

Hi Raymond,

I was also looking for pictures if saved anywhere but I didn't find pictures anywhere on device iPhone/iPad.

Thanks,
Shaifee

Comment 169 by Raymond Camden posted on 4/30/2014 at 11:16 PM

Interesting. So iOS may be assuming then that the pic you take is ONLY for uploads. On Android I think they always save the picture, which makes more sense. Not sure what you can do about that to be honest.

Comment 170 by Elad posted on 5/18/2014 at 12:07 AM

Really need your help here -
How can I prevent the photo from being saved to the gallery after being taken ? I'm only referring to Android.
I want to upload the photo to my server with Ajax (which I do know how to do) but it's important that it will not stay on the device (in iOS it's not being saved, as you've already mentioned).
Please help as this is a very critical issue for me..
Thanks a lot !

Comment 171 by Raymond Camden posted on 5/19/2014 at 3:45 AM

As far as I know, you have *zero* control over this method. If you used Cordova, you could handle it of course.

Comment 172 by johntorri posted on 6/3/2014 at 5:01 PM

how can i upload the image which i was taken?

Comment 173 by Raymond Camden posted on 6/3/2014 at 5:56 PM

It is a form already, so when you submit, it will send it.

Comment 174 by johntorri posted on 6/4/2014 at 10:25 AM

Ok. thanks. Great post. but i´ve one more question: how can i get the path of the picture?

Comment 175 by Raymond Camden posted on 6/4/2014 at 6:44 PM

The file field can be read via JavaScript. But that's all you can. A web page can't write to the file system or copy files around.

Comment 176 by Dan posted on 6/6/2014 at 4:03 AM

Thanks for your great articles Raymond. I have learned a lot of great info from your website.

Comment 177 by johntorri posted on 6/12/2014 at 11:13 AM

Hello again, i´ve finished my little script, the server recieves the file correctly, but only works for me on firefox browser app. but i need implement this on dolphin browser. do you have any idea?

Comment 178 by Raymond Camden posted on 6/12/2014 at 3:58 PM

Dolphin may simply not support this.

Comment 179 by Bhavik posted on 6/18/2014 at 7:59 PM

Hi Raymond, nice article, I would like to try it if you don't mind.

Just can I know where can I find the quantize.js and color-thief.js file you have imported?

Thanks.

Comment 180 by Raymond Camden posted on 6/18/2014 at 8:04 PM
Comment 181 by Quint posted on 7/8/2014 at 10:47 AM

Very well done. Thanks for sharing!

Comment 182 by Gyowanny posted on 7/8/2014 at 10:12 PM

Man, no kidding. Awesome!

Thanks for sharing! It helped me a lot!

Cheers,

Gyo

Comment 183 by dhayalan posted on 7/30/2014 at 11:58 AM

Hi,

I'm Developing a responsive web application using php, for which i need a device camera to be used. provide me some extra info for my project ..

Thanks in advance...

Comment 184 by Raymond Camden posted on 7/30/2014 at 3:54 PM

You need to ask a specific question. Your comment is too broad.

Comment 185 by Ericson posted on 8/4/2014 at 9:49 AM

Does it have a function for adding frames or overlays?

Comment 186 by Raymond Camden posted on 8/4/2014 at 7:29 PM

Not that I know of.

Comment 187 by Greg posted on 8/4/2014 at 10:15 PM

This is exactly what I'm looking for! thanks for sharing. I have one question.
How can I read binary data from event.target.files[0]? basically I want to populate a text field with the image binary as a text

Thank you!

Comment 188 by Raymond Camden posted on 8/4/2014 at 10:23 PM

You would need to work with JS's BLOB support. I've done it a few times, but I'm not very familiar with it. I'd hit MDN as they have good docs on it.

Comment 189 by recky posted on 8/7/2014 at 9:36 AM

thanks Mr. Raymond, nice script. can you help me how to save that picture into database mysql ?

Comment 190 by Raymond Camden posted on 8/7/2014 at 5:45 PM

This posts just like any regular form post with a file attachment. What I would do server side is:

a) send the upload to a temporary dir NOT under web root
b) double check to ensure it is a valid image
c) move it to a location that makes sense, maybe even s3, and note the filename
d) update whatever mysql table makes sense with the filename

You *can* store binary data in MySQL, but I'd just store the path.

Comment 191 by Poonam posted on 8/8/2014 at 1:42 PM

Hello Raymond.
I tried the above mentioned code without using the quantize.js and color-theif js as i don't require the color palate option.

When i tested the page everything seems to works fine on the mobile browser except that the image is getting rotated by 90 degree when clicked through camera. But when i try to use the same code in the mobile webview (placed inside an andriod/IOS app to view the page) it didn't work. Even in case of android, clicking on the button does nothing.

Can you please suggest what can be the issue and how can i resolve that.

Thank You.

Comment 192 by poonam posted on 8/8/2014 at 1:43 PM

*It is really very urgent if you can help me on this.

Comment 193 by Raymond Camden posted on 8/8/2014 at 7:59 PM

When you debugged, what did you see? Use Chrome Remote Debugging and dig into the problem.

Comment 194 by Greg posted on 8/21/2014 at 11:55 PM

Raymond,

I'm getting the error "Can't find variable: URL" in Safari. It works well in Chrome.
The line is
$("#yourimage").attr("src",URL.createObjectURL(event.target.files[0]));

Any ideas?
TIA

Comment 195 by Raymond Camden posted on 8/22/2014 at 12:01 AM

Try using webkitURL. It seems to be prefixed still.

Comment 196 by Avinash Sahu posted on 8/22/2014 at 5:22 PM

Very gud description, i have captured image from my android phone but i want to save image in my database or folder, how to achive it??

Comment 197 by Raymond Camden posted on 8/22/2014 at 5:57 PM

If you mean on a server, you would need to post the form to something that can handle it.

Comment 198 by Sajid posted on 9/9/2014 at 3:35 PM

This article is very useful, kindly share how we can upload the captured image into database.

Comment 199 by Raymond Camden posted on 9/9/2014 at 3:57 PM

You would use an app server. I'm not going to answer that in a comment as it is beyond the scope of this article. But every major app server product (PHP, ColdFusion, Node, etc) make file uploads easy.

Comment 200 by makc3d posted on 9/21/2014 at 6:10 AM

Did you try this on any actual device, not emulator? It fails to load for me on either ios6 iphone or ios8 ipad. Here is my test code: http://jsbin.com/tazitaliti... It does work on desktop, so there must be no stupid typos.

Comment 201 by makc3d posted on 9/21/2014 at 6:23 AM

Just noticed

> The only tricky part I ran into was that in iOS the URL object is still prefixed.

And modified my test to include that too: http://jsbin.com/tazitaliti...

But no, it did not help.

Comment 202 by makc3d posted on 9/21/2014 at 7:22 AM

Update: /2/ test does work on ios6. So it must be some ios8 breaking change.

Comment 203 by JAMBA posted on 9/21/2014 at 1:29 PM

I confirm that there seems to have been a breaking change in Safari Mobile on iOS8. We were using the <input type="file" capture="camera" accept="image/*"> mechanism for an internal web app fine, but when everyone updated to iOS8 from iOS7, it broke.

N.B. It still works fine with other installed mobile browsers, like Chrome, on iOS8.

Comment 204 by Raymond Camden posted on 9/21/2014 at 4:42 PM

Guys, thanks for digging into this. Will share w/ Max Firtman here (http://www.mobilexweb.com/b... later today.

Comment 205 by Michael Kovacs posted on 10/1/2014 at 12:05 AM

Looks like it's fixed in 8.0.2

http://blog.uploadcare.com/...

Comment 206 by Will posted on 10/5/2014 at 12:03 AM

Hi i am from Brazil and it is very cool, but a have one question Can i send the picture by the email smtp server?

Comment 207 by Raymond Camden posted on 10/5/2014 at 12:09 AM

No, not from a web page. You could with a proper PhoneGap/Cordova app as you can use a plugin to do email with attachments.

Comment 208 by androidexample posted on 10/9/2014 at 9:58 PM

Hi
I have found one good example here
<a href="http://androidexample.com/O..." >Open File Chooser With Camera Option In Webview File Option</a>

Comment 209 by smovie9 posted on 10/13/2014 at 8:51 PM

Is it possible to take a gif with jquery mobile and how?

Comment 210 by Raymond Camden posted on 10/13/2014 at 8:54 PM

jQuery Mobile is a framework that makes it easier to build mobile-friendly web apps. It doesn't have anything to do with "taking a gif" - which I assume you mean taking a picture and making it a gif.

Comment 211 by Ngug posted on 11/10/2014 at 1:39 PM

There is a question that no one has answered please. How can I use/replace this line $("#yourimage").attr("src",URL.createObjectURL(event.target.files[0])) in an Intel XDK app so that the app can display the image in an image tag. Guys, if you learn something on this blog, please post it properly so that somebody can also benefit. Let's make Raymond's work easier, he's doing a great thing. Thanks all.

Comment 212 by Christian Will posted on 11/13/2014 at 1:26 PM

Hi, I used a somehow similar code to yours, and was wondering if you could help me out. I'm trying to store the image captured on a folder and than save the path of the saved picture to a database.

Comment 213 by Raymond Camden posted on 11/13/2014 at 7:56 PM

You can't store it in a folder unless you use a hybrid solution like PhoneGap.

Comment 214 by Maurizio posted on 11/17/2014 at 10:08 AM

If can't store in a folder ... may be it's possible to save the image in blob SQL field or in base64 encoding?
Awesome script, thanks

Comment 215 by Raymond Camden posted on 11/17/2014 at 4:18 PM

Converting it to Base64 would let you save it in either LocalStorage or IndexedDB. I'd use IDB.

Comment 216 by Maurizio posted on 11/17/2014 at 9:14 PM

Thanks all, awesome post!

Comment 217 by Duke Snyder posted on 1/21/2015 at 2:42 AM

great post ray. exactly what I needed and was implemented in less than 10 minutes using cffile. Android 4.4.2

Comment 218 by Kumar Kashyap posted on 2/5/2015 at 3:45 PM

Hi Raymond, Thank you for sharing this article. Helped me a lot! I am trying to upload the image to my server using PHP/Javascript. Can you help me with that? It says image has been uploaded successfully but it doesnt actually get to the folder.Here is my code:

echo $target_dir = "uploads/";

echo $target_file = $target_dir . basename($_FILES["takeSinglePicture"]["name"]);

$uploadOk = 1;

echo $imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);

echo $image_name = $_FILES['takeSinglePicture']['name'];

//echo $imageFileType = $_FILES['image']['type'];

echo $image_size = $_FILES['takeSinglePicture']['size'];

echo $image_tmp_name = $_FILES['takeSinglePicture']['tmp_name'];

if ($uploadOk == 0) {

echo "Sorry, your file was not uploaded.";

echo "
";

// if everything is ok, try to upload file

} else {

if($image_name == ''){

echo "<script>alert('Please Select an image')</script>";

exit();

}

else{

move_uploaded_file($image_tmp_name,"uploads/$image_name");

echo "Image Uploaded Successfully!";

echo "<img src="uploads/$image_name">";

}

}

Comment 219 (In reply to #218) by Raymond Camden posted on 2/5/2015 at 3:46 PM

I don't use PHP, so I can't help with this.

Comment 220 by Sasha posted on 3/4/2015 at 12:56 AM

I guess it won't work with KitKat

Comment 221 by Amit posted on 4/16/2015 at 8:51 AM

is someone send me code for taking the screen shot of the mobile please

Comment 222 by rendhon posted on 8/17/2015 at 6:14 AM

got it worked but it's having a light error i think it's not serious issue when i toke a pic this error message occur failed to open selected file.

Comment 223 by Furkan Şahin posted on 9/28/2015 at 3:14 AM

thanks !!