Updated Branches: refs/heads/master 06f014246 -> 9f8ca3e9e
[CB-4488] - added some manual capture tests Project: http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/repo Commit: http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/commit/bf272273 Tree: http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/tree/bf272273 Diff: http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/diff/bf272273 Branch: refs/heads/master Commit: bf2722737eca75fd757d831e8b3e3479eed0353a Parents: 06f0142 Author: timkim <[email protected]> Authored: Tue Sep 10 14:45:27 2013 -0700 Committer: timkim <[email protected]> Committed: Tue Sep 10 14:45:27 2013 -0700 ---------------------------------------------------------------------- capture/index.html | 407 ++++++++++++++++++++++++++++++++++++++++++++++++ index.html | 1 + 2 files changed, 408 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/bf272273/capture/index.html ---------------------------------------------------------------------- diff --git a/capture/index.html b/capture/index.html new file mode 100644 index 0000000..309de1a --- /dev/null +++ b/capture/index.html @@ -0,0 +1,407 @@ +<!DOCTYPE html> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +--> + + +<html> + <head> + <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" /> + <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 --> + <title>Cordova Mobile Spec</title> + <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8"> + <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script> + + +<script type="text/javascript" charset="utf-8"> + + var deviceReady = false; + var platformId = cordova.require('cordova/platform').id; + var pictureUrl = null; + var fileObj = null; + var fileEntry = null; + var pageStartTime = +new Date(); + var capture = navigator.device.capture; + + + //------------------------------------------------------------------------- + // Camera + //------------------------------------------------------------------------- + + function log(value) { + console.log(value); + document.getElementById('camera_status').textContent += (new Date() - pageStartTime) / 1000 + ': ' + value + '\n'; + } + + function captureAudioWin(mediaFiles){ + /* + var i, path, len; + for (i = 0, len = mediaFiles.length; i < len; i += 1) { + path = mediaFiles[i].fullPath; + // do something interesting with the file + } + */ + var m = new Media(mediaFiles[i].fullPath); + m.play(); + } + + function captureAudioFail(e){ + log('Error getting audio: ' + e.code); + } + + function getAudio(){ + clearStatus(); + var options = { limit: 1, duration: 10}; + capture.captureAudio(captureAudioWin, captureAudioFail, options); + + } + + function clearStatus() { + document.getElementById('camera_status').innerHTML = ''; + document.getElementById('camera_image').src = 'about:blank'; + var canvas = document.getElementById('canvas'); + canvas.width = canvas.height = 1; + pictureUrl = null; + fileObj = null; + fileEntry = null; + } + + function setPicture(url, callback) { + try { + window.atob(url); + // if we got here it is a base64 string (DATA_URL) + url = "data:image/jpeg;base64," + url; + } catch (e) { + // not DATA_URL + log('URL: ' + url.slice(0, 100)); + } + + pictureUrl = url; + var img = document.getElementById('camera_image'); + var startTime = new Date(); + img.src = url; + img.onloadend = function() { + log('Image tag load time: ' + (new Date() - startTime)); + callback && callback(); + }; + } + + function onGetPictureError(e) { + log('Error getting picture: ' + e.code); + } + + function getPictureWin(data) { + setPicture(data); + // TODO: Fix resolveLocalFileSystemURI to work with native-uri. + if (pictureUrl.indexOf('file:') == 0) { + resolveLocalFileSystemURI(data, function(e) { + fileEntry = e; + logCallback('resolveLocalFileSystemURI()', true)(e); + }, logCallback('resolveLocalFileSystemURI()', false)); + } else if (pictureUrl.indexOf('data:image/jpeg;base64' == 0)) { + // do nothing + } else { + var path = pictureUrl.replace(/^file:\/\/(localhost)?/, '').replace(/%20/g, ' '); + fileEntry = new FileEntry('image_name.png', path); + } + } + + function getPicture() { + clearStatus(); + var options = extractOptions(); + log('Getting picture with options: ' + JSON.stringify(options)); + var popoverHandle = navigator.camera.getPicture(getPictureWin, onGetPictureError, options); + + // Reposition the popover if the orientation changes. + window.onorientationchange = function() { + var newPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, 0); + popoverHandle.setPosition(newPopoverOptions); + } + } + + function uploadImage() { + var ft = new FileTransfer(), + uploadcomplete=0, + progress = 0, + options = new FileUploadOptions(); + options.fileKey="photo"; + options.fileName='test.jpg'; + options.mimeType="image/jpeg"; + ft.onprogress = function(progressEvent) { + log('progress: ' + progressEvent.loaded + ' of ' + progressEvent.total); + }; + var server = "http://cordova-filetransfer.jitsu.com"; + + ft.upload(pictureUrl, server + '/upload', win, fail, options); + function win(information_back){ + log('upload complete'); + } + function fail(message) { + log('upload failed: ' + JSON.stringify(message)); + } + } + + function logCallback(apiName, success) { + return function() { + log('Call to ' + apiName + (success ? ' success: ' : ' failed: ') + JSON.stringify([].slice.call(arguments))); + }; + } + + /** + * Select image from library using a NATIVE_URI destination type + * This calls FileEntry.getMetadata, FileEntry.setMetadata, FileEntry.getParent, FileEntry.file, and FileReader.readAsDataURL. + */ + function readFile() { + function onFileReadAsDataURL(evt) { + var img = document.getElementById('camera_image'); + img.style.visibility = "visible"; + img.style.display = "block"; + img.src = evt.target.result; + log("FileReader.readAsDataURL success"); + }; + + function onFileReceived(file) { + log('Got file: ' + JSON.stringify(file)); + fileObj = file; + + var reader = new FileReader(); + reader.onload = function() { + log('FileReader.readAsDataURL() - length = ' + reader.result.length); + }; + reader.onerror = logCallback('FileReader.readAsDataURL', false); + reader.readAsDataURL(file); + }; + // Test out onFileReceived when the file object was set via a native <input> elements. + if (fileObj) { + onFileReceived(fileObj); + } else { + fileEntry.file(onFileReceived, logCallback('FileEntry.file', false)); + } + } + function getFileInfo() { + // Test FileEntry API here. + fileEntry.getMetadata(logCallback('FileEntry.getMetadata', true), logCallback('FileEntry.getMetadata', false)); + fileEntry.setMetadata(logCallback('FileEntry.setMetadata', true), logCallback('FileEntry.setMetadata', false), { "com.apple.MobileBackup": 1 }); + fileEntry.getParent(logCallback('FileEntry.getParent', true), logCallback('FileEntry.getParent', false)); + fileEntry.getParent(logCallback('FileEntry.getParent', true), logCallback('FileEntry.getParent', false)); + }; + + /** + * Copy image from library using a NATIVE_URI destination type + * This calls FileEntry.copyTo and FileEntry.moveTo. + */ + function copyImage() { + var onFileSystemReceived = function(fileSystem) { + var destDirEntry = fileSystem.root; + + // Test FileEntry API here. + fileEntry.copyTo(destDirEntry, 'copied_file.png', logCallback('FileEntry.copyTo', true), logCallback('FileEntry.copyTo', false)); + fileEntry.moveTo(destDirEntry, 'moved_file.png', logCallback('FileEntry.moveTo', true), logCallback('FileEntry.moveTo', false)); + }; + + window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, onFileSystemReceived, null); + }; + + /** + * Write image to library using a NATIVE_URI destination type + * This calls FileEntry.createWriter, FileWriter.write, and FileWriter.truncate. + */ + function writeImage() { + var onFileWriterReceived = function(fileWriter) { + fileWriter.onwrite = logCallback('FileWriter.write', true); + fileWriter.onerror = logCallback('FileWriter.write', false); + fileWriter.write("some text!"); + }; + + var onFileTruncateWriterReceived = function(fileWriter) { + fileWriter.onwrite = logCallback('FileWriter.truncate', true); + fileWriter.onerror = logCallback('FileWriter.truncate', false); + fileWriter.truncate(10); + }; + + fileEntry.createWriter(onFileWriterReceived, logCallback('FileEntry.createWriter', false)); + fileEntry.createWriter(onFileTruncateWriterReceived, null); + }; + + function displayImageUsingCanvas() { + var canvas = document.getElementById('canvas'); + var img = document.getElementById('camera_image'); + var w = img.width; + var h = img.height; + h = 100 / w * h; + w = 100; + canvas.width = w; + canvas.height= h; + var context = canvas.getContext('2d'); + context.drawImage(img, 0, 0, w, h); + }; + + /** + * Remove image from library using a NATIVE_URI destination type + * This calls FileEntry.remove. + */ + function removeImage() { + fileEntry.remove(logCallback('FileEntry.remove', true), logCallback('FileEntry.remove', false)); + }; + + function testInputTag(inputEl) { + clearStatus(); + // iOS 6 likes to dead-lock in the onchange context if you + // do any alerts or try to remote-debug. + window.setTimeout(function() { + testNativeFile2(inputEl); + }, 0); + }; + + function testNativeFile2(inputEl) { + if (!inputEl.value) { + alert('No file selected.'); + return; + } + fileObj = inputEl.files[0]; + if (!fileObj) { + alert('Got value but no file.'); + return; + } + var URLApi = window.URL || window.webkitURL; + if (URLApi) { + var blobURL = URLApi.createObjectURL(fileObj); + if (blobURL) { + setPicture(blobURL, function() { + URLApi.revokeObjectURL(blobURL); + }); + } else { + log('URL.createObjectURL returned null'); + } + } else { + log('URL.createObjectURL() not supported.'); + } + } + + function extractOptions() { + var els = document.querySelectorAll('#image-options select'); + var ret = {}; + for (var i = 0, el; el = els[i]; ++i) { + var value = el.value; + if (value === '') continue; + if (el.isBool) { + ret[el.keyName] = !!+value; + } else { + ret[el.keyName] = +value; + } + } + return ret; + } + + function createOptionsEl(name, values, selectionDefault) { + var container = document.createElement('div'); + container.style.display = 'inline-block'; + container.appendChild(document.createTextNode(name + ': ')); + var select = document.createElement('select'); + select.keyName = name; + container.appendChild(select); + + // if we didn't get a default value, insert the blank <default> entry + if (selectionDefault == undefined) { + var opt = document.createElement('option'); + opt.value = ''; + opt.text = '<default>'; + select.appendChild(opt); + } + + select.isBool = typeof values == 'boolean'; + if (select.isBool) { + values = {'true': 1, 'false': 0}; + } + + for (var k in values) { + var opt = document.createElement('option'); + opt.value = values[k]; + opt.textContent = k; + if (selectionDefault) { + if (selectionDefault[0] == k) { + opt.selected = true; + } + } + select.appendChild(opt); + } + var optionsDiv = document.getElementById('image-options'); + optionsDiv.appendChild(container); + } + + /** + * Function called when page has finished loading. + */ + function init() { + document.addEventListener("deviceready", function() { + deviceReady = true; + console.log("Device="+device.platform+" "+device.version); + createOptionsEl('sourceType', Camera.PictureSourceType, camPictureSourceTypeDefault); + createOptionsEl('destinationType', Camera.DestinationType, camDestinationTypeDefault); + createOptionsEl('encodingType', Camera.EncodingType, camEncodingTypeDefault); + createOptionsEl('mediaType', Camera.MediaType, camMediaTypeDefault); + createOptionsEl('quality', {'0': 0, '50': 50, '80': 80, '100': 100}, camQualityDefault); + createOptionsEl('targetWidth', {'50': 50, '200': 200, '800': 800, '2048': 2048}); + createOptionsEl('targetHeight', {'50': 50, '200': 200, '800': 800, '2048': 2048}); + createOptionsEl('allowEdit', true, camAllowEditDefault); + createOptionsEl('correctOrientation', true, camCorrectOrientationDefault); + createOptionsEl('saveToPhotoAlbum', true, camSaveToPhotoAlbumDefault); + createOptionsEl('cameraDirection', Camera.Direction); + + }, false); + window.setTimeout(function() { + if (!deviceReady) { + alert("Error: Apache Cordova did not initialize. Demo will not run correctly."); + } + },1000); + }; + +</script> + + </head> + <body onload="init();" id="stage" class="theme"> + + <h1>Camera</h1> + <div id="info" style="white-space: pre-wrap"> + <b>Status:</b> <div id="camera_status"></div> + img: <img width="100" id="camera_image"> + canvas: <canvas id="canvas" width="1" height="1"></canvas> + </div> + <h2>Cordova Capture API</h2> + <div id="image-options"></div> + <div class="btn large" onclick="getPicture();">camera.getPicture()</div> + <h2>Native File Inputs</h2> + <div>input type=file <input type="file" onchange="testInputTag(this)"></div> + <div>capture=camera <input type="file" accept="image/*;capture=camera" onchange="testInputTag(this)"></div> + <div>capture=camcorder <input type="file" accept="video/*;capture=camcorder" onchange="testInputTag(this)"></div> + <div>capture=microphone <input type="file" accept="audio/*;capture=microphone" onchange="testInputTag(this)"></div> + <h2>Actions</h2> + <div class="btn large" onclick="getFileInfo();">Get File Metadata</div> + <div class="btn large" onclick="readFile();">Read with FileReader</div> + <div class="btn large" onclick="copyImage();">Copy Image</div> + <div class="btn large" onclick="writeImage();">Write Image</div> + <div class="btn large" onclick="uploadImage();">Upload Image</div> + <div class="btn large" onclick="displayImageUsingCanvas();">Draw Using Canvas</div> + <div class="btn large" onclick="removeImage();">Remove Image</div> + + <div class="btn large" onclick="getAudio();">Capture and play audio</div> + <h2> </h2><div class="backBtn" onclick="backHome();">Back</div> + </body> +</html> http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/bf272273/index.html ---------------------------------------------------------------------- diff --git a/index.html b/index.html index 727c504..568d94f 100644 --- a/index.html +++ b/index.html @@ -47,6 +47,7 @@ <a href="audio/index.html" class="btn large">Audio Play/Record</a> <a href="battery/index.html" class="btn large">Battery</a> <a href="camera/index.html" class="btn large">Camera</a> + <a href="capture/index.html" class="btn large">Capture</a> <a href="compass/index.html" class="btn large">Compass</a> <a href="contacts/index.html" class="btn large">Contacts</a> <a href="events/index.html" class="btn large">Events</a>
