| <!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(); |
| |
| //default camera options |
| var camQualityDefault = ['quality value', 50]; |
| var camDestinationTypeDefault = ['FILE_URI', 1]; |
| var camPictureSourceTypeDefault = ['CAMERA', 1]; |
| var camAllowEditDefault = ['allowEdit', false]; |
| var camEncodingTypeDefault = ['JPEG', 0]; |
| var camMediaTypeDefault = ['mediaType', 0]; |
| var camCorrectOrientationDefault = ['correctOrientation', false]; |
| var camSaveToPhotoAlbumDefault = ['saveToPhotoAlbum', true]; |
| |
| |
| //------------------------------------------------------------------------- |
| // Camera |
| //------------------------------------------------------------------------- |
| |
| function log(value) { |
| console.log(value); |
| document.getElementById('camera_status').textContent += (new Date() - pageStartTime) / 1000 + ': ' + value + '\n'; |
| } |
| |
| 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 Camera 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> |
| <h2> </h2><div class="backBtn" onclick="backHome();">Back</div> |
| </body> |
| </html> |