HTML5 Camera Access Through Browser in iOS
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.
<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', () => { context.drawImage(player, 0, 0, canvas.width, canvas.height); }); 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.