diff --git a/README.md b/README.md index 27bf6f5..c3948f0 100644 --- a/README.md +++ b/README.md @@ -179,14 +179,10 @@ than `DATA_URL`. __Supported Platforms__ - Android -- BlackBerry - Browser -- Firefox -- FireOS - iOS - Windows -- WP8 -- Ubuntu +- OSX More examples [here](#camera-getPicture-examples). Quirks [here](#camera-getPicture-quirks). @@ -469,12 +465,6 @@ Take a photo and retrieve it as a Base64-encoded image: <preference name="CameraUsesGeolocation" value="false" /> -#### Amazon Fire OS Quirks <a name="camera-getPicture-quirks"></a> - -Amazon Fire OS uses intents to launch the camera activity on the device to capture -images, and on phones with low memory, the Cordova activity may be killed. In this -scenario, the image may not appear when the Cordova activity is restored. - #### Android Quirks Android uses intents to launch the camera activity on the device to capture @@ -490,10 +480,6 @@ successful. Can only return photos as Base64-encoded image. -#### Firefox OS Quirks - -Camera plugin is currently implemented using [Web Activities][web_activities]. - #### iOS Quirks Including a JavaScript `alert()` in either of the callback functions @@ -505,11 +491,6 @@ displays: // do your thing here! }, 0); -#### Windows Phone 7 Quirks - -Invoking the native camera application while the device is connected -via Zune does not work, and triggers an error callback. - #### Windows quirks On Windows Phone 8.1 using `SAVEDPHOTOALBUM` or `PHOTOLIBRARY` as a source type causes application to suspend until file picker returns the selected image and @@ -520,22 +501,6 @@ To avoid this we suggest using SPA pattern or call `camera.getPicture` only from More information about Windows Phone 8.1 picker APIs is here: [How to continue your Windows Phone app after calling a file picker](https://msdn.microsoft.com/en-us/library/windows/apps/dn720490.aspx) -#### Tizen Quirks - -Tizen only supports a `destinationType` of -`Camera.DestinationType.FILE_URI` and a `sourceType` of -`Camera.PictureSourceType.PHOTOLIBRARY`. - - -## `CameraOptions` Errata <a name="CameraOptions-quirks"></a> - -#### Amazon Fire OS Quirks - -- Any `cameraDirection` value results in a back-facing photo. - -- Ignores the `allowEdit` parameter. - -- `Camera.PictureSourceType.PHOTOLIBRARY` and `Camera.PictureSourceType.SAVEDPHOTOALBUM` both display the same photo album. #### Android Quirks @@ -547,38 +512,6 @@ Tizen only supports a `destinationType` of - Ignores the `encodingType` parameter if the image is unedited (i.e. `quality` is 100, `correctOrientation` is false, and no `targetHeight` or `targetWidth` are specified). The `CAMERA` source will always return the JPEG file given by the native camera and the `PHOTOLIBRARY` and `SAVEDPHOTOALBUM` sources will return the selected file in its existing encoding. -#### BlackBerry 10 Quirks - -- Ignores the `quality` parameter. - -- Ignores the `allowEdit` parameter. - -- `Camera.MediaType` is not supported. - -- Ignores the `correctOrientation` parameter. - -- Ignores the `cameraDirection` parameter. - -#### Firefox OS Quirks - -- Ignores the `quality` parameter. - -- `Camera.DestinationType` is ignored and equals `1` (image file URI) - -- Ignores the `allowEdit` parameter. - -- Ignores the `PictureSourceType` parameter (user chooses it in a dialog window) - -- Ignores the `encodingType` - -- Ignores the `targetWidth` and `targetHeight` - -- `Camera.MediaType` is not supported. - -- Ignores the `correctOrientation` parameter. - -- Ignores the `cameraDirection` parameter. - #### iOS Quirks - When using `destinationType.FILE_URI`, photos are saved in the application's temporary directory. The contents of the application's temporary directory is deleted when the application ends. @@ -587,29 +520,6 @@ Tizen only supports a `destinationType` of - When using `destinationType.NATIVE_URI` and `sourceType.PHOTOLIBRARY` or `sourceType.SAVEDPHOTOALBUM`, all editing options are ignored and link is returned to original picture. -#### Tizen Quirks - -- options not supported - -- always returns a FILE URI - -#### Windows Phone 7 and 8 Quirks - -- Ignores the `allowEdit` parameter. - -- Ignores the `correctOrientation` parameter. - -- Ignores the `cameraDirection` parameter. - -- Ignores the `saveToPhotoAlbum` parameter. IMPORTANT: All images taken with the WP8/8 Cordova camera API are always copied to the phone's camera roll. Depending on the user's settings, this could also mean the image is auto-uploaded to their OneDrive. This could potentially mean the image is available to a wider audience than your app intended. If this is a blocker for your application, you will need to implement the CameraCaptureTask as [documented on MSDN][msdn_wp8_docs]. You may also comment or up-vote the related issue in the [issue tracker][wp8_bug]. - -- Ignores the `mediaType` property of `cameraOptions` as the Windows Phone SDK does not provide a way to choose videos from PHOTOLIBRARY. - -[android_lifecycle]: http://cordova.apache.org/docs/en/dev/guide/platforms/android/lifecycle.html -[web_activities]: https://hacks.mozilla.org/2013/01/introducing-web-activities/ -[wp8_bug]: https://issues.apache.org/jira/browse/CB-2083 -[msdn_wp8_docs]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx - ## Sample: Take Pictures, Select Pictures from the Picture Library, and Get Thumbnails <a name="sample"></a> The Camera plugin allows you to do things like open the device's Camera app and take a picture, or open the file picker and select one. The code snippets in this section demonstrate different tasks including: diff --git a/package.json b/package.json index 5ff3df1..80b4fb9 100644 --- a/package.json +++ b/package.json @@ -1,20 +1,13 @@ { "name": "cordova-plugin-camera", - "version": "3.0.1-dev", + "version": "4.0.0-dev", "description": "Cordova Camera Plugin", "types": "./types/index.d.ts", "cordova": { "id": "cordova-plugin-camera", "platforms": [ - "firefoxos", "android", - "amazon-fireos", - "ubuntu", "ios", - "blackberry10", - "wp7", - "wp8", - "windows8", "browser", "windows", "osx" @@ -31,15 +24,8 @@ "cordova", "camera", "ecosystem:cordova", - "cordova-firefoxos", "cordova-android", - "cordova-amazon-fireos", - "cordova-ubuntu", "cordova-ios", - "cordova-blackberry10", - "cordova-wp7", - "cordova-wp8", - "cordova-windows8", "cordova-browser", "cordova-windows", "cordova-osx" diff --git a/plugin.xml b/plugin.xml index cd59c02..31728cb 100644 --- a/plugin.xml +++ b/plugin.xml @@ -22,7 +22,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:rim="http://www.blackberry.com/ns/widgets" id="cordova-plugin-camera" - version="3.0.1-dev"> + version="4.0.0-dev"> <name>Camera</name> <description>Cordova Camera Plugin</description> <license>Apache 2.0</license> @@ -48,19 +48,6 @@ <clobbers target="navigator.camera" /> </js-module> - <!-- firefoxos --> - <platform name="firefoxos"> - <config-file target="config.xml" parent="/*"> - <feature name="Camera"> - <param name="firefoxos-package" value="Camera" /> - </feature> - </config-file> - - <js-module src="src/firefoxos/CameraProxy.js" name="CameraProxy"> - <runs /> - </js-module> - </platform> - <!-- android --> <platform name="android"> <config-file target="res/xml/config.xml" parent="/*"> @@ -97,48 +84,6 @@ </platform> - <!-- amazon-fireos --> - <platform name="amazon-fireos"> - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="Camera"> - <param name="android-package" value="org.apache.cordova.camera.CameraLauncher"/> - </feature> - </config-file> - <config-file target="AndroidManifest.xml" parent="/*"> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> - </config-file> - - <source-file src="src/android/CameraLauncher.java" target-dir="src/org/apache/cordova/camera" /> - <source-file src="src/android/FileHelper.java" target-dir="src/org/apache/cordova/camera" /> - <source-file src="src/android/ExifHelper.java" target-dir="src/org/apache/cordova/camera" /> - - <js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle"> - <clobbers target="CameraPopoverHandle" /> - </js-module> - - </platform> - - <!-- ubuntu --> - <platform name="ubuntu"> - <config-file target="config.xml" parent="/*"> - <feature name="Camera"> - <param policy_group="camera" policy_version="1" /> - </feature> - </config-file> - <js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle"> - <clobbers target="CameraPopoverHandle" /> - </js-module> - <header-file src="src/ubuntu/camera.h" /> - <source-file src="src/ubuntu/camera.cpp" /> - - <resource-file src="src/ubuntu/back.png" /> - <resource-file src="src/ubuntu/CaptureWidget.qml" /> - <resource-file src="src/ubuntu/shoot.png" /> - <resource-file src="src/ubuntu/toolbar-left.png" /> - <resource-file src="src/ubuntu/toolbar-middle.png" /> - <resource-file src="src/ubuntu/toolbar-right.png" /> - </platform> - <!-- ios --> <platform name="ios"> <config-file target="config.xml" parent="/*"> @@ -169,79 +114,6 @@ </platform> - <!-- blackberry10 --> - <platform name="blackberry10"> - <source-file src="src/blackberry10/index.js" target-dir="Camera" /> - <config-file target="www/config.xml" parent="/widget"> - <feature name="Camera" value="Camera"/> - </config-file> - <config-file target="www/config.xml" parent="/widget/rim:permissions"> - <rim:permit>access_shared</rim:permit> - <rim:permit>use_camera</rim:permit> - </config-file> - <js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle"> - <clobbers target="CameraPopoverHandle" /> - </js-module> - <asset src="www/blackberry10/assets" target="chrome" /> - </platform> - - <!-- wp7 --> - <platform name="wp7"> - <config-file target="config.xml" parent="/*"> - <feature name="Camera"> - <param name="wp-package" value="Camera"/> - </feature> - </config-file> - - <config-file target="Properties/WMAppManifest.xml" parent="/Deployment/App/Capabilities"> - <Capability Name="ID_CAP_ISV_CAMERA" /> - <Capability Name="ID_CAP_MEDIALIB" /> - </config-file> - - <source-file src="src/wp/Camera.cs" /> - - - <js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle"> - <clobbers target="CameraPopoverHandle" /> - </js-module> - </platform> - - <!-- wp8 --> - <platform name="wp8"> - <config-file target="config.xml" parent="/*"> - <feature name="Camera"> - <param name="wp-package" value="Camera"/> - </feature> - </config-file> - - <config-file target="Properties/WMAppManifest.xml" parent="/Deployment/App/Capabilities"> - <Capability Name="ID_CAP_ISV_CAMERA" /> - <Capability Name="ID_CAP_MEDIALIB_PHOTO"/> - </config-file> - - <source-file src="src/wp/Camera.cs" /> - - <js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle"> - <clobbers target="CameraPopoverHandle" /> - </js-module> - </platform> - - <!-- windows8 --> - <platform name="windows8"> - - <config-file target="package.appxmanifest" parent="/Package/Capabilities"> - <Capability Name="picturesLibrary" /> - <DeviceCapability Name="webcam" /> - </config-file> - <js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle"> - <clobbers target="CameraPopoverHandle" /> - </js-module> - <js-module src="src/windows/CameraProxy.js" name="CameraProxy"> - <runs /> - </js-module> - - </platform> - <!-- browser --> <platform name="browser"> <config-file target="config.xml" parent="/*"> diff --git a/src/blackberry10/index.js b/src/blackberry10/index.js deleted file mode 100644 index 2ec7f69..0000000 --- a/src/blackberry10/index.js +++ /dev/null @@ -1,227 +0,0 @@ -/* - * - * 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. - * -*/ - -/* globals qnx, FileError, PluginResult */ - -var PictureSourceType = { - PHOTOLIBRARY: 0, // Choose image from picture library (same as SAVEDPHOTOALBUM for Android) - CAMERA: 1, // Take picture from camera - SAVEDPHOTOALBUM: 2 // Choose image from picture library (same as PHOTOLIBRARY for Android) -}; -var DestinationType = { - DATA_URL: 0, // Return base64 encoded string - FILE_URI: 1, // Return file uri (content://media/external/images/media/2 for Android) - NATIVE_URI: 2 // Return native uri (eg. asset-library://... for iOS) -}; -var savePath = window.qnx.webplatform.getApplication().getEnv('HOME').replace('/data', '') + '/shared/camera/'; -var invokeAvailable = true; - -// check for camera card - it isn't currently availble in work perimeter -window.qnx.webplatform.getApplication().invocation.queryTargets( - { - type: 'image/jpeg', - action: 'bb.action.CAPTURE', - target_type: 'CARD' - }, - function (error, targets) { - invokeAvailable = !error && targets && targets instanceof Array && - targets.filter(function (t) { return t.default === 'sys.camera.card'; }).length > 0; - } -); - -// open a webview with getUserMedia camera card implementation when camera card not available -function showCameraDialog (done, cancel, fail) { - var wv = qnx.webplatform.createWebView(function () { - wv.url = 'local:///chrome/camera.html'; - wv.allowQnxObject = true; - wv.allowRpc = true; - wv.zOrder = 1; - wv.setGeometry(0, 0, screen.width, screen.height); /* eslint no-undef : 0 */ - wv.backgroundColor = 0x00000000; - wv.active = true; - wv.visible = true; - wv.on('UserMediaRequest', function (evt, args) { - wv.allowUserMedia(JSON.parse(args).id, 'CAMERA_UNIT_REAR'); - }); - wv.on('JavaScriptCallback', function (evt, data) { - var args = JSON.parse(data).args; - if (args[0] === 'cordova-plugin-camera') { - if (args[1] === 'cancel') { - cancel('User canceled'); - } else if (args[1] === 'error') { - fail(args[2]); - } else { - saveImage(args[1], done, fail); - } - wv.un('JavaScriptCallback', arguments.callee); /* eslint no-caller : 0 */ - wv.visible = false; - wv.destroy(); - qnx.webplatform.getApplication().unlockRotation(); - } - }); - wv.on('Destroyed', function () { - wv.delete(); - }); - qnx.webplatform.getApplication().lockRotation(); - qnx.webplatform.getController().dispatchEvent('webview.initialized', [wv]); - }); -} - -// create unique name for saved file (same pattern as BB10 camera app) -function imgName () { - var date = new Date(); - var pad = function (n) { return n < 10 ? '0' + n : n; }; - return 'IMG_' + date.getFullYear() + pad(date.getMonth() + 1) + pad(date.getDate()) + '_' + - pad(date.getHours()) + pad(date.getMinutes()) + pad(date.getSeconds()) + '.png'; -} - -// convert dataURI to Blob -function dataURItoBlob (dataURI) { - var byteString = atob(dataURI.split(',')[1]); - var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; - var arrayBuffer = new ArrayBuffer(byteString.length); - var ia = new Uint8Array(arrayBuffer); - var i; - for (i = 0; i < byteString.length; i++) { - ia[i] = byteString.charCodeAt(i); - } - return new Blob([new DataView(arrayBuffer)], { type: mimeString }); -} - -// save dataURI to file system and call success with path -function saveImage (data, success, fail) { - var name = savePath + imgName(); - require('lib/webview').setSandbox(false); - window.webkitRequestFileSystem(window.PERSISTENT, 0, function (fs) { - fs.root.getFile(name, { create: true }, function (entry) { - entry.createWriter(function (writer) { - writer.onwriteend = function () { - success(name); - }; - writer.onerror = fail; - writer.write(dataURItoBlob(data)); - }); - }, fail); - }, fail); -} - -function encodeBase64 (filePath, callback) { - var sandbox = window.qnx.webplatform.getController().setFileSystemSandbox; // save original sandbox value - var errorHandler = function (err) { - var msg = 'An error occured: '; - - switch (err.code) { - case FileError.NOT_FOUND_ERR: - msg += 'File or directory not found'; - break; - - case FileError.NOT_READABLE_ERR: - msg += 'File or directory not readable'; - break; - - case FileError.PATH_EXISTS_ERR: - msg += 'File or directory already exists'; - break; - - case FileError.TYPE_MISMATCH_ERR: - msg += 'Invalid file type'; - break; - - default: - msg += 'Unknown Error'; - break; - } - - // set it back to original value - window.qnx.webplatform.getController().setFileSystemSandbox = sandbox; - callback(msg); - }; - var gotFile = function (fileEntry) { - fileEntry.file(function (file) { - var reader = new FileReader(); - - reader.onloadend = function (e) { - // set it back to original value - window.qnx.webplatform.getController().setFileSystemSandbox = sandbox; - callback(this.result); - }; - - reader.readAsDataURL(file); - }, errorHandler); - }; - var onInitFs = function (fs) { - window.qnx.webplatform.getController().setFileSystemSandbox = false; - fs.root.getFile(filePath, {create: false}, gotFile, errorHandler); - }; - - window.webkitRequestFileSystem(window.TEMPORARY, 10 * 1024 * 1024, onInitFs, errorHandler); // set size to 10MB max -} - -module.exports = { - takePicture: function (success, fail, args, env) { - var destinationType = JSON.parse(decodeURIComponent(args[1])); - var sourceType = JSON.parse(decodeURIComponent(args[2])); - var result = new PluginResult(args, env); - var done = function (data) { - if (destinationType === DestinationType.FILE_URI) { - data = 'file://' + data; - result.callbackOk(data, false); - } else { - encodeBase64(data, function (data) { - if (/^data:/.test(data)) { - data = data.slice(data.indexOf(',') + 1); - result.callbackOk(data, false); - } else { - result.callbackError(data, false); - } - }); - } - }; - var cancel = function (reason) { - result.callbackError(reason, false); - }; - var invoked = function (error) { - if (error) { - result.callbackError(error, false); - } - }; - - switch (sourceType) { - case PictureSourceType.CAMERA: - if (invokeAvailable) { - window.qnx.webplatform.getApplication().cards.camera.open('photo', done, cancel, invoked); - } else { - showCameraDialog(done, cancel, fail); - } - break; - - case PictureSourceType.PHOTOLIBRARY: - case PictureSourceType.SAVEDPHOTOALBUM: - window.qnx.webplatform.getApplication().cards.filePicker.open({ - mode: 'Picker', - type: ['picture'] - }, done, cancel, invoked); - break; - } - - result.noResult(true); - } -}; diff --git a/src/firefoxos/CameraProxy.js b/src/firefoxos/CameraProxy.js deleted file mode 100644 index 83a685a..0000000 --- a/src/firefoxos/CameraProxy.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * 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. - * - */ - -/* globals MozActivity */ - -function takePicture (success, error, opts) { - var pick = new MozActivity({ - name: 'pick', - data: { - type: ['image/*'] - } - }); - - pick.onerror = error || function () {}; - - pick.onsuccess = function () { - // image is returned as Blob in this.result.blob - // we need to call success with url or base64 encoded image - if (opts && opts.destinationType === 0) { - // TODO: base64 - return; - } - if (!opts || !opts.destinationType || opts.destinationType > 0) { - // url - return success(window.URL.createObjectURL(this.result.blob)); - } - }; -} - -module.exports = { - takePicture: takePicture, - cleanup: function () {} -}; - -require('cordova/exec/proxy').add('Camera', module.exports); diff --git a/src/ubuntu/CaptureWidget.qml b/src/ubuntu/CaptureWidget.qml deleted file mode 100644 index 0a332e2..0000000 --- a/src/ubuntu/CaptureWidget.qml +++ /dev/null @@ -1,118 +0,0 @@ -/* - * - * Copyright 2013 Canonical Ltd. - * - * 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. - * -*/ -import QtQuick 2.0 -import QtMultimedia 5.0 - -Rectangle { - property string shootImagePath: "shoot.png" - function isSuffix(str, suffix) { - return String(str).substr(String(str).length - suffix.length) == suffix - } - - id: ui - color: "#252423" - anchors.fill: parent - - Camera { - objectName: "camera" - id: camera - onError: { - console.log(errorString); - } - videoRecorder.audioBitRate: 128000 - imageCapture { - onImageSaved: { - root.exec("Camera", "onImageSaved", [path]); - ui.destroy(); - } - } - } - VideoOutput { - id: output - source: camera - width: parent.width - height: parent.height - } - - Item { - anchors.bottom: parent.bottom - width: parent.width - height: shootButton.height - BorderImage { - id: leftBackground - anchors.left: parent.left - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.right: middle.left - anchors.topMargin: units.dp(2) - anchors.bottomMargin: units.dp(2) - source: "toolbar-left.png" - Image { - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: parent.iconSpacing - source: "back.png" - width: units.gu(6) - height: units.gu(5) - MouseArea { - anchors.fill: parent - onClicked: { - root.exec("Camera", "cancel"); - } - } - } - } - BorderImage { - id: middle - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - height: shootButton.height + units.gu(1) - width: shootButton.width - source: "toolbar-middle.png" - Image { - id: shootButton - width: units.gu(8) - height: width - anchors.horizontalCenter: parent.horizontalCenter - source: shootImagePath - MouseArea { - anchors.fill: parent - onClicked: { - camera.imageCapture.captureToLocation(ui.parent.plugin('Camera').generateLocation("jpg")); - } - } - } - } - BorderImage { - id: rightBackground - anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: middle.right - anchors.topMargin: units.dp(2) - anchors.bottomMargin: units.dp(2) - source: "toolbar-right.png" - } - } -} diff --git a/src/ubuntu/back.png b/src/ubuntu/back.png deleted file mode 100644 index af78faa..0000000 Binary files a/src/ubuntu/back.png and /dev/null differ diff --git a/src/ubuntu/camera.cpp b/src/ubuntu/camera.cpp deleted file mode 100644 index c58af32..0000000 --- a/src/ubuntu/camera.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * - * 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. - * -*/ - -#include "camera.h" -#include <cordova.h> - -#include <QCameraViewfinder> -#include <QCameraImageCapture> -#include <QGraphicsObject> -#include <QCloseEvent> -#include <QQuickItem> - -const char code[] = "\ -var component, object; \ -function createObject() { \ - component = Qt.createComponent(%1); \ - if (component.status == Component.Ready) \ - finishCreation(); \ - else \ - component.statusChanged.connect(finishCreation); \ -} \ -function finishCreation() { \ - CordovaWrapper.global.cameraPluginWidget = component.createObject(root, \ - {root: root, cordova: cordova}); \ -} \ -createObject()"; - - -Camera::Camera(Cordova *cordova): - CPlugin(cordova), - _lastScId(0), - _lastEcId(0) { -} - -bool Camera::preprocessImage(QString &path) { - bool convertToPNG = (*_options.find("encodingType")).toInt() == Camera::PNG; - int quality = (*_options.find("quality")).toInt(); - int width = (*_options.find("targetWidth")).toInt(); - int height = (*_options.find("targetHeight")).toInt(); - - QImage image(path); - if (width <= 0) - width = image.width(); - if (height <= 0) - height = image.height(); - image = image.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation); - - QFile oldImage(path); - QTemporaryFile newImage; - - const char *type; - if (convertToPNG) { - path = generateLocation("png"); - type = "png"; - } else { - path = generateLocation("jpg"); - type = "jpg"; - } - - image.save(path, type, quality); - - oldImage.remove(); - - return true; -} - -void Camera::onImageSaved(QString path) { - bool dataURL = _options.find("destinationType")->toInt() == Camera::DATA_URL; - - QString cbParams; - if (preprocessImage(path)) { - QString absolutePath = QFileInfo(path).absoluteFilePath(); - if (dataURL) { - QFile image(absolutePath); - image.open(QIODevice::ReadOnly); - QByteArray content = image.readAll().toBase64(); - cbParams = QString("\"%1\"").arg(content.data()); - image.remove(); - } else { - cbParams = CordovaInternal::format(QString("file://localhost") + absolutePath); - } - } - - this->callback(_lastScId, cbParams); - - _lastEcId = _lastScId = 0; -} - -void Camera::takePicture(int scId, int ecId, int quality, int destinationType, int/*sourceType*/, int targetWidth, int targetHeight, int encodingType, - int/*mediaType*/, bool/*allowEdit*/, bool/*correctOrientation*/, bool/*saveToPhotoAlbum*/, const QVariantMap &/*popoverOptions*/, int/*cameraDirection*/) { - if (_camera.isNull()) { - _camera = QSharedPointer<QCamera>(new QCamera()); - } - - if (((_lastScId || _lastEcId) && (_lastScId != scId && _lastEcId != ecId)) || !_camera->isAvailable() || _camera->lockStatus() != QCamera::Unlocked) { - this->cb(_lastEcId, "Device is busy"); - return; - } - - _options.clear(); - _options.insert("quality", quality); - _options.insert("destinationType", destinationType); - _options.insert("targetWidth", targetWidth); - _options.insert("targetHeight", targetHeight); - _options.insert("encodingType", encodingType); - - _lastScId = scId; - _lastEcId = ecId; - - QString path = m_cordova->get_app_dir() + "/../qml/CaptureWidget.qml"; - - // TODO: relative url - QString qml = QString(code).arg(CordovaInternal::format(path)); - m_cordova->execQML(qml); -} - -void Camera::cancel() { - m_cordova->execQML("CordovaWrapper.global.cameraPluginWidget.destroy()"); - this->cb(_lastEcId, "canceled"); - - _lastEcId = _lastScId = 0; -} diff --git a/src/ubuntu/camera.h b/src/ubuntu/camera.h deleted file mode 100644 index 6d96038..0000000 --- a/src/ubuntu/camera.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * - * 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. - * -*/ - -#ifndef CAMERA_H -#define CAMERA_H - -#include <cplugin.h> - -#include <QtCore> -#include <QQuickView> -#include <QCamera> -#include <QtMultimediaWidgets/QCameraViewfinder> -#include <QCameraImageCapture> - -class Camera: public CPlugin { - Q_OBJECT -public: - explicit Camera(Cordova *cordova); - - virtual const QString fullName() override { - return Camera::fullID(); - } - - virtual const QString shortName() override { - return "Camera"; - } - - static const QString fullID() { - return "Camera"; - } - -public slots: - void takePicture(int scId, int ecId, int quality, int destinationType, int/*sourceType*/, int targetWidth, int targetHeight, int encodingType, - int/*mediaType*/, bool/*allowEdit*/, bool/*correctOrientation*/, bool/*saveToPhotoAlbum*/, const QVariantMap &popoverOptions, int cameraDirection); - void cancel(); - - void onImageSaved(QString path); - - QString generateLocation(const QString &extension) { - int i = 1; - for (;;++i) { - QString path = QString("%1/.local/share/%2/persistent/%3.%4").arg(QDir::homePath()) - .arg(QCoreApplication::applicationName()).arg(i).arg(extension); - - if (!QFileInfo(path).exists()) - return path; - } - } -private: - bool preprocessImage(QString &path); - - int _lastScId; - int _lastEcId; - QSharedPointer<QCamera> _camera; - - QVariantMap _options; -protected: - enum DestinationType { - DATA_URL = 0, - FILE_URI = 1 - }; - enum EncodingType { - JPEG = 0, - PNG = 1 - }; -}; - -#endif // CAMERA_H diff --git a/src/ubuntu/shoot.png b/src/ubuntu/shoot.png deleted file mode 100644 index c093b63..0000000 Binary files a/src/ubuntu/shoot.png and /dev/null differ diff --git a/src/ubuntu/toolbar-left.png b/src/ubuntu/toolbar-left.png deleted file mode 100644 index 720d7f6..0000000 Binary files a/src/ubuntu/toolbar-left.png and /dev/null differ diff --git a/src/ubuntu/toolbar-middle.png b/src/ubuntu/toolbar-middle.png deleted file mode 100644 index 77595bb..0000000 Binary files a/src/ubuntu/toolbar-middle.png and /dev/null differ diff --git a/src/ubuntu/toolbar-right.png b/src/ubuntu/toolbar-right.png deleted file mode 100644 index e4e6aa6..0000000 Binary files a/src/ubuntu/toolbar-right.png and /dev/null differ diff --git a/src/wp/Camera.cs b/src/wp/Camera.cs deleted file mode 100644 index 264a205..0000000 --- a/src/wp/Camera.cs +++ /dev/null @@ -1,534 +0,0 @@ -/* - Licensed 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. -*/ - -using System; -using System.Net; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Ink; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Collections.Generic; -using Microsoft.Phone.Tasks; -using System.Runtime.Serialization; -using System.IO; -using System.IO.IsolatedStorage; -using System.Windows.Media.Imaging; -using Microsoft.Phone; -using Microsoft.Xna.Framework.Media; -using System.Diagnostics; - -namespace WPCordovaClassLib.Cordova.Commands -{ - public class Camera : BaseCommand - { - - /// <summary> - /// Return base64 encoded string - /// </summary> - private const int DATA_URL = 0; - - /// <summary> - /// Return file uri - /// </summary> - private const int FILE_URI = 1; - - /// <summary> - /// Return native uri - /// </summary> - private const int NATIVE_URI = 2; - - /// <summary> - /// Choose image from picture library - /// </summary> - private const int PHOTOLIBRARY = 0; - - /// <summary> - /// Take picture from camera - /// </summary> - - private const int CAMERA = 1; - - /// <summary> - /// Choose image from picture library - /// </summary> - private const int SAVEDPHOTOALBUM = 2; - - /// <summary> - /// Take a picture of type JPEG - /// </summary> - private const int JPEG = 0; - - /// <summary> - /// Take a picture of type PNG - /// </summary> - private const int PNG = 1; - - /// <summary> - /// Folder to store captured images - /// </summary> - private const string isoFolder = "CapturedImagesCache"; - - /// <summary> - /// Represents captureImage action options. - /// </summary> - [DataContract] - public class CameraOptions - { - /// <summary> - /// Source to getPicture from. - /// </summary> - [DataMember(IsRequired = false, Name = "sourceType")] - public int PictureSourceType { get; set; } - - /// <summary> - /// Format of image that returned from getPicture. - /// </summary> - [DataMember(IsRequired = false, Name = "destinationType")] - public int DestinationType { get; set; } - - /// <summary> - /// Quality of saved image - /// </summary> - [DataMember(IsRequired = false, Name = "quality")] - public int Quality { get; set; } - - /// <summary> - /// Controls whether or not the image is also added to the device photo album. - /// </summary> - [DataMember(IsRequired = false, Name = "saveToPhotoAlbum")] - public bool SaveToPhotoAlbum { get; set; } - - /// <summary> - /// Ignored - /// </summary> - [DataMember(IsRequired = false, Name = "correctOrientation")] - public bool CorrectOrientation { get; set; } - - /// <summary> - /// Ignored - /// </summary> - [DataMember(IsRequired = false, Name = "allowEdit")] - public bool AllowEdit { get; set; } - - /// <summary> - /// Height in pixels to scale image - /// </summary> - [DataMember(IsRequired = false, Name = "encodingType")] - public int EncodingType { get; set; } - - /// <summary> - /// Height in pixels to scale image - /// </summary> - [DataMember(IsRequired = false, Name = "mediaType")] - public int MediaType { get; set; } - - - /// <summary> - /// Height in pixels to scale image - /// </summary> - [DataMember(IsRequired = false, Name = "targetHeight")] - public int TargetHeight { get; set; } - - - /// <summary> - /// Width in pixels to scale image - /// </summary> - [DataMember(IsRequired = false, Name = "targetWidth")] - public int TargetWidth { get; set; } - - /// <summary> - /// Creates options object with default parameters - /// </summary> - public CameraOptions() - { - this.SetDefaultValues(new StreamingContext()); - } - - /// <summary> - /// Initializes default values for class fields. - /// Implemented in separate method because default constructor is not invoked during deserialization. - /// </summary> - /// <param name="context"></param> - [OnDeserializing()] - public void SetDefaultValues(StreamingContext context) - { - PictureSourceType = CAMERA; - DestinationType = FILE_URI; - Quality = 80; - TargetHeight = -1; - TargetWidth = -1; - SaveToPhotoAlbum = false; - CorrectOrientation = true; - AllowEdit = false; - MediaType = -1; - EncodingType = -1; - } - } - - /// <summary> - /// Camera options - /// </summary> - CameraOptions cameraOptions; - - public void takePicture(string options) - { - try - { - string[] args = JSON.JsonHelper.Deserialize<string[]>(options); - // ["quality", "destinationType", "sourceType", "targetWidth", "targetHeight", "encodingType", - // "mediaType", "allowEdit", "correctOrientation", "saveToPhotoAlbum" ] - cameraOptions = new CameraOptions(); - cameraOptions.Quality = int.Parse(args[0]); - cameraOptions.DestinationType = int.Parse(args[1]); - cameraOptions.PictureSourceType = int.Parse(args[2]); - cameraOptions.TargetWidth = int.Parse(args[3]); - cameraOptions.TargetHeight = int.Parse(args[4]); - cameraOptions.EncodingType = int.Parse(args[5]); - cameraOptions.MediaType = int.Parse(args[6]); - cameraOptions.AllowEdit = bool.Parse(args[7]); - cameraOptions.CorrectOrientation = bool.Parse(args[8]); - cameraOptions.SaveToPhotoAlbum = bool.Parse(args[9]); - - // a very large number will force the other value to be the bound - if (cameraOptions.TargetWidth > -1 && cameraOptions.TargetHeight == -1) - { - cameraOptions.TargetHeight = 100000; - } - else if (cameraOptions.TargetHeight > -1 && cameraOptions.TargetWidth == -1) - { - cameraOptions.TargetWidth = 100000; - } - } - catch (Exception ex) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message)); - return; - } - - // Api supports FILE_URI, DATA_URL, NATIVE_URI destination types. - // Treat all other destination types as an error. - switch (cameraOptions.DestinationType) - { - case Camera.FILE_URI: - case Camera.DATA_URL: - case Camera.NATIVE_URI: - break; - default: - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType")); - return; - } - - ChooserBase<PhotoResult> chooserTask = null; - if (cameraOptions.PictureSourceType == CAMERA) - { - chooserTask = new CameraCaptureTask(); - } - else if ((cameraOptions.PictureSourceType == PHOTOLIBRARY) || (cameraOptions.PictureSourceType == SAVEDPHOTOALBUM)) - { - chooserTask = new PhotoChooserTask(); - } - // if chooserTask is still null, then PictureSourceType was invalid - if (chooserTask != null) - { - chooserTask.Completed += onTaskCompleted; - chooserTask.Show(); - } - else - { - Debug.WriteLine("Unrecognized PictureSourceType :: " + cameraOptions.PictureSourceType.ToString()); - DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT)); - } - } - - public void onTaskCompleted(object sender, PhotoResult e) - { - var task = sender as ChooserBase<PhotoResult>; - if (task != null) - { - task.Completed -= onTaskCompleted; - } - - if (e.Error != null) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR)); - return; - } - - switch (e.TaskResult) - { - case TaskResult.OK: - try - { - string imagePathOrContent = string.Empty; - - // Save image back to media library - // only save to photoalbum if it didn't come from there ... - if (cameraOptions.PictureSourceType == CAMERA && cameraOptions.SaveToPhotoAlbum) - { - MediaLibrary library = new MediaLibrary(); - Picture pict = library.SavePicture(e.OriginalFileName, e.ChosenPhoto); // to save to photo-roll ... - } - - int newAngle = 0; - // There's bug in Windows Phone 8.1 causing Seek on a DssPhotoStream not working properly. - // https://connect.microsoft.com/VisualStudio/feedback/details/783252 - // But a mis-oriented file is better than nothing, so try and catch. - try { - int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto); - switch (orient) { - case ImageExifOrientation.LandscapeLeft: - newAngle = 90; - break; - case ImageExifOrientation.PortraitUpsideDown: - newAngle = 180; - break; - case ImageExifOrientation.LandscapeRight: - newAngle = 270; - break; - case ImageExifOrientation.Portrait: - default: break; // 0 default already set - } - } catch { - Debug.WriteLine("Error fetching orientation from Exif"); - } - - if (newAngle != 0) - { - using (Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle)) - { - // we should reset stream position after saving stream to media library - rotImageStream.Seek(0, SeekOrigin.Begin); - if (cameraOptions.DestinationType == DATA_URL) - { - imagePathOrContent = GetImageContent(rotImageStream); - } - else // FILE_URL or NATIVE_URI (both use the same resultant uri format) - { - imagePathOrContent = SaveImageToLocalStorage(rotImageStream, Path.GetFileName(e.OriginalFileName)); - } - } - } - else // no need to reorient - { - if (cameraOptions.DestinationType == DATA_URL) - { - imagePathOrContent = GetImageContent(e.ChosenPhoto); - } - else // FILE_URL or NATIVE_URI (both use the same resultant uri format) - { - imagePathOrContent = SaveImageToLocalStorage(e.ChosenPhoto, Path.GetFileName(e.OriginalFileName)); - } - } - - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent)); - } - catch (Exception) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image.")); - } - break; - case TaskResult.Cancel: - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled.")); - break; - default: - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!")); - break; - } - } - - /// <summary> - /// Returns image content in a form of base64 string - /// </summary> - /// <param name="stream">Image stream</param> - /// <returns>Base64 representation of the image</returns> - private string GetImageContent(Stream stream) - { - byte[] imageContent = null; - - try - { - // Resize photo and convert to JPEG - imageContent = ResizePhoto(stream); - } - finally - { - stream.Dispose(); - } - - return Convert.ToBase64String(imageContent); - } - - /// <summary> - /// Resize image - /// </summary> - /// <param name="stream">Image stream</param> - /// <returns>resized image</returns> - private byte[] ResizePhoto(Stream stream) - { - //output - byte[] resizedFile; - - BitmapImage objBitmap = new BitmapImage(); - objBitmap.SetSource(stream); - objBitmap.CreateOptions = BitmapCreateOptions.None; - - WriteableBitmap objWB = new WriteableBitmap(objBitmap); - objBitmap.UriSource = null; - - // Calculate resultant image size - int width, height; - if (cameraOptions.TargetWidth >= 0 && cameraOptions.TargetHeight >= 0) - { - // Keep proportionally - double ratio = Math.Min( - (double)cameraOptions.TargetWidth / objWB.PixelWidth, - (double)cameraOptions.TargetHeight / objWB.PixelHeight); - width = Convert.ToInt32(ratio * objWB.PixelWidth); - height = Convert.ToInt32(ratio * objWB.PixelHeight); - } - else - { - width = objWB.PixelWidth; - height = objWB.PixelHeight; - } - - //Hold the result stream - using (MemoryStream objBitmapStreamResized = new MemoryStream()) - { - - try - { - // resize the photo with user defined TargetWidth & TargetHeight - Extensions.SaveJpeg(objWB, objBitmapStreamResized, width, height, 0, cameraOptions.Quality); - } - finally - { - //Dispose bitmaps immediately, they are memory expensive - DisposeImage(objBitmap); - DisposeImage(objWB); - GC.Collect(); - } - - //Convert the resized stream to a byte array. - int streamLength = (int)objBitmapStreamResized.Length; - resizedFile = new Byte[streamLength]; //-1 - objBitmapStreamResized.Position = 0; - - //for some reason we have to set Position to zero, but we don't have to earlier when we get the bytes from the chosen photo... - objBitmapStreamResized.Read(resizedFile, 0, streamLength); - } - - return resizedFile; - } - - /// <summary> - /// Util: Dispose a bitmap resource - /// </summary> - /// <param name="image">BitmapSource subclass to dispose</param> - private void DisposeImage(BitmapSource image) - { - if (image != null) - { - try - { - using (var ms = new MemoryStream(new byte[] { 0x0 })) - { - image.SetSource(ms); - } - } - catch (Exception) - { - } - } - } - - /// <summary> - /// Saves captured image in isolated storage - /// </summary> - /// <param name="imageFileName">image file name</param> - /// <returns>Image path</returns> - private string SaveImageToLocalStorage(Stream stream, string imageFileName) - { - - if (stream == null) - { - throw new ArgumentNullException("imageBytes"); - } - try - { - var isoFile = IsolatedStorageFile.GetUserStoreForApplication(); - - if (!isoFile.DirectoryExists(isoFolder)) - { - isoFile.CreateDirectory(isoFolder); - } - - string filePath = System.IO.Path.Combine("///" + isoFolder + "/", imageFileName); - - using (IsolatedStorageFileStream outputStream = isoFile.CreateFile(filePath)) - { - BitmapImage objBitmap = new BitmapImage(); - objBitmap.SetSource(stream); - objBitmap.CreateOptions = BitmapCreateOptions.None; - - WriteableBitmap objWB = new WriteableBitmap(objBitmap); - objBitmap.UriSource = null; - - try - { - - //use photo's actual width & height if user doesn't provide width & height - if (cameraOptions.TargetWidth < 0 && cameraOptions.TargetHeight < 0) - { - objWB.SaveJpeg(outputStream, objWB.PixelWidth, objWB.PixelHeight, 0, cameraOptions.Quality); - } - else - { - //Resize - //Keep proportionally - double ratio = Math.Min((double)cameraOptions.TargetWidth / objWB.PixelWidth, (double)cameraOptions.TargetHeight / objWB.PixelHeight); - int width = Convert.ToInt32(ratio * objWB.PixelWidth); - int height = Convert.ToInt32(ratio * objWB.PixelHeight); - - // resize the photo with user defined TargetWidth & TargetHeight - objWB.SaveJpeg(outputStream, width, height, 0, cameraOptions.Quality); - } - } - finally - { - //Dispose bitmaps immediately, they are memory expensive - DisposeImage(objBitmap); - DisposeImage(objWB); - GC.Collect(); - } - } - - return new Uri(filePath, UriKind.Relative).ToString(); - } - catch (Exception) - { - //TODO: log or do something else - throw; - } - finally - { - stream.Dispose(); - } - } - - } -} diff --git a/www/blackberry10/assets/camera.html b/www/blackberry10/assets/camera.html deleted file mode 100644 index 2ebd9d1..0000000 --- a/www/blackberry10/assets/camera.html +++ /dev/null @@ -1,82 +0,0 @@ -<!-- - Licensed 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. - --> -<!DOCTYPE HTML> -<html lang="en"> - <head> - <meta charset="utf-8"> - <script src="camera.js" type="text/javascript"></script> - <script> - var meta = document.createElement("meta"); - meta.setAttribute('name','viewport'); - meta.setAttribute('content','initial-scale='+ (1/window.devicePixelRatio) + ',user-scalable=no'); - document.getElementsByTagName('head')[0].appendChild(meta); - </script> - </head> - <style type="text/css"> - body { - background-color: black; - } - .action-bar { - position: fixed; - left: 0px; - bottom: 0px; - height: 100px; - width: 100%; - background-image: linear-gradient(rgb(41, 41, 41), rgb(32, 32, 32)); - } - .action-bar-back { - width: 78px; - height: 100px; - background-color: black; - } - .action-bar-divider { - position: fixed; - bottom: 0px; - left: 78px; - width: 28px; - height: 100px; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAABkCAYAAACVfFA4AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3ggLDiUo1ElOKAAABHdJREFUaN612ktvE1cUB/Bz7bGdGcePJk1i4tA0DomCRJUQEGphAa3KQwGpUHWFYMEiIBZdtKgfADbdsekXaFW1XZUuQAiFh0BRi+iqap2EJrUSJSjg2I7Hk3GmdmwPi5Z4ziQEx57/XeXKUn6255w558y1ICKTUOvKverfpkl0/ahwEXKZ1c/iLhlERAQDu85etcrkX3mGBbPhPiIhXnkUyPyNBfO+1upGEIUyU1iQXG52LSd/HRNY0BIwPiNbfR8Iq+3CN5brZ5KiJrBgLrCT7cPpKSxYlPyWgBE0e/d7AQMHDh0nEhavVOSx5DRodA6zm6WSX8SC2dYBFjCvEh4GrsjtbB9MT2BB0+Vh++nx2wIG7jp2liW8VNQ23oAc/To79lavH5nkV+ewoBrqsVak9Rs2DCx4Q6xCfDbUKcHA/R+dsnydRKJSputfXyvDwHSgl1cIPbl51XLs+rXvYQnfnJ3BgprSyfah1AQWrLh9ZI2YxKNfBAzs//A0a2/da/nXdx5OgHpkH9sr2jwWVFv6eIVIT2HBVV8Lq/DB9CQWZP/GrNDTJw8FDIydHGUB4zXStb61OvOvY5BXiOUEFlSb3+EVYouAcQQsSTKrEHP3fxQwsP/gCdYSukqF7YRXHS1hlLeE8v8zIAzMtu62tYTTWDAvt7HrF0jFsaApJBahM7+NCRjYe+wcS3hPIbfde9I2W8LIEK8Q2QQWVEMxFjDB1CQWLHoCrEIs3P1OwMD/WkKLV16rp67UvpYCu1jCN+kvsKC9JfQvT2NBXdnB9rUkfEMgawkF0ez4TQEDe4+c4S1hMV9vM1Jjw7RjH3vapGwyAzoKqm/1sSmp+Q0VvmHQ8IVZwn85MuSFguwpYaVMX31+eQ0Gdo9cZDOgdzXdSAdbQ0sYGeQBk5nBgiuBnSxggqm/sGDJrbCAmX/0s4CBvQdPsIR3rRmNTiFvagmtM6BJsraABXMtA+xYwJ96igVXlTZbhZjAgqZLYl9p4vf7Agb2fHyOPyU0VCdG1y3yr3Mvr/A1toR1g1qwh+39S3EsWPTylnDxwQ8CBg7bW0LbsYDj4FKQt4Q+/TkW1Nre4+dIqSksqPt5SxhMxbFgxW09FhA09/iOgIGxw2fY9XMXdSefWW0yUkeHWYTK6iwW1MJ9tC6aJvlrnAHrBo0m/pTwxtVRFxQk6+8KKmU69P4BEwZ2j4w23BJuC1Q7hnjC284BHQd128FxczKOBcuSwhL+2fgNAQNjHxznLWHJIKfWpqDRxY8FmnILWFCzPSV0IuG3BPPK2yzho//OYUESHjYl/fHgloCB3UfPs4T3GMvk5NoA5iODvEJk/sGCWijGK8RSHAvaW8LnD38SUJDFTrlITi8GRj/5gr3oW1nEglo7bwnlOmfAmkFdiVjv1xRI/okFTclrHQFp/smYgIHvHv6U/5awoBFirYOr0WH2gpydxYK5cD+vEA4n/Aaw0BRiCZ+8962AgrwlLBFquYiIuk5ess2ASRgoERHp7XtIUGUdlTPTVACBLwEignyX5voIbgAAAABJRU5ErkJggg==); - } - .action-bar-back-button { - position: fixed; - bottom: 35px; - left: 34px; - width: 18px; - height: 28px; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAcCAYAAABsxO8nAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3ggLDh43ZfOs5QAAAvdJREFUOMuVlU9LMm0Uh6+ZRguUKaNoWbs0QVIMCb9CqQtb1UdI2lS0dBNhn6D2EVQQLaM2UZpTUknRwm3UooI2lTZ/9H42b/M+g2k+A/fmPjcXF+f8OAMg/vVEIhFRLBbF4+Oj0DRNjI2NCem/YsdfJBJhf38fWZbtu4eHBzoGSZJELBZjZ2cHSZKa6nKnkKmpKQ4ODgAQQjhOpVL53UiWZaanp9nY2EDX9ab6+/s76XS6vVFXVxepVIrNzc0fIU9PTySTSSqVCkoriKIozM7OksvlqNVqjpoQwoa8vb217pHL5SKTybC+vk61WnX0o9FocH9/TyKRsCFAs5Hb7SaTybC8vMzn56ej1mg0uL29ZWZmhnq93npqHo+HhYUFlpaW+Pj4sC0ALMuiUCiQTqebIA4jr9dLNptlbm7OYSJJEqZpcnx8zPz8fOuIAEJVVdbW1kilUo7GSpJErVbj8PCQxcXF9lnz+XxidXWVRCLRNJ1qtcr29ja5XO7X0MorKyskk8kmiCzLHB0ddQQBkF9eXnh9fUWSpKboK4rCwMBAR6CuYrGYdbvdBAIBuru77SkJIQiFQoyMjKBpGtVqtT0IyF5cXKAoCuFwGEX5P1qWZeH3+xkeHiafz/P19dUeBFAqlejr68Pv9+NyuWwz0zQJBAKoqkq5XG7qZRMI4OzsDFVVCQQCuFwu+5FhGExMTKCqKtfX1z/CHCCAQqGA1+tlfHzcHgCArutEo1E8Hg+lUgnDMNqDAM7PzxkcHMTv9yPLsg0zDINoNIosy9zd3TlWy48ggJOTE/r7+wkGg47Vapom8XgcRVG4ubmxzVqCAE5PT+nt7SUcDtNoNOx7XdeZnJwE4OrqCsuy2oMA8vk8Q0NDBINBxzYwDINYLMb3xH8FfZv5fD5CoZAN+s5ZPB5H07TOQEII8vk8qqoSjUaxLMu2M02T5+fnzn5HAPV6nVwux+7uLm63277v6emhXC53ZvT3qr28vMTn8zE6OgrA3t4eW1tb/AH4Zo+8fEoEngAAAABJRU5ErkJggg==); - } - .camera-cross-hairs { - position: fixed; - top: 50%; - left: 50%; - -webkit-transform: translate(-50%, -147px); - width: 194px; - height: 195px; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMIAAADDCAQAAAB6tAYfAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfeCAsPDxicOdibAAACbElEQVR42u3a7U7aYBgG4Oet0yZLTMx2bDu5nYo7nSUmzi34DUSe/bA0UHSDbpS5Xpc/sECNuW/a5yV5I4CI8toL03y31R94ipMy7gj/PKmNp7/lWSx27PEuzkZaxFWe7viJL3EdH8ovS5hnRkTu+K9UcVzGehX0u/WsXxNVt4LcuYLoccb/ok9WGRHzfKWEWS56xvkw2hLue1a3WKuh9L+wluqRD+bH7BdA6Q7qr59mOW1/LBr3Wdky5VlenK9dCattjv2TPdwwXy5oqu4iSQX7VpfsjPVq7OubQ1i8VMLFefndF2j24i7b1O/z6LWJzT4Wtp28K5EcnhKUgBKUgBKUgBKUgBKUgBKUgBKUgBKUgBLeSglP7eFMIgPo5t3Zd2TDyzCWe4/q1X1HPz5HREykM5BJyBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWhfn05zl95TEMC5zmrO8bPIuzw+zfD44LgIawjxzJe8qIuI2MzIyFnHnWhjATS6avG+zLaFqXz6W0ACO2t9OYj1/DkYJSkAJSkAJSkAJSkAJSkAJSkAJSkAJSkAJb6WE6y+COIzbiGh3WzxmaQ5P7LfYu4dc3oDq4nb0j8yA5ni50yWbHUjsz2bCTQmTlakwVcMeraZ73TyWzftUiYiMjO2Gw1O8H/kUuc+jrd6XUZpsY20ixGrSy+HceXoLN/FxpEVc5elO71+9ydTlxbT73oiq0e5hneei55l1eWVQ1z2jHO8Qyb9QwcZqqS6TPuve8a74e5wz2fiwl22m+C6tjnu9IyngTfsJ8D+4z5r15Y4AAAAASUVORK5CYII=); - } - </style> - <body> - <div id="camera"> - <video id="v"></video> - <div class="camera-cross-hairs"></div> - </div> - <canvas id="c" style="display: none;"></canvas> - <div class="action-bar"> - <div id="back" class="action-bar-back"> - <div class="action-bar-back-button"></div> - </div> - <div class="action-bar-divider"></div> - </div> - </body> -</html> diff --git a/www/blackberry10/assets/camera.js b/www/blackberry10/assets/camera.js deleted file mode 100644 index 2a272be..0000000 --- a/www/blackberry10/assets/camera.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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. - * - */ - -document.addEventListener('DOMContentLoaded', function () { - document.getElementById('back').onclick = function () { - window.qnx.callExtensionMethod('cordova-plugin-camera', 'cancel'); - }; - window.navigator.webkitGetUserMedia( - { video: true }, - function (stream) { - var video = document.getElementById('v'); - var canvas = document.getElementById('c'); - var camera = document.getElementById('camera'); - video.autoplay = true; - video.width = window.innerWidth; - video.height = window.innerHeight - 100; - video.src = window.webkitURL.createObjectURL(stream); - camera.onclick = function () { - canvas.width = video.videoWidth; - canvas.height = video.videoHeight; - canvas.getContext('2d').drawImage(video, 0, 0, video.videoWidth, video.videoHeight); - window.qnx.callExtensionMethod('cordova-plugin-camera', canvas.toDataURL('img/png')); - }; - }, - function () { - window.qnx.callExtensionMethod('cordova-plugin-camera', 'error', 'getUserMedia failed'); - } - ); -});