155

We are creating an HTML5 website for mobile and need to get camera access through the web browser without being a native app. We are having trouble making this work in iOS. Is anyone aware of a solution for this?

Paolo Forgia
  • 6,572
  • 8
  • 46
  • 58
Julia
  • 1,551
  • 2
  • 10
  • 3

6 Answers6

129

You could try this:

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

but it has to be iOS 6+ to work. That will give you a nice dialogue for you to choose either to take a picture or to upload one from your album i.e.

Screenhot

An example can be found here: Capturing camera/picture data without PhoneGap

radu florescu
  • 4,315
  • 10
  • 60
  • 92
Xeroxoid
  • 2,146
  • 1
  • 17
  • 22
  • 6
    This is AWESOME on Android too! – Matt Oct 02 '13 at 03:30
  • 1
    Nice demo for uploading to a server. Anyone know how to modify this to save the picture to a local album on the device? – K.Niemczyk Oct 04 '13 at 17:16
  • 2
    The only problem is that, at least on iphone (ios 7.0.4) at least at the moment it creates a temporary image named always `'image.jpg'`. So if you upload a few images in the same form, they overwrite each other due to same name unless you do something to rename them, be careful! – aleation Jan 30 '14 at 16:34
  • @K.Niemczyk: did you ever figure that out? if so i'd be interested in the solution. I found this: http://dev.w3.org/2009/dap/camera/ (see examples 6-7 for local storage) – lamarant Feb 24 '14 at 18:27
  • @Leon Not directly. We ended up switching to using Phonegap for our needs for several other reasons. – K.Niemczyk Feb 24 '14 at 22:34
  • I have a problem with this solution on iPad. Could you check this [post](http://stackoverflow.com/q/21885144/902025) and tell me where it can come from? Thanks – Maxbester Mar 24 '14 at 07:44
  • Apologies for down-vote. Miss-clicked and then couldn't correct after an hour+ later. – Ross Rogers Dec 04 '14 at 16:41
  • This is great, however does anyone know why if u choose existing pic its around 150kb in size, however if u take photo they always seem to be like 1.50mb. Is there any workaround for this? – Mattias Jul 05 '15 at 13:38
  • 1
    Brilliant. [Here's a fiddle](http://jsfiddle.net/simoneast/6y2rdk1p/) for anyone wanting to give this code a test run on their device. – Simon East Aug 11 '15 at 02:14
  • Just be aware that on iOS it gives you the *choice* of taking a photo or choosing an existing photo. On Android is immediately launches the camera without asking. – Simon East Aug 11 '15 at 02:21
  • @SimonEast: There are [five fiddles in this question about the `input` element](http://stackoverflow.com/questions/21523544/html-file-input-control-with-capture-and-accept-attributes-works-wrong) with `accept="image/*"`. – Dan Dascalescu Jul 27 '16 at 08:38
34

As of 2015, it now just works.

<input type="file">

This will ask user for the upload of any file. On iOS 8.x this can be a camera video, camera photo, or a photo/video from Photo Library.

iOS/iPhone photo/video/file upload

<input type="file" accept="image/*">

This is as above, but limits the uploads to photos only from camera or library, no videos.

octavn
  • 3,154
  • 32
  • 49
Simon East
  • 55,742
  • 17
  • 139
  • 133
  • 1
    Is there any way to restrict users from choosing a file from the photo library? I want to accept only a newly taken image. – Daryl May 09 '16 at 16:59
  • @Daryl not on iOS. Android supports the `capture` attribute which does just that. See [Correct Syntax for HTML Media Capture](https://addpipe.com/blog/correct-syntax-html-media-capture/) – octavn Nov 09 '16 at 16:36
  • shall I close this Take Photo or Video and Photo Library popup after some time in user not click on it. – Pritish Feb 07 '17 at 08:21
  • looks like the video functions is not there anymore? – MartianMartian Feb 27 '17 at 04:34
26

In iOS6, Apple supports this via the <input type="file"> tag. I couldn't find a useful link in Apple's developer documentation, but there's an example here.

It looks like overlays and more advanced functionality is not yet available, but this should work for a lot of use cases.

EDIT: The w3c has a spec that iOS6 Safari seems to implement a subset of. The capture attribute is notably missing.

octavn
  • 3,154
  • 32
  • 49
user295691
  • 7,108
  • 1
  • 26
  • 35
10

I think this one is working. Recording a video or audio;

<input type="file" accept="video/*;capture=camcorder">
<input type="file" accept="audio/*;capture=microphone">

or (new method)

<device type="media" onchange="update(this.data)"></device>
<video autoplay></video>
<script>
  function update(stream) {
    document.querySelector('video').src = stream.url;
  }
</script>

If it is not, probably will work on ios6, more detail can be found at get user media

siniradam
  • 2,727
  • 26
  • 37
5

Update 11/2020: The Google Developer link is (currently) dead. The original article with a LOT more explanations can still be found at web.archive.org.


This question is already a few years old but in that time some additional possibilities have evolved, like accessing the camera directly, displaying a preview and capturing snapshots (e.g. for QR code scanning).

This Google Developers article provides an in-depth explaination of all (?) the ways how to get image/camera data into a web application, from "work everywhere" (even in desktop browsers) to "work only on modern, up-to-date mobile devices with camera". Along with many useful tips.

Explained methods:

  • Ask for a URL: Easiest but least satisfying.

  • File input (covered by most other posts here): The data can then be attached to a or manipulated with JavaScript by listening for an onchange event on the input element and then reading the files property of the event target.

<input type="file" accept="image/*" id="file-input">
<script>
  const fileInput = document.getElementById('file-input');

  fileInput.addEventListener('change', (e) => doSomethingWithFiles(e.target.files));
</script>

The files property is a FileList object.

  • Drag and drop (useful for desktop browsers):
<div id="target">You can drag an image file here</div>
<script>
  const target = document.getElementById('target');

  target.addEventListener('drop', (e) => {
    e.stopPropagation();
    e.preventDefault();

    doSomethingWithFiles(e.dataTransfer.files);
  });

  target.addEventListener('dragover', (e) => {
    e.stopPropagation();
    e.preventDefault();

    e.dataTransfer.dropEffect = 'copy';
  });
</script>

You can get a FileList object from the dataTransfer.files property of the drop event.

  • Paste from clipboard
<textarea id="target">Paste an image here</textarea>
<script>
  const target = document.getElementById('target');

  target.addEventListener('paste', (e) => {
    e.preventDefault();
    doSomethingWithFiles(e.clipboardData.files);
  });
</script>

e.clipboardData.files is a FileList object again.

  • Access the camera interactively (necessary if application needs to give instant feedback on what it "sees", like QR codes): Detect camera support with const supported = 'mediaDevices' in navigator; and prompt the user for consent. Then show a realtime preview and copy snapshots to a canvas.
<video id="player" controls autoplay></video>
<button id="capture">Capture</button>
<canvas id="canvas" width=320 height=240></canvas>
<script>
  const player = document.getElementById('player');
  const canvas = document.getElementById('canvas');
  const context = canvas.getContext('2d');
  const captureButton = document.getElementById('capture');

  const constraints = {
    video: true,
  };

  captureButton.addEventListener('click', () => {
    // Draw the video frame to the canvas.
    context.drawImage(player, 0, 0, canvas.width, canvas.height);
  });

  // Attach the video stream to the video element and autoplay.
  navigator.mediaDevices.getUserMedia(constraints)
    .then((stream) => {
      player.srcObject = stream;
    });
</script>

Don't forget to stop the video stream with

player.srcObject.getVideoTracks().forEach(track => track.stop());

Update 11/2020: The Google Developer link is (currently) dead. The original article with a LOT more explanations can still be found at web.archive.org.

Christoph
  • 2,211
  • 1
  • 16
  • 28
  • This is why link answers should also include the specifics in the answer, links break. – mikeb Nov 08 '20 at 12:33
  • I dug up the original article in a web archive and added examples. Would appreciate the undoing of the downvotes. – Christoph Nov 09 '20 at 14:11
4

The Picup app is a way to take pictures from an HTML5 page and upload them to your server. It requires some extra programming on the server, but apart from PhoneGap, I have not found another way.

Ry-
  • 218,210
  • 55
  • 464
  • 476
rakensi
  • 1,437
  • 1
  • 15
  • 20