forked from public/cordova-plugin-camera
Compare commits
242 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19feee9cb0 | ||
|
|
69c687e0cf | ||
|
|
b0ee9dd905 | ||
|
|
c2e0db2b86 | ||
|
|
8f07f562a2 | ||
|
|
1e8c836844 | ||
|
|
b131021303 | ||
|
|
0dabe94416 | ||
|
|
fb8ce21711 | ||
|
|
b67e4a09ed | ||
|
|
d10bf50c61 | ||
|
|
b7af490a3e | ||
|
|
c2e4d1f36d | ||
|
|
d0fe66e1d5 | ||
|
|
af36e74d05 | ||
|
|
629dbcb712 | ||
|
|
bc7c4278ef | ||
|
|
302aacb214 | ||
|
|
3927735d09 | ||
|
|
9e11ab4dfb | ||
|
|
d1dfc1e8ee | ||
|
|
ee4ac0d7b2 | ||
|
|
d52b936bd8 | ||
|
|
9fe5b430aa | ||
|
|
23dbb8889a | ||
|
|
ac4af88f55 | ||
|
|
f1ae0e9ccf | ||
|
|
563f0038fd | ||
|
|
ccbbdccc4c | ||
|
|
04ed502d92 | ||
|
|
7209d38fa2 | ||
|
|
8062a006c0 | ||
|
|
29c9ea387d | ||
|
|
5ef04e552c | ||
|
|
b8a700215a | ||
|
|
081aec5602 | ||
|
|
9e4174caff | ||
|
|
7b2f453c25 | ||
|
|
00cd249dd7 | ||
|
|
b698e10386 | ||
|
|
2a93a48956 | ||
|
|
929733b891 | ||
|
|
f39a08ba29 | ||
|
|
bca73e6ee9 | ||
|
|
2c597a389b | ||
|
|
b780331389 | ||
|
|
57aa707c6a | ||
|
|
97514fb01e | ||
|
|
799ed580d3 | ||
|
|
d7e708db09 | ||
|
|
80b0048384 | ||
|
|
2ead6335c9 | ||
|
|
2a0735d551 | ||
|
|
4f056f0a73 | ||
|
|
376bec2b96 | ||
|
|
482f2ac2cc | ||
|
|
35c653d24d | ||
|
|
3ab650bdc9 | ||
|
|
2045e0a644 | ||
|
|
032531ae77 | ||
|
|
fb4cff9cc0 | ||
|
|
0d389857cf | ||
|
|
8b8db828f6 | ||
|
|
03fade661e | ||
|
|
c06ae46485 | ||
|
|
dbe33a44ff | ||
|
|
021743f20e | ||
|
|
53e42fc97b | ||
|
|
7413c1bcb2 | ||
|
|
860fedece4 | ||
|
|
9adc39ca2c | ||
|
|
af18483d69 | ||
|
|
3581c595d7 | ||
|
|
513bfde49e | ||
|
|
43cb385f0e | ||
|
|
45da410662 | ||
|
|
fcfe642147 | ||
|
|
05da230c2a | ||
|
|
986bf6fd3c | ||
|
|
d84b875c44 | ||
|
|
1ffb14d764 | ||
|
|
e851960910 | ||
|
|
ae22820046 | ||
|
|
fa30a56760 | ||
|
|
5c1394058c | ||
|
|
6dcfa9cf9b | ||
|
|
f3cfadb19e | ||
|
|
e9a834955c | ||
|
|
5b84c38a43 | ||
|
|
af566264ef | ||
|
|
a423e57c8a | ||
|
|
481ff27727 | ||
|
|
599ab31090 | ||
|
|
b3b43b1f3c | ||
|
|
b2403c6076 | ||
|
|
c8c3bf0782 | ||
|
|
f3bc296da8 | ||
|
|
938543c203 | ||
|
|
e316e32808 | ||
|
|
8e1e5c8550 | ||
|
|
d53a7770d9 | ||
|
|
42bf5d2983 | ||
|
|
9064130fce | ||
|
|
6366aeba47 | ||
|
|
823eb5d27a | ||
|
|
0d63ac27ca | ||
|
|
dbaa458b7f | ||
|
|
f2eebeed0a | ||
|
|
c696f6e0b3 | ||
|
|
45a50c448e | ||
|
|
e8cbb106ae | ||
|
|
10e0efc503 | ||
|
|
cb7e19311a | ||
|
|
9a26e97ac8 | ||
|
|
f8d5ef643e | ||
|
|
98749a611b | ||
|
|
08acf7bc49 | ||
|
|
e4ab155fd0 | ||
|
|
7305c64db0 | ||
|
|
f20703de20 | ||
|
|
543c4198d8 | ||
|
|
1650dce693 | ||
|
|
5b8324e984 | ||
|
|
4aa85de064 | ||
|
|
fa93b534d1 | ||
|
|
c1683000d2 | ||
|
|
1a495492c6 | ||
|
|
a07c85e8b4 | ||
|
|
06ecc91fd1 | ||
|
|
05e3eed60e | ||
|
|
ffd46c4ef5 | ||
|
|
1cf38cd775 | ||
|
|
4fa934e06f | ||
|
|
1f51a3b61d | ||
|
|
4bdb990b77 | ||
|
|
d00464e9d3 | ||
|
|
7b60a0b6d1 | ||
|
|
4c901d56be | ||
|
|
5af2653f18 | ||
|
|
9de98fcc0d | ||
|
|
68453f2492 | ||
|
|
61325f4620 | ||
|
|
8ff4d3f16e | ||
|
|
6e93ebbf90 | ||
|
|
8719cb7342 | ||
|
|
d5405ba2e0 | ||
|
|
8760c99b31 | ||
|
|
2eb71f648f | ||
|
|
199732845e | ||
|
|
707426ece2 | ||
|
|
10e5455356 | ||
|
|
30a75e3fa7 | ||
|
|
7e9f099301 | ||
|
|
9e0d943971 | ||
|
|
87a5030771 | ||
|
|
0c9de56da5 | ||
|
|
e8596fbc8e | ||
|
|
d899d7a4b8 | ||
|
|
c7d88e8b34 | ||
|
|
d6af2098c1 | ||
|
|
b76b5ae670 | ||
|
|
f2a41e4b5e | ||
|
|
85a986f589 | ||
|
|
4c2c567fd8 | ||
|
|
fe6dc72a75 | ||
|
|
ae2acd9ab2 | ||
|
|
f6e8548381 | ||
|
|
e7a3d70fe9 | ||
|
|
91d6e10b29 | ||
|
|
6fb63fede5 | ||
|
|
c9bab1f94c | ||
|
|
5393a28191 | ||
|
|
2d3f10ea3f | ||
|
|
2a7520112e | ||
|
|
552b806347 | ||
|
|
61a963d6fb | ||
|
|
3be1802c9e | ||
|
|
19a44608b8 | ||
|
|
3f995dd3de | ||
|
|
f1fb8d210e | ||
|
|
80205f41e3 | ||
|
|
92dd3eeee3 | ||
|
|
f3a704b59d | ||
|
|
4ae4414856 | ||
|
|
61ba9cca4b | ||
|
|
ab5c957434 | ||
|
|
031919be5b | ||
|
|
0fbddb8364 | ||
|
|
ab1281fb25 | ||
|
|
77f4683ca8 | ||
|
|
706a2efe20 | ||
|
|
ba278d2495 | ||
|
|
fc0678f970 | ||
|
|
464c37eb50 | ||
|
|
99dff47962 | ||
|
|
9b0d17ec85 | ||
|
|
76eb49da95 | ||
|
|
f9fa6ccedb | ||
|
|
39a5889c3b | ||
|
|
2d3997b2e7 | ||
|
|
e0f6d33876 | ||
|
|
ff03f474da | ||
|
|
bf105f9832 | ||
|
|
7574e66315 | ||
|
|
2437c40fe7 | ||
|
|
ccd59e66ba | ||
|
|
6f4fef8479 | ||
|
|
34e85810c8 | ||
|
|
0d94289921 | ||
|
|
3424ddb39c | ||
|
|
e8e420895e | ||
|
|
a6736cda71 | ||
|
|
885c6a7459 | ||
|
|
d8a3d2ff3a | ||
|
|
4590f2597c | ||
|
|
7c35f56a0d | ||
|
|
e0176cc61e | ||
|
|
b44ea1c69f | ||
|
|
703f6c68d8 | ||
|
|
4e6cf5cc2e | ||
|
|
eab4822ae9 | ||
|
|
a600de41eb | ||
|
|
fed4f2280d | ||
|
|
c42bfe881f | ||
|
|
200d6833f9 | ||
|
|
6a1a558e81 | ||
|
|
6a9949bb8c | ||
|
|
f5a521f5ea | ||
|
|
ed86de0d2a | ||
|
|
363d139653 | ||
|
|
809a23ffae | ||
|
|
3a3bbb1cc9 | ||
|
|
8077d302fe | ||
|
|
9bcf725e39 | ||
|
|
224e7cfb20 | ||
|
|
bc32c501da | ||
|
|
df028dd257 | ||
|
|
44517ea93f | ||
|
|
8c77ddb864 | ||
|
|
a9546c4f49 | ||
|
|
f33e00083a | ||
|
|
118ca18d5a |
13
.travis.yml
Normal file
13
.travis.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
language: objective-c
|
||||
git:
|
||||
depth: 2
|
||||
node_js:
|
||||
- "0.10"
|
||||
install:
|
||||
- echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
|
||||
- cd ..
|
||||
- npm install -g cordova-paramedic
|
||||
- npm install -g cordova
|
||||
- npm install -g ios-sim
|
||||
script:
|
||||
- cordova-paramedic --platform ios --plugin ${TRAVIS_BUILD_DIR}
|
||||
@@ -7,9 +7,9 @@
|
||||
# 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
|
||||
@@ -18,8 +18,20 @@
|
||||
# under the License.
|
||||
#
|
||||
-->
|
||||
# Release Notes
|
||||
|
||||
### 0.2.1 (Sept 5, 2013)
|
||||
* [CB-4656] Don't add line-breaks to base64-encoded images (Fixes type=DataURI)
|
||||
* [CB-4432] copyright notice change
|
||||
# Contributing to Apache Cordova
|
||||
|
||||
Anyone can contribute to Cordova. And we need your contributions.
|
||||
|
||||
There are multiple ways to contribute: report bugs, improve the docs, and
|
||||
contribute code.
|
||||
|
||||
For instructions on this, start with the
|
||||
[contribution overview](http://cordova.apache.org/#contribute).
|
||||
|
||||
The details are explained there, but the important items are:
|
||||
- Sign and submit an Apache ICLA (Contributor License Agreement).
|
||||
- Have a Jira issue open that corresponds to your contribution.
|
||||
- Run the tests so your patch doesn't break existing functionality.
|
||||
|
||||
We look forward to your contributions!
|
||||
5
NOTICE
Normal file
5
NOTICE
Normal file
@@ -0,0 +1,5 @@
|
||||
Apache Cordova
|
||||
Copyright 2012 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
461
README.md
461
README.md
@@ -1,5 +1,458 @@
|
||||
cordova-plugin-camera
|
||||
==========================
|
||||
To install this plugin, follow the [Command-line Interface Guide](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).
|
||||
<!---
|
||||
license: 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
|
||||
|
||||
If you are not using the Cordova Command-line Interface, follow [Using Plugman to Manage Plugins](http://cordova.apache.org/docs/en/edge/plugin_ref_plugman.md.html).
|
||||
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.
|
||||
-->
|
||||
|
||||
# cordova-plugin-camera
|
||||
|
||||
[](https://travis-ci.org/apache/cordova-plugin-camera)
|
||||
|
||||
This plugin defines a global `navigator.camera` object, which provides an API for taking pictures and for choosing images from
|
||||
the system's image library.
|
||||
|
||||
Although the object is attached to the global scoped `navigator`, it is not available until after the `deviceready` event.
|
||||
|
||||
document.addEventListener("deviceready", onDeviceReady, false);
|
||||
function onDeviceReady() {
|
||||
console.log(navigator.camera);
|
||||
}
|
||||
|
||||
## Installation
|
||||
|
||||
cordova plugin add cordova-plugin-camera
|
||||
|
||||
## navigator.camera.getPicture
|
||||
|
||||
Takes a photo using the camera, or retrieves a photo from the device's
|
||||
image gallery. The image is passed to the success callback as a
|
||||
base64-encoded `String`, or as the URI for the image file. The method
|
||||
itself returns a `CameraPopoverHandle` object that can be used to
|
||||
reposition the file selection popover.
|
||||
|
||||
navigator.camera.getPicture( cameraSuccess, cameraError, cameraOptions );
|
||||
|
||||
### Description
|
||||
|
||||
The `camera.getPicture` function opens the device's default camera
|
||||
application that allows users to snap pictures. This behavior occurs
|
||||
by default, when `Camera.sourceType` equals
|
||||
`Camera.PictureSourceType.CAMERA`. Once the user snaps the photo, the
|
||||
camera application closes and the application is restored.
|
||||
|
||||
If `Camera.sourceType` is `Camera.PictureSourceType.PHOTOLIBRARY` or
|
||||
`Camera.PictureSourceType.SAVEDPHOTOALBUM`, then a dialog displays
|
||||
that allows users to select an existing image. The
|
||||
`camera.getPicture` function returns a `CameraPopoverHandle` object,
|
||||
which can be used to reposition the image selection dialog, for
|
||||
example, when the device orientation changes.
|
||||
|
||||
The return value is sent to the `cameraSuccess` callback function, in
|
||||
one of the following formats, depending on the specified
|
||||
`cameraOptions`:
|
||||
|
||||
- A `String` containing the base64-encoded photo image.
|
||||
|
||||
- A `String` representing the image file location on local storage (default).
|
||||
|
||||
You can do whatever you want with the encoded image or URI, for
|
||||
example:
|
||||
|
||||
- Render the image in an `<img>` tag, as in the example below
|
||||
|
||||
- Save the data locally (`LocalStorage`, [Lawnchair](http://brianleroux.github.com/lawnchair/), etc.)
|
||||
|
||||
- Post the data to a remote server
|
||||
|
||||
__NOTE__: Photo resolution on newer devices is quite good. Photos
|
||||
selected from the device's gallery are not downscaled to a lower
|
||||
quality, even if a `quality` parameter is specified. To avoid common
|
||||
memory problems, set `Camera.destinationType` to `FILE_URI` rather
|
||||
than `DATA_URL`.
|
||||
|
||||
### Supported Platforms
|
||||
|
||||
- Amazon Fire OS
|
||||
- Android
|
||||
- BlackBerry 10
|
||||
- Browser
|
||||
- Firefox OS
|
||||
- iOS
|
||||
- Tizen
|
||||
- Windows Phone 7 and 8
|
||||
- Windows 8
|
||||
- Windows
|
||||
|
||||
### Preferences (iOS)
|
||||
|
||||
- __CameraUsesGeolocation__ (boolean, defaults to false). For capturing JPEGs, set to true to get geolocation data in the EXIF header. This will trigger a request for geolocation permissions if set to true.
|
||||
|
||||
<preference name="CameraUsesGeolocation" value="false" />
|
||||
|
||||
|
||||
### Amazon Fire OS Quirks
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
### Browser Quirks
|
||||
|
||||
Can only return photos as base64-encoded image.
|
||||
|
||||
### Firefox OS Quirks
|
||||
|
||||
Camera plugin is currently implemented using [Web Activities](https://hacks.mozilla.org/2013/01/introducing-web-activities/).
|
||||
|
||||
### iOS Quirks
|
||||
|
||||
Including a JavaScript `alert()` in either of the callback functions
|
||||
can cause problems. Wrap the alert within a `setTimeout()` to allow
|
||||
the iOS image picker or popover to fully close before the alert
|
||||
displays:
|
||||
|
||||
setTimeout(function() {
|
||||
// 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.
|
||||
|
||||
### Tizen Quirks
|
||||
|
||||
Tizen only supports a `destinationType` of
|
||||
`Camera.DestinationType.FILE_URI` and a `sourceType` of
|
||||
`Camera.PictureSourceType.PHOTOLIBRARY`.
|
||||
|
||||
### Example
|
||||
|
||||
Take a photo and retrieve it as a base64-encoded image:
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.DATA_URL
|
||||
});
|
||||
|
||||
function onSuccess(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
Take a photo and retrieve the image's file location:
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.FILE_URI });
|
||||
|
||||
function onSuccess(imageURI) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = imageURI;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
## CameraOptions
|
||||
|
||||
Optional parameters to customize the camera settings.
|
||||
|
||||
{ quality : 75,
|
||||
destinationType : Camera.DestinationType.DATA_URL,
|
||||
sourceType : Camera.PictureSourceType.CAMERA,
|
||||
allowEdit : true,
|
||||
encodingType: Camera.EncodingType.JPEG,
|
||||
targetWidth: 100,
|
||||
targetHeight: 100,
|
||||
popoverOptions: CameraPopoverOptions,
|
||||
saveToPhotoAlbum: false };
|
||||
|
||||
### Options
|
||||
|
||||
- __quality__: Quality of the saved image, expressed as a range of 0-100, where 100 is typically full resolution with no loss from file compression. The default is 50. _(Number)_ (Note that information about the camera's resolution is unavailable.)
|
||||
|
||||
- __destinationType__: Choose the format of the return value. The default is FILE_URI. Defined in `navigator.camera.DestinationType` _(Number)_
|
||||
|
||||
Camera.DestinationType = {
|
||||
DATA_URL : 0, // Return image as base64-encoded string
|
||||
FILE_URI : 1, // Return image file URI
|
||||
NATIVE_URI : 2 // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
|
||||
};
|
||||
|
||||
- __sourceType__: Set the source of the picture. The default is CAMERA. Defined in `navigator.camera.PictureSourceType` _(Number)_
|
||||
|
||||
Camera.PictureSourceType = {
|
||||
PHOTOLIBRARY : 0,
|
||||
CAMERA : 1,
|
||||
SAVEDPHOTOALBUM : 2
|
||||
};
|
||||
|
||||
- __allowEdit__: Allow simple editing of image before selection. _(Boolean)_
|
||||
|
||||
- __encodingType__: Choose the returned image file's encoding. Default is JPEG. Defined in `navigator.camera.EncodingType` _(Number)_
|
||||
|
||||
Camera.EncodingType = {
|
||||
JPEG : 0, // Return JPEG encoded image
|
||||
PNG : 1 // Return PNG encoded image
|
||||
};
|
||||
|
||||
- __targetWidth__: Width in pixels to scale image. Must be used with __targetHeight__. Aspect ratio remains constant. _(Number)_
|
||||
|
||||
- __targetHeight__: Height in pixels to scale image. Must be used with __targetWidth__. Aspect ratio remains constant. _(Number)_
|
||||
|
||||
- __mediaType__: Set the type of media to select from. Only works when `PictureSourceType` is `PHOTOLIBRARY` or `SAVEDPHOTOALBUM`. Defined in `nagivator.camera.MediaType` _(Number)_
|
||||
|
||||
Camera.MediaType = {
|
||||
PICTURE: 0, // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
|
||||
VIDEO: 1, // allow selection of video only, WILL ALWAYS RETURN FILE_URI
|
||||
ALLMEDIA : 2 // allow selection from all media types
|
||||
};
|
||||
|
||||
- __correctOrientation__: Rotate the image to correct for the orientation of the device during capture. _(Boolean)_
|
||||
|
||||
- __saveToPhotoAlbum__: Save the image to the photo album on the device after capture. _(Boolean)_
|
||||
|
||||
- __popoverOptions__: iOS-only options that specify popover location in iPad. Defined in `CameraPopoverOptions`.
|
||||
|
||||
- __cameraDirection__: Choose the camera to use (front- or back-facing). The default is BACK. Defined in `navigator.camera.Direction` _(Number)_
|
||||
|
||||
Camera.Direction = {
|
||||
BACK : 0, // Use the back-facing camera
|
||||
FRONT : 1 // Use the front-facing camera
|
||||
};
|
||||
|
||||
### 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
|
||||
|
||||
- Any `cameraDirection` value results in a back-facing photo.
|
||||
|
||||
- Android also uses the Crop Activity for allowEdit, even though crop should work and actually pass the cropped image back to Cordova, the only one that works consistently is the one bundled
|
||||
with the Google Plus Photos application. Other crops may not work.
|
||||
|
||||
- `Camera.PictureSourceType.PHOTOLIBRARY` and `Camera.PictureSourceType.SAVEDPHOTOALBUM` both display the same photo album.
|
||||
|
||||
### 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
|
||||
|
||||
- Set `quality` below 50 to avoid memory errors on some devices.
|
||||
|
||||
- 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.
|
||||
|
||||
### 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 wp7/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 a blocker for your application, you will need to implement the CameraCaptureTask as documented on msdn : [http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx](http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx)
|
||||
You may also comment or up-vote the related issue in the [issue tracker](https://issues.apache.org/jira/browse/CB-2083)
|
||||
|
||||
- Ignores the `mediaType` property of `cameraOptions` as the Windows Phone SDK does not provide a way to choose videos from PHOTOLIBRARY.
|
||||
|
||||
|
||||
## CameraError
|
||||
|
||||
onError callback function that provides an error message.
|
||||
|
||||
function(message) {
|
||||
// Show a helpful message
|
||||
}
|
||||
|
||||
### Parameters
|
||||
|
||||
- __message__: The message is provided by the device's native code. _(String)_
|
||||
|
||||
|
||||
## cameraSuccess
|
||||
|
||||
onSuccess callback function that provides the image data.
|
||||
|
||||
function(imageData) {
|
||||
// Do something with the image
|
||||
}
|
||||
|
||||
### Parameters
|
||||
|
||||
- __imageData__: Base64 encoding of the image data, _or_ the image file URI, depending on `cameraOptions` in effect. _(String)_
|
||||
|
||||
### Example
|
||||
|
||||
// Show image
|
||||
//
|
||||
function cameraCallback(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverHandle
|
||||
|
||||
A handle to the popover dialog created by `navigator.camera.getPicture`.
|
||||
|
||||
### Methods
|
||||
|
||||
- __setPosition__: Set the position of the popover.
|
||||
|
||||
### Supported Platforms
|
||||
|
||||
- iOS
|
||||
|
||||
### setPosition
|
||||
|
||||
Set the position of the popover.
|
||||
|
||||
__Parameters__:
|
||||
|
||||
- `cameraPopoverOptions`: the `CameraPopoverOptions` that specify the new position
|
||||
|
||||
### Example
|
||||
|
||||
var cameraPopoverHandle = navigator.camera.getPicture(onSuccess, onFail,
|
||||
{ destinationType: Camera.DestinationType.FILE_URI,
|
||||
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
|
||||
popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)
|
||||
});
|
||||
|
||||
// Reposition the popover if the orientation changes.
|
||||
window.onorientationchange = function() {
|
||||
var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
|
||||
cameraPopoverHandle.setPosition(cameraPopoverOptions);
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverOptions
|
||||
|
||||
iOS-only parameters that specify the anchor element location and arrow
|
||||
direction of the popover when selecting images from an iPad's library
|
||||
or album.
|
||||
|
||||
{ x : 0,
|
||||
y : 32,
|
||||
width : 320,
|
||||
height : 480,
|
||||
arrowDir : Camera.PopoverArrowDirection.ARROW_ANY
|
||||
};
|
||||
|
||||
### CameraPopoverOptions
|
||||
|
||||
- __x__: x pixel coordinate of screen element onto which to anchor the popover. _(Number)_
|
||||
|
||||
- __y__: y pixel coordinate of screen element onto which to anchor the popover. _(Number)_
|
||||
|
||||
- __width__: width, in pixels, of the screen element onto which to anchor the popover. _(Number)_
|
||||
|
||||
- __height__: height, in pixels, of the screen element onto which to anchor the popover. _(Number)_
|
||||
|
||||
- __arrowDir__: Direction the arrow on the popover should point. Defined in `Camera.PopoverArrowDirection` _(Number)_
|
||||
|
||||
Camera.PopoverArrowDirection = {
|
||||
ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants
|
||||
ARROW_DOWN : 2,
|
||||
ARROW_LEFT : 4,
|
||||
ARROW_RIGHT : 8,
|
||||
ARROW_ANY : 15
|
||||
};
|
||||
|
||||
Note that the size of the popover may change to adjust to the
|
||||
direction of the arrow and orientation of the screen. Make sure to
|
||||
account for orientation changes when specifying the anchor element
|
||||
location.
|
||||
|
||||
## navigator.camera.cleanup
|
||||
|
||||
Removes intermediate photos taken by the camera from temporary
|
||||
storage.
|
||||
|
||||
navigator.camera.cleanup( cameraSuccess, cameraError );
|
||||
|
||||
### Description
|
||||
|
||||
Removes intermediate image files that are kept in temporary storage
|
||||
after calling `camera.getPicture`. Applies only when the value of
|
||||
`Camera.sourceType` equals `Camera.PictureSourceType.CAMERA` and the
|
||||
`Camera.destinationType` equals `Camera.DestinationType.FILE_URI`.
|
||||
|
||||
### Supported Platforms
|
||||
|
||||
- iOS
|
||||
|
||||
### Example
|
||||
|
||||
navigator.camera.cleanup(onSuccess, onFail);
|
||||
|
||||
function onSuccess() {
|
||||
console.log("Camera cleanup success.")
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
208
RELEASENOTES.md
Normal file
208
RELEASENOTES.md
Normal file
@@ -0,0 +1,208 @@
|
||||
<!--
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
-->
|
||||
# Release Notes
|
||||
|
||||
### 0.2.1 (Sept 5, 2013)
|
||||
* [CB-4656] Don't add line-breaks to base64-encoded images (Fixes type=DataURI)
|
||||
* [CB-4432] copyright notice change
|
||||
|
||||
### 0.2.3 (Sept 25, 2013)
|
||||
* CB-4889 bumping&resetting version
|
||||
* CB-4889 forgot index.html
|
||||
* CB-4889 renaming core inside cameraProxy
|
||||
* [Windows8] commandProxy has moved
|
||||
* [Windows8] commandProxy has moved
|
||||
* added Camera API for FirefoxOS
|
||||
* Rename CHANGELOG.md -> RELEASENOTES.md
|
||||
* [CB-4823] Fix XCode 5 camera plugin warnings
|
||||
* Fix compiler warnings
|
||||
* [CB-4765] Move ExifHelper.java into Camera Plugin
|
||||
* [CB-4764] Remove reference to DirectoryManager from CameraLauncher
|
||||
* [CB-4763] Use a copy of FileHelper.java within camera-plugin.
|
||||
* [CB-4752] Incremented plugin version on dev branch.
|
||||
* CB-4633: We really should close cursors. It's just the right thing to do.
|
||||
* No longer causes a stack trace, but it doesn't cause the error to be called.
|
||||
* CB-4889 renaming org.apache.cordova.core.camera to org.apache.cordova.camera
|
||||
|
||||
### 0.2.4 (Oct 28, 2013)
|
||||
* CB-5128: added repo + issue tag to plugin.xml for camera plugin
|
||||
* CB-4958 - iOS - Camera plugin should not show the status bar
|
||||
* [CB-4919] updated plugin.xml for FxOS
|
||||
* [CB-4915] Incremented plugin version on dev branch.
|
||||
|
||||
### 0.2.5 (Dec 4, 2013)
|
||||
* fix camera for firefox os
|
||||
* getPicture via web activities
|
||||
* [ubuntu] specify policy_group
|
||||
* add ubuntu platform
|
||||
* 1. User Agent detection now detects AmazonWebView. 2. Change to use amazon-fireos as the platform if user agent string contains 'cordova-amazon-fireos'
|
||||
* Added amazon-fireos platform.
|
||||
|
||||
### 0.2.6 (Jan 02, 2014)
|
||||
* CB-5658 Add doc/index.md for Camera plugin
|
||||
* CB-2442 CB-2419 Use Windows.Storage.ApplicationData.current.localFolder, instead of writing to app package.
|
||||
* [BlackBerry10] Adding platform level permissions
|
||||
* CB-5599 Android: Catch and ignore OutOfMemoryError in getRotatedBitmap()
|
||||
|
||||
### 0.2.7 (Feb 05, 2014)
|
||||
* CB-4919 firefox os quirks added and supported platforms list is updated
|
||||
* getPicture via web activities
|
||||
* Documented quirk for CB-5335 + CB-5206 for WP7+8
|
||||
* reference the correct firefoxos implementation
|
||||
* [BlackBerry10] Add permission to access_shared
|
||||
|
||||
### 0.2.8 (Feb 26, 2014)
|
||||
* CB-1826 Catch OOM on gallery image resize
|
||||
|
||||
### 0.2.9 (Apr 17, 2014)
|
||||
* CB-6460: Update license headers
|
||||
* CB-6422: [windows8] use cordova/exec/proxy
|
||||
* [WP8] When only targetWidth or targetHeight is provided, use it as the only bound
|
||||
* CB-4027, CB-5102, CB-2737, CB-2387: [WP] Fix camera issues, cropping, memory leaks
|
||||
* CB-6212: [iOS] fix warnings compiled under arm64 64-bit
|
||||
* [BlackBerry10] Add rim xml namespaces declaration
|
||||
* Add NOTICE file
|
||||
|
||||
### 0.3.0 (Jun 05, 2014)
|
||||
* CB-2083 documented saveToPhotoAlbum quirk on WP8
|
||||
* CB-5895 documented saveToPhotoAlbum quirk on WP8
|
||||
* Remove deprecated symbols for iOS < 6
|
||||
* documentation translation: cordova-plugin-camera
|
||||
* Lisa testing pulling in plugins for plugin: cordova-plugin-camera
|
||||
* Lisa testing pulling in plugins for plugin: cordova-plugin-camera
|
||||
* Lisa testing pulling in plugins for plugin: cordova-plugin-camera
|
||||
* Lisa testing pulling in plugins for plugin: cordova-plugin-camera
|
||||
* ubuntu: use application directory for images
|
||||
* CB-6795 Add license
|
||||
* Little fix in code formatting
|
||||
* CB-6613 Use WinJS functionality to get base64-encoded content of image instead of File plugin functionality
|
||||
* CB-6612 camera.getPicture now always returns encoded JPEG image
|
||||
* Removed invalid note from CB-5398
|
||||
* CB-6576 - Returns a specific error message when app has no access to library.
|
||||
* CB-6491 add CONTRIBUTING.md
|
||||
* CB-6546 android: Fix a couple bugs with allowEdit pull request
|
||||
* CB-6546 android: Add support for allowEdit Camera option
|
||||
|
||||
### 0.3.1 (Aug 06, 2014)
|
||||
* **FFOS** update CameraProxy.js
|
||||
* CB-7187 ios: Add explicit dependency on CoreLocation.framework
|
||||
* [BlackBerry10] Doc correction - sourceType is supported
|
||||
* CB-7071 android: Fix callback firing before CROP intent is sent when allowEdit=true
|
||||
* CB-6875 android: Handle exception when SDCard is not mounted
|
||||
* ios: Delete postImage (dead code)
|
||||
* Prevent NPE on processResiultFromGallery when intent comes null
|
||||
* Remove iOS doc reference to non-existing navigator.fileMgr API
|
||||
* Docs updated with some default values
|
||||
* Removes File plugin dependency from windows8 code.
|
||||
* Use WinJS functionality to resize image instead of File plugin functionality
|
||||
* CB-6127 Updated translations for docs
|
||||
|
||||
### 0.3.2 (Sep 17, 2014)
|
||||
* CB-7551 [Camera][iOS 8] Scaled images show a white line
|
||||
* CB-7558 hasPendingOperation flag in Camera plugin's takePicture should be reversed to fix memory errors
|
||||
* CB-7557 Camera plugin tests is missing a File dependency
|
||||
* CB-7423 do cleanup after copyImage manual test
|
||||
* CB-7471 cordova-plugin-camera documentation translation: cordova-plugin-camera
|
||||
* CB-7413 Resolve 'ms-appdata' URIs with File plugin
|
||||
* Fixed minor bugs with the browser
|
||||
* CB-7433 Adds missing window reference to prevent manual tests failure on Android and iOS
|
||||
* CB-7249 cordova-plugin-camera documentation translation: cordova-plugin-camera
|
||||
* CB-4003 Add config option to not use location information in Camera plugin (and default to not use it)
|
||||
* CB-7461 Geolocation fails in Camera plugin in iOS 8
|
||||
* CB-7378 Use single Proxy for both windows8 and windows.
|
||||
* CB-7378 Adds support for windows platform
|
||||
* CB-7433 Fixes manual tests failure on windows
|
||||
* CB-6958 Get the correct default for "quality" in the test
|
||||
* add documentation for manual tests
|
||||
* CB-7249 cordova-plugin-camera documentation translation: cordova-plugin-camera
|
||||
* CB-4003 Add config option to not use location information in Camera plugin (and default to not use it)
|
||||
* CB-7461 Geolocation fails in Camera plugin in iOS 8
|
||||
* CB-7433 Fixes manual tests failure on windows
|
||||
* CB-7378 Use single Proxy for both windows8 and windows.
|
||||
* CB-7378 Adds support for windows platform
|
||||
* CB-6958 Get the correct default for "quality" in the test
|
||||
* add documentation for manual tests
|
||||
* Updated docs for browser
|
||||
* Added support for the browser
|
||||
* CB-7286 [BlackBerry10] Use getUserMedia if camera card is unavailable
|
||||
* CB-7180 Update Camera plugin to support generic plugin webView UIView (which can be either a UIWebView or WKWebView)
|
||||
* Renamed test dir, added nested plugin.xml
|
||||
* CB-6958 added manual tests
|
||||
* CB-6958 Port camera tests to plugin-test-framework
|
||||
|
||||
### 0.3.3 (Oct 03, 2014)
|
||||
* CB-7600 Adds informative message to error callback in manual test.
|
||||
|
||||
### 0.3.4 (Dec 02, 2014)
|
||||
* CB-7977 Mention `deviceready` in plugin docs
|
||||
* CB-7979 Each plugin doc should have a ## Installation section
|
||||
* Fix memory leak of image data in `imagePickerControllerReturnImageResult`
|
||||
* Pass uri to crop instead of pulling the low resolution image out of the intent return (close #43)
|
||||
* Add orientation support for PNG to Android (closes #45)
|
||||
* CB-7700 cordova-plugin-camera documentation translation: cordova-plugin-camera
|
||||
|
||||
### 0.3.5 (Feb 04, 2015)
|
||||
* CB-8351 ios: Stop using now-deprecated [NSData base64EncodedString]
|
||||
* CB-8351 ios: Stop using now-deprecated integerValueForKey: class extension
|
||||
* CB-8351 ios: Use argumentForIndex rather than NSArray extension
|
||||
* CB-8032 ios: Add nativeURL external method support for CDVFileSystem->makeEntryForPath:isDirectory:
|
||||
* CB-7938 ios: Added XCTest unit tests project, with stubs (adapted from SplashScreen unit test setup)
|
||||
* CB-7937 ios: Re-factor iOS Camera plugin so that it is testable
|
||||
|
||||
### 0.3.6 (Mar 10, 2015)
|
||||
* Fix localize key for Videos. This closes #58
|
||||
* CB-8235 android: Fix crash when selecting images from DropBox with spaces in path (close #65)
|
||||
* add try ... catch for getting image orientation
|
||||
* CB-8599 fix threading issue with cameraPicker (fixes #72)
|
||||
* CB-8559 Integrate TravisCI
|
||||
* CB-8438 cordova-plugin-camera documentation translation: cordova-plugin-camera
|
||||
* CB-8538 Added package.json file
|
||||
|
||||
### 1.0.0 (Apr 15, 2015)
|
||||
* CB-8780 - Display popover using main thread. Fixes popover slowness (closes #81)
|
||||
* CB-8746 bumped version of file dependency
|
||||
* CB-8746 gave plugin major version bump
|
||||
* CB-8707 refactoring windows code to improve readability
|
||||
* CB-8706 use filePicker if saveToPhotoAlbum is true
|
||||
* CB-8706 remove unnecessary capabilities from xml
|
||||
* CB-8747 updated dependency, added peer dependency
|
||||
* CB-8683 updated blackberry specific references of org.apache.cordova.camera to cordova-plugin-camera
|
||||
* CB-8782: Updated the docs to talk about the allowEdit quirks, it's not 100% working, but better than it was
|
||||
* CB-8782: Fixed the flow so that we save the cropped image and use it, not the original non-cropped. Crop only supports G+ Photos Crop, other crops may not work, depending on the OEM
|
||||
* CB-8740: Removing FileHelper call that was failing on Samsung Galaxy S3, now that we have a real path, we only need to update the MediaStore, not pull from it in this case
|
||||
* CB-8740: Partial fix for Save Image to Gallery error found in MobileSpec
|
||||
* CB-8683 changed plugin-id to pacakge-name
|
||||
* CB-8653 properly updated translated docs to use new id
|
||||
* CB-8653 updated translated docs to use new id
|
||||
* CB-8351 Fix custom implementation of integerValueForKey (close #79)
|
||||
* Fix cordova-paramedic path change, build with TRAVIS_BUILD_DIR, use npm to install paramedic
|
||||
* docs: added 'Windows' to supported platforms
|
||||
* CB-8653 Updated Readme
|
||||
* CB-8659: ios: 4.0.x Compatibility: Remove use of deprecated headers
|
||||
|
||||
### 1.1.0 (May 06, 2015)
|
||||
* CB-8943 fix `PickAndContinue` issue on *Win10Phone*
|
||||
* CB-8253 Fix potential unreleased resources
|
||||
* CB-8909: Remove unused import from File
|
||||
* CB-8404 typo fix `cameraproxy.js`
|
||||
* CB-8404 Rotate camera feed with device orientation
|
||||
* CB-8054 Support taking pictures from file for *WP8*
|
||||
* CB-8405 Use `z-index` instead of `z-order`
|
||||
434
doc/de/index.md
Normal file
434
doc/de/index.md
Normal file
@@ -0,0 +1,434 @@
|
||||
<!---
|
||||
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.
|
||||
-->
|
||||
|
||||
# cordova-plugin-camera
|
||||
|
||||
Dieses Plugin definiert eine globale `navigator.camera`-Objekt, das eine API für Aufnahmen und für die Auswahl der Bilder aus dem System-Image-Library bietet.
|
||||
|
||||
Obwohl das Objekt mit der globalen Gültigkeitsbereich `navigator` verbunden ist, steht es nicht bis nach dem `Deviceready`-Ereignis.
|
||||
|
||||
document.addEventListener("deviceready", onDeviceReady, false);
|
||||
function onDeviceReady() {
|
||||
console.log(navigator.camera);
|
||||
}
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
cordova plugin add cordova-plugin-camera
|
||||
|
||||
|
||||
## navigator.camera.getPicture
|
||||
|
||||
Nimmt ein Foto mit der Kamera, oder ein Foto aus dem Gerät Bildergalerie abgerufen. Das Bild wird an den Erfolg-Rückruf als base64-codierte `String` oder als URI für die Image-Datei übergeben. Die Methode selbst gibt ein `CameraPopoverHandle`-Objekt, das verwendet werden kann, um die Datei-Auswahl-Popover neu zu positionieren.
|
||||
|
||||
navigator.camera.getPicture( cameraSuccess, cameraError, cameraOptions );
|
||||
|
||||
|
||||
### Beschreibung
|
||||
|
||||
Die `camera.getPicture`-Funktion öffnet das Gerät Standard-Kamera-Anwendung, die Benutzern ermöglicht, Bilder ausrichten. Dieses Verhalten tritt in der Standardeinstellung, wenn `Camera.sourceType` `Camera.PictureSourceType.CAMERA` entspricht. Sobald der Benutzer die Fotoschnäpper, die Kameraanwendung geschlossen wird und die Anwendung wird wiederhergestellt.
|
||||
|
||||
Wenn `Camera.sourceType` `Camera.PictureSourceType.PHOTOLIBRARY` oder `Camera.PictureSourceType.SAVEDPHOTOALBUM` ist, dann wird ein Dialogfeld angezeigt, das Benutzern ermöglicht, ein vorhandenes Bild auszuwählen. Die `camera.getPicture`-Funktion gibt ein `CameraPopoverHandle`-Objekt, das verwendet werden kann, um die Bild-Auswahl-Dialog, z. B. beim ändert sich der Orientierung des Geräts neu positionieren.
|
||||
|
||||
Der Rückgabewert wird an die `cameraSuccess`-Callback-Funktion in einem der folgenden Formate, je nach dem angegebenen `cameraOptions` gesendet:
|
||||
|
||||
* A `String` mit dem base64-codierte Foto-Bild.
|
||||
|
||||
* A `String` , die die Bild-Datei-Stelle auf lokalem Speicher (Standard).
|
||||
|
||||
Sie können tun, was Sie wollen, mit dem codierten Bildes oder URI, zum Beispiel:
|
||||
|
||||
* Rendern Sie das Bild in ein `<img>` Tag, wie im folgenden Beispiel
|
||||
|
||||
* Die Daten lokal zu speichern ( `LocalStorage` , [Lawnchair][1], etc..)
|
||||
|
||||
* Post die Daten an einen entfernten server
|
||||
|
||||
[1]: http://brianleroux.github.com/lawnchair/
|
||||
|
||||
**Hinweis**: Fotoauflösung auf neueren Geräten ist ganz gut. Fotos aus dem Gerät Galerie ausgewählt sind nicht zu einer niedrigeren Qualität herunterskaliert, selbst wenn ein `Qualität`-Parameter angegeben wird. Um Speicherprobleme zu vermeiden, legen Sie `Camera.destinationType` auf `FILE_URI` statt `DATA_URL`.
|
||||
|
||||
### Unterstützte Plattformen
|
||||
|
||||
* Amazon Fire OS
|
||||
* Android
|
||||
* BlackBerry 10
|
||||
* Browser
|
||||
* Firefox OS
|
||||
* iOS
|
||||
* Tizen
|
||||
* Windows Phone 7 und 8
|
||||
* Windows 8
|
||||
|
||||
### "Einstellungen" (iOS)
|
||||
|
||||
* **CameraUsesGeolocation** (Boolean, Standardwert ist False). Zur Erfassung von JPEGs, auf true festgelegt, um Geolocation-Daten im EXIF-Header zu erhalten. Dies löst einen Antrag auf Geolocation-Berechtigungen, wenn auf True festgelegt.
|
||||
|
||||
<preference name="CameraUsesGeolocation" value="false" />
|
||||
|
||||
|
||||
### Amazon Fire OS Macken
|
||||
|
||||
Amazon Fire OS verwendet Absichten zum Starten von der Kamera-Aktivität auf dem Gerät, um Bilder zu erfassen und auf Handys mit wenig Speicher, Cordova Tätigkeit getötet werden kann. In diesem Szenario kann das Bild nicht angezeigt, wenn die Aktivität von Cordova wiederhergestellt wird.
|
||||
|
||||
### Android Eigenarten
|
||||
|
||||
Android verwendet Absichten zum Starten von der Kamera-Aktivität auf dem Gerät, um Bilder zu erfassen und auf Handys mit wenig Speicher, Cordova Tätigkeit getötet werden kann. In diesem Szenario kann das Bild nicht angezeigt, wenn die Aktivität von Cordova wiederhergestellt wird.
|
||||
|
||||
### Browser-Eigenheiten
|
||||
|
||||
Fotos können nur als base64-codierte Bild zurückgeben werden.
|
||||
|
||||
### Firefox OS Macken
|
||||
|
||||
Kamera-Plugin ist derzeit implementiert mithilfe von [Web-Aktivitäten][2].
|
||||
|
||||
[2]: https://hacks.mozilla.org/2013/01/introducing-web-activities/
|
||||
|
||||
### iOS Macken
|
||||
|
||||
Einschließlich einer JavaScript-`alert()` entweder Rückruffunktionen kann Probleme verursachen. Wickeln Sie die Warnung innerhalb eine `setTimeout()` erlauben die iOS-Bild-Picker oder Popover vollständig zu schließen, bevor die Warnung angezeigt:
|
||||
|
||||
setTimeout(function() {
|
||||
// do your thing here!
|
||||
}, 0);
|
||||
|
||||
|
||||
### Windows Phone 7 Macken
|
||||
|
||||
Die native Kameraanwendung aufrufen, während das Gerät via Zune angeschlossen ist funktioniert nicht und löst eine Fehler-Callback.
|
||||
|
||||
### Tizen Macken
|
||||
|
||||
Tizen unterstützt nur ein `DestinationType` von `Camera.DestinationType.FILE_URI` und ein `SourceType` von `Camera.PictureSourceType.PHOTOLIBRARY`.
|
||||
|
||||
### Beispiel
|
||||
|
||||
Nehmen Sie ein Foto und rufen Sie sie als base64-codierte Bild:
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.DATA_URL
|
||||
});
|
||||
|
||||
function onSuccess(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
|
||||
Nehmen Sie ein Foto und rufen Sie das Bild-Datei-Speicherort:
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.FILE_URI });
|
||||
|
||||
function onSuccess(imageURI) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = imageURI;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
|
||||
## CameraOptions
|
||||
|
||||
Optionale Parameter die Kameraeinstellungen anpassen.
|
||||
|
||||
{ quality : 75,
|
||||
destinationType : Camera.DestinationType.DATA_URL,
|
||||
sourceType : Camera.PictureSourceType.CAMERA,
|
||||
allowEdit : true,
|
||||
encodingType: Camera.EncodingType.JPEG,
|
||||
targetWidth: 100,
|
||||
targetHeight: 100,
|
||||
popoverOptions: CameraPopoverOptions,
|
||||
saveToPhotoAlbum: false };
|
||||
|
||||
|
||||
### Optionen
|
||||
|
||||
* **Qualität**: Qualität des gespeicherten Bildes, ausgedrückt als ein Bereich von 0-100, wo 100 in der Regel voller Auflösung ohne Verlust aus der Dateikomprimierung ist. Der Standardwert ist 50. *(Anzahl)* (Beachten Sie, dass Informationen über die Kamera Auflösung nicht verfügbar ist.)
|
||||
|
||||
* **DestinationType**: Wählen Sie das Format des Rückgabewerts. Der Standardwert ist FILE_URI. Im Sinne `navigator.camera.DestinationType` *(Anzahl)*
|
||||
|
||||
Camera.DestinationType = {
|
||||
DATA_URL : 0, // Return image as base64-encoded string
|
||||
FILE_URI : 1, // Return image file URI
|
||||
NATIVE_URI : 2 // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
|
||||
};
|
||||
|
||||
|
||||
* **SourceType**: Legen Sie die Quelle des Bildes. Der Standardwert ist die Kamera. Im Sinne `navigator.camera.PictureSourceType` *(Anzahl)*
|
||||
|
||||
Camera.PictureSourceType = {
|
||||
PHOTOLIBRARY : 0,
|
||||
CAMERA : 1,
|
||||
SAVEDPHOTOALBUM : 2
|
||||
};
|
||||
|
||||
|
||||
* **AllowEdit**: einfache Bearbeitung des Bildes vor Auswahl zu ermöglichen. *(Boolesch)*
|
||||
|
||||
* **EncodingType**: die zurückgegebene Image-Datei ist Codierung auswählen. Standardwert ist JPEG. Im Sinne `navigator.camera.EncodingType` *(Anzahl)*
|
||||
|
||||
Camera.EncodingType = {
|
||||
JPEG : 0, // Return JPEG encoded image
|
||||
PNG : 1 // Return PNG encoded image
|
||||
};
|
||||
|
||||
|
||||
* **TargetWidth**: Breite in Pixel zum Bild skalieren. Muss mit **TargetHeight**verwendet werden. Seitenverhältnis bleibt konstant. *(Anzahl)*
|
||||
|
||||
* **TargetHeight**: Höhe in Pixel zum Bild skalieren. Muss mit **TargetWidth**verwendet werden. Seitenverhältnis bleibt konstant. *(Anzahl)*
|
||||
|
||||
* **MediaType**: Legen Sie den Typ der Medien zur Auswahl. Funktioniert nur, wenn `PictureSourceType` ist `PHOTOLIBRARY` oder `SAVEDPHOTOALBUM` . Im Sinne `nagivator.camera.MediaType` *(Anzahl)*
|
||||
|
||||
Camera.MediaType = {
|
||||
PICTURE: 0, // allow selection of still pictures only. STANDARD. Will return format specified via DestinationType
|
||||
VIDEO: 1, // allow selection of video only, WILL ALWAYS RETURN FILE_URI
|
||||
ALLMEDIA : 2 // allow selection from all media types
|
||||
};
|
||||
|
||||
|
||||
* **CorrectOrientation**: Drehen Sie das Bild um die Ausrichtung des Geräts während der Aufnahme zu korrigieren. *(Boolesch)*
|
||||
|
||||
* **SaveToPhotoAlbum**: das Bild auf das Fotoalbum auf dem Gerät zu speichern, nach Einnahme. *(Boolesch)*
|
||||
|
||||
* **PopoverOptions**: iOS-nur Optionen, die Popover Lage in iPad angeben. In definierten`CameraPopoverOptions`.
|
||||
|
||||
* **CameraDirection**: Wählen Sie die Kamera (vorn oder hinten-gerichtete) verwenden. Der Standardwert ist zurück. Im Sinne `navigator.camera.Direction` *(Anzahl)*
|
||||
|
||||
Camera.Direction = {
|
||||
BACK : 0, // Use the back-facing camera
|
||||
FRONT : 1 // Use the front-facing camera
|
||||
};
|
||||
|
||||
|
||||
### Amazon Fire OS Macken
|
||||
|
||||
* `cameraDirection`Ergebnisse in einem hinten gerichteter Foto Wert.
|
||||
|
||||
* Ignoriert die `allowEdit` Parameter.
|
||||
|
||||
* `Camera.PictureSourceType.PHOTOLIBRARY`und `Camera.PictureSourceType.SAVEDPHOTOALBUM` beide das gleiche Fotoalbum anzuzeigen.
|
||||
|
||||
### Android Eigenarten
|
||||
|
||||
* `cameraDirection`Ergebnisse in einem hinten gerichteter Foto Wert.
|
||||
|
||||
* Ignoriert die `allowEdit` Parameter.
|
||||
|
||||
* `Camera.PictureSourceType.PHOTOLIBRARY`und `Camera.PictureSourceType.SAVEDPHOTOALBUM` beide das gleiche Fotoalbum anzuzeigen.
|
||||
|
||||
### BlackBerry 10 Macken
|
||||
|
||||
* Ignoriert die `quality` Parameter.
|
||||
|
||||
* Ignoriert die `allowEdit` Parameter.
|
||||
|
||||
* `Camera.MediaType`wird nicht unterstützt.
|
||||
|
||||
* Ignoriert die `correctOrientation` Parameter.
|
||||
|
||||
* Ignoriert die `cameraDirection` Parameter.
|
||||
|
||||
### Firefox OS Macken
|
||||
|
||||
* Ignoriert die `quality` Parameter.
|
||||
|
||||
* `Camera.DestinationType`wird ignoriert, und gleich `1` (Bilddatei-URI)
|
||||
|
||||
* Ignoriert die `allowEdit` Parameter.
|
||||
|
||||
* Ignoriert die `PictureSourceType` Parameter (Benutzer wählt es in einem Dialogfenster)
|
||||
|
||||
* Ignoriert die`encodingType`
|
||||
|
||||
* Ignoriert die `targetWidth` und`targetHeight`
|
||||
|
||||
* `Camera.MediaType`wird nicht unterstützt.
|
||||
|
||||
* Ignoriert die `correctOrientation` Parameter.
|
||||
|
||||
* Ignoriert die `cameraDirection` Parameter.
|
||||
|
||||
### iOS Macken
|
||||
|
||||
* Legen Sie `quality` unter 50 Speicherfehler auf einigen Geräten zu vermeiden.
|
||||
|
||||
* Bei der Verwendung `destinationType.FILE_URI` , Fotos werden im temporären Verzeichnis der Anwendung gespeichert. Den Inhalt des temporären Verzeichnis der Anwendung wird gelöscht, wenn die Anwendung beendet.
|
||||
|
||||
### Tizen Macken
|
||||
|
||||
* nicht unterstützte Optionen
|
||||
|
||||
* gibt immer einen Datei-URI
|
||||
|
||||
### Windows Phone 7 und 8 Eigenarten
|
||||
|
||||
* Ignoriert die `allowEdit` Parameter.
|
||||
|
||||
* Ignoriert die `correctOrientation` Parameter.
|
||||
|
||||
* Ignoriert die `cameraDirection` Parameter.
|
||||
|
||||
* Ignoriert die `saveToPhotoAlbum` Parameter. WICHTIG: Alle Aufnahmen die wp7/8 Cordova-Kamera-API werden immer in Kamerarolle des Telefons kopiert. Abhängig von den Einstellungen des Benutzers könnte dies auch bedeuten, dass das Bild in ihre OneDrive automatisch hochgeladen ist. Dies könnte möglicherweise bedeuten, dass das Bild für ein breiteres Publikum als Ihre Anwendung vorgesehen ist. Wenn diese einen Blocker für Ihre Anwendung, Sie müssen die CameraCaptureTask zu implementieren, wie im Msdn dokumentiert: <http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx> Sie können kommentieren oder Up-Abstimmung das Beiträge zu diesem Thema im [Bugtracker][3]
|
||||
|
||||
* Ignoriert die `mediaType` -Eigenschaft des `cameraOptions` wie das Windows Phone SDK keine Möglichkeit, Fotothek Videos wählen.
|
||||
|
||||
[3]: https://issues.apache.org/jira/browse/CB-2083
|
||||
|
||||
## CameraError
|
||||
|
||||
onError-Callback-Funktion, die eine Fehlermeldung bereitstellt.
|
||||
|
||||
function(message) {
|
||||
// Show a helpful message
|
||||
}
|
||||
|
||||
|
||||
### Parameter
|
||||
|
||||
* **Meldung**: die Nachricht wird durch das Gerät systemeigenen Code bereitgestellt. *(String)*
|
||||
|
||||
## cameraSuccess
|
||||
|
||||
onSuccess Callback-Funktion, die die Bilddaten bereitstellt.
|
||||
|
||||
function(imageData) {
|
||||
// Do something with the image
|
||||
}
|
||||
|
||||
|
||||
### Parameter
|
||||
|
||||
* **CMYK**: Base64-Codierung der Bilddaten, *oder* die Image-Datei-URI, je nach `cameraOptions` in Kraft. *(String)*
|
||||
|
||||
### Beispiel
|
||||
|
||||
// Show image
|
||||
//
|
||||
function cameraCallback(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverHandle
|
||||
|
||||
Ein Handle für das Dialogfeld "Popover" erstellt von `navigator.camera.getPicture`.
|
||||
|
||||
### Methoden
|
||||
|
||||
* **SetPosition**: Legen Sie die Position der Popover.
|
||||
|
||||
### Unterstützte Plattformen
|
||||
|
||||
* iOS
|
||||
|
||||
### setPosition
|
||||
|
||||
Legen Sie die Position von der Popover.
|
||||
|
||||
**Parameter**:
|
||||
|
||||
* `cameraPopoverOptions`: die `CameraPopoverOptions` angeben, dass die neue Position
|
||||
|
||||
### Beispiel
|
||||
|
||||
var cameraPopoverHandle = navigator.camera.getPicture(onSuccess, onFail,
|
||||
{ destinationType: Camera.DestinationType.FILE_URI,
|
||||
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
|
||||
popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)
|
||||
});
|
||||
|
||||
// Reposition the popover if the orientation changes.
|
||||
window.onorientationchange = function() {
|
||||
var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
|
||||
cameraPopoverHandle.setPosition(cameraPopoverOptions);
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverOptions
|
||||
|
||||
nur iOS-Parametern, die Anker-Element Lage und Pfeil Richtung der Popover angeben, bei der Auswahl von Bildern aus einem iPad Bibliothek oder Album.
|
||||
|
||||
{ x : 0,
|
||||
y : 32,
|
||||
width : 320,
|
||||
height : 480,
|
||||
arrowDir : Camera.PopoverArrowDirection.ARROW_ANY
|
||||
};
|
||||
|
||||
|
||||
### CameraPopoverOptions
|
||||
|
||||
* **X**: x Pixelkoordinate des Bildschirmelement auf dem der Popover zu verankern. *(Anzahl)*
|
||||
|
||||
* **y**: y Pixelkoordinate des Bildschirmelement auf dem der Popover zu verankern. *(Anzahl)*
|
||||
|
||||
* **width**: Breite in Pixeln, das Bildschirmelement auf dem der Popover zu verankern. *(Anzahl)*
|
||||
|
||||
* **height**: Höhe in Pixeln, das Bildschirmelement auf dem der Popover zu verankern. *(Anzahl)*
|
||||
|
||||
* **arrowDir**: Richtung der Pfeil auf der Popover zeigen sollte. Im Sinne `Camera.PopoverArrowDirection` *(Anzahl)*
|
||||
|
||||
Camera.PopoverArrowDirection = {
|
||||
ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants
|
||||
ARROW_DOWN : 2,
|
||||
ARROW_LEFT : 4,
|
||||
ARROW_RIGHT : 8,
|
||||
ARROW_ANY : 15
|
||||
};
|
||||
|
||||
|
||||
Beachten Sie, dass die Größe der Popover ändern kann, um die Richtung des Pfeils und Ausrichtung des Bildschirms anzupassen. Achten Sie darauf, um Orientierung zu berücksichtigen, wenn Sie den Anker-Element-Speicherort angeben.
|
||||
|
||||
## navigator.camera.cleanup
|
||||
|
||||
Entfernt Mittelstufe Fotos von der Kamera aus der vorübergehenden Verwahrung genommen.
|
||||
|
||||
navigator.camera.cleanup( cameraSuccess, cameraError );
|
||||
|
||||
|
||||
### Beschreibung
|
||||
|
||||
Fortgeschrittene Image-Dateien, die in vorübergehender Verwahrung gehalten werden, nach dem Aufruf von `camera.getPicture` entfernt. Gilt nur wenn der Wert von `Camera.sourceType` gleich `Camera.PictureSourceType.CAMERA` und `Camera.destinationType` gleich `Camera.DestinationType.FILE_URI`.
|
||||
|
||||
### Unterstützte Plattformen
|
||||
|
||||
* iOS
|
||||
|
||||
### Beispiel
|
||||
|
||||
navigator.camera.cleanup(onSuccess, onFail);
|
||||
|
||||
function onSuccess() {
|
||||
console.log("Camera cleanup success.")
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
391
doc/es/index.md
Normal file
391
doc/es/index.md
Normal file
@@ -0,0 +1,391 @@
|
||||
<!---
|
||||
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.
|
||||
-->
|
||||
|
||||
# cordova-plugin-camera
|
||||
|
||||
Este plugin define un global `navigator.camera` objeto que proporciona una API para tomar fotografías y por elegir imágenes de biblioteca de imágenes del sistema.
|
||||
|
||||
Aunque el objeto está unido al ámbito global `navigator` , no estará disponible hasta después de la `deviceready` evento.
|
||||
|
||||
document.addEventListener ("deviceready", onDeviceReady, false);
|
||||
function onDeviceReady() {console.log(navigator.camera)};
|
||||
|
||||
|
||||
## Instalación
|
||||
|
||||
Cordova plugin agregar cordova-plugin-camera
|
||||
|
||||
|
||||
## navigator.camera.getPicture
|
||||
|
||||
Toma una foto con la cámara, o recupera una foto de Galería de imágenes del dispositivo. La imagen se pasa a la devolución de llamada de éxito como un codificado en base64 `String` , o como el URI para el archivo de imagen. El método se devuelve un `CameraPopoverHandle` objeto que puede utilizarse para volver a colocar el popover de selección de archivo.
|
||||
|
||||
navigator.camera.getPicture (cameraSuccess, cameraError, cameraOptions);
|
||||
|
||||
|
||||
### Descripción
|
||||
|
||||
El `camera.getPicture` función abre la aplicación de cámara predeterminada del dispositivo que permite a los usuarios ajustar imágenes. Este comportamiento se produce de forma predeterminada, cuando `Camera.sourceType` es igual a `Camera.PictureSourceType.CAMERA` . Una vez que el usuario ajusta la foto, una aplicación de cámara se cierra y se restablecerá la aplicación.
|
||||
|
||||
Si `Camera.sourceType` es `Camera.PictureSourceType.PHOTOLIBRARY` o `Camera.PictureSourceType.SAVEDPHOTOALBUM` , entonces una muestra de diálogo que permite a los usuarios seleccionar una imagen existente. El `camera.getPicture` función devuelve un `CameraPopoverHandle` objeto, que puede utilizarse para volver a colocar el diálogo de selección de imagen, por ejemplo, cuando cambia la orientación del dispositivo.
|
||||
|
||||
El valor devuelto es enviado a la `cameraSuccess` función de callback, en uno de los formatos siguientes, dependiendo del objeto `cameraOptions` :
|
||||
|
||||
* Una `String` que contiene la imagen codificada en base64.
|
||||
|
||||
* Una `String` que representa la ubicación del archivo de imagen en almacenamiento local (por defecto).
|
||||
|
||||
Puedes hacer lo que quieras con la imagen codificada o URI, por ejemplo:
|
||||
|
||||
* Representar la imagen en una etiqueta de `<img>`, como en el ejemplo siguiente
|
||||
|
||||
* Guardar los datos localmente (`LocalStorage`, [Lawnchair][1], etc.)
|
||||
|
||||
* Enviar los datos a un servidor remoto
|
||||
|
||||
[1]: http://brianleroux.github.com/lawnchair/
|
||||
|
||||
**Nota**: resolución de la foto en los nuevos dispositivos es bastante bueno. Fotos seleccionadas de la Galería del dispositivo no son degradadas a una calidad más baja, incluso si un `quality` se especifica el parámetro. Para evitar problemas con la memoria común, establezca `Camera.destinationType` a `FILE_URI` en lugar de`DATA_URL`.
|
||||
|
||||
### Plataformas soportadas
|
||||
|
||||
* Amazon fire OS
|
||||
* Android
|
||||
* BlackBerry 10
|
||||
* Explorador
|
||||
* Firefox OS
|
||||
* iOS
|
||||
* Tizen
|
||||
* Windows Phone 7 y 8
|
||||
* Windows 8
|
||||
|
||||
### Preferencias (iOS)
|
||||
|
||||
* **CameraUsesGeolocation** (booleano, el valor predeterminado de false). Para la captura de imágenes JPEG, establecido en true para obtener datos de geolocalización en la cabecera EXIF. Esto activará la solicitud de permisos de geolocalización si establecido en true.
|
||||
|
||||
<preference name="CameraUsesGeolocation" value="false" />
|
||||
|
||||
|
||||
### Amazon fuego OS rarezas
|
||||
|
||||
Amazon fuego OS utiliza los intentos para poner en marcha la actividad de la cámara del dispositivo para capturar imágenes y en teléfonos con poca memoria, puede matar la actividad Cordova. En este escenario, la imagen no aparezca cuando se restaura la actividad cordova.
|
||||
|
||||
### Rarezas Android
|
||||
|
||||
Android utiliza los intentos para iniciar la actividad de la cámara del dispositivo para capturar imágenes, y en los teléfonos con poca memoria, puede matar la actividad Cordova. En este escenario, la imagen no aparezca cuando se restaura la actividad Cordova.
|
||||
|
||||
### Navegador rarezas
|
||||
|
||||
Sólo puede devolver fotos como imagen codificada en base64.
|
||||
|
||||
### Firefox OS rarezas
|
||||
|
||||
Cámara plugin actualmente se implementa mediante [Actividades Web][2].
|
||||
|
||||
[2]: https://hacks.mozilla.org/2013/01/introducing-web-activities/
|
||||
|
||||
### iOS rarezas
|
||||
|
||||
Incluyendo un JavaScript `alert()` en cualquiera de la devolución de llamada funciones pueden causar problemas. Envuelva la alerta dentro de un `setTimeout()` para permitir que el selector de imagen iOS o popover cerrar completamente antes de la alerta se muestra:
|
||||
|
||||
setTimeout(function() {/ / Haz lo tuyo aquí!}, 0);
|
||||
|
||||
|
||||
### Windows Phone 7 rarezas
|
||||
|
||||
Invocando la aplicación de cámara nativa mientras el dispositivo está conectado vía Zune no funciona y desencadena un callback de error.
|
||||
|
||||
### Rarezas Tizen
|
||||
|
||||
Tizen sólo es compatible con un `destinationType` de `Camera.DestinationType.FILE_URI` y un `sourceType` de`Camera.PictureSourceType.PHOTOLIBRARY`.
|
||||
|
||||
### Ejemplo
|
||||
|
||||
Tomar una foto y recuperarlo como una imagen codificada en base64:
|
||||
|
||||
navigator.camera.getPicture (onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.DATA_URL
|
||||
});
|
||||
|
||||
function onSuccess(imageData) {var imagen = document.getElementById('myImage');
|
||||
Image.src = "datos: image / jpeg; base64," + imageData;}
|
||||
|
||||
function onFail(message) {alert (' falló porque: ' + mensaje);}
|
||||
|
||||
|
||||
Tomar una foto y recuperar la ubicación del archivo de la imagen:
|
||||
|
||||
navigator.camera.getPicture (onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.FILE_URI });
|
||||
|
||||
function onSuccess(imageURI) {var imagen = document.getElementById('myImage');
|
||||
Image.src = imageURI;
|
||||
} function onFail(message) {alert (' falló porque: ' + mensaje);}
|
||||
|
||||
|
||||
## CameraOptions
|
||||
|
||||
Parámetros opcionales para personalizar la configuración de la cámara.
|
||||
|
||||
{calidad: destinationType 75,: Camera.DestinationType.DATA_URL, sourceType: Camera.PictureSourceType.CAMERA, allowEdit: true, encodingType: Camera.EncodingType.JPEG, targetWidth: 100, targetHeight: 100, popoverOptions: CameraPopoverOptions, saveToPhotoAlbum: falsa};
|
||||
|
||||
|
||||
### Opciones
|
||||
|
||||
* **calidad**: calidad de la imagen guardada, expresada en un rango de 0-100, donde 100 es típicamente resolución sin pérdida de compresión del archivo. El valor predeterminado es 50. *(Número)* (Tenga en cuenta que no está disponible información sobre resolución de la cámara).
|
||||
|
||||
* **destinationType**: elegir el formato del valor devuelto. El valor predeterminado es FILE_URI. Definido en `navigator.camera.DestinationType` *(número)*
|
||||
|
||||
Camera.DestinationType = {
|
||||
DATA_URL : 0, // Return image as base64-encoded string
|
||||
FILE_URI : 1, // Return image file URI
|
||||
NATIVE_URI : 2 // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
|
||||
};
|
||||
|
||||
|
||||
* **sourceType**: establecer el origen de la imagen. El valor predeterminado es cámara. Definido en `navigator.camera.PictureSourceType` *(número)*
|
||||
|
||||
Camera.PictureSourceType = {
|
||||
PHOTOLIBRARY : 0,
|
||||
CAMERA : 1,
|
||||
SAVEDPHOTOALBUM : 2
|
||||
};
|
||||
|
||||
|
||||
* **allowEdit**: permite edición sencilla de imagen antes de la selección. *(Booleano)*
|
||||
|
||||
* **encodingType**: elegir la codificación del archivo de imagen devuelta. Por defecto es JPEG. Definido en `navigator.camera.EncodingType` *(número)*
|
||||
|
||||
Camera.EncodingType = {
|
||||
JPEG : 0, // Return JPEG encoded image
|
||||
PNG : 1 // Return PNG encoded image
|
||||
};
|
||||
|
||||
|
||||
* **targetWidth**: ancho en píxeles a escala de la imagen. Debe usarse con **targetHeight**. Proporción se mantiene constante. *(Número)*
|
||||
|
||||
* **targetHeight**: altura en píxeles a escala de la imagen. Debe usarse con **targetWidth**. Proporción se mantiene constante. *(Número)*
|
||||
|
||||
* **mediaType**: definir el tipo de medios para seleccionar. Sólo funciona cuando `PictureSourceType` es `PHOTOLIBRARY` o `SAVEDPHOTOALBUM` . Definido en `nagivator.camera.MediaType` *(número)*
|
||||
|
||||
Camera.MediaType = {
|
||||
PICTURE: 0, // allow selection of still pictures only. DE FORMA PREDETERMINADA. Will return format specified via DestinationType
|
||||
VIDEO: 1, // allow selection of video only, WILL ALWAYS RETURN FILE_URI
|
||||
ALLMEDIA : 2 // allow selection from all media types
|
||||
};
|
||||
|
||||
|
||||
* **correctOrientation**: rotar la imagen para corregir la orientación del dispositivo durante la captura. *(Booleano)*
|
||||
|
||||
* **saveToPhotoAlbum**: guardar la imagen en el álbum de fotos en el dispositivo después de su captura. *(Booleano)*
|
||||
|
||||
* **popoverOptions**: opciones sólo iOS que especifican popover ubicación en iPad. Definido en`CameraPopoverOptions`.
|
||||
|
||||
* **cameraDirection**: elegir la cámara para usar (o parte posterior-frontal). El valor predeterminado es atrás. Definido en `navigator.camera.Direction` *(número)*
|
||||
|
||||
Camera.Direction = {
|
||||
BACK : 0, // Use the back-facing camera
|
||||
FRONT : 1 // Use the front-facing camera
|
||||
};
|
||||
|
||||
|
||||
### Amazon fuego OS rarezas
|
||||
|
||||
* Cualquier valor de `cameraDirection` da como resultado una foto orientada hacia atrás.
|
||||
|
||||
* Ignora el `allowEdit` parámetro.
|
||||
|
||||
* `Camera.PictureSourceType.PHOTOLIBRARY` y `Camera.PictureSourceType.SAVEDPHOTOALBUM` Mostrar el mismo álbum de fotos.
|
||||
|
||||
### Rarezas Android
|
||||
|
||||
* Cualquier valor de `cameraDirection` da como resultado una foto orientada hacia atrás.
|
||||
|
||||
* Ignora el `allowEdit` parámetro.
|
||||
|
||||
* `Camera.PictureSourceType.PHOTOLIBRARY` y `Camera.PictureSourceType.SAVEDPHOTOALBUM` Mostrar el mismo álbum de fotos.
|
||||
|
||||
### BlackBerry 10 rarezas
|
||||
|
||||
* Ignora el `quality` parámetro.
|
||||
|
||||
* Ignora el `allowEdit` parámetro.
|
||||
|
||||
* `Camera.MediaType`No se admite.
|
||||
|
||||
* Ignora el `correctOrientation` parámetro.
|
||||
|
||||
* Ignora el `cameraDirection` parámetro.
|
||||
|
||||
### Firefox OS rarezas
|
||||
|
||||
* Ignora el `quality` parámetro.
|
||||
|
||||
* `Camera.DestinationType`se ignora y es igual a `1` (URI del archivo de imagen)
|
||||
|
||||
* Ignora el `allowEdit` parámetro.
|
||||
|
||||
* Ignora el `PictureSourceType` parámetro (el usuario lo elige en una ventana de diálogo)
|
||||
|
||||
* Ignora el`encodingType`
|
||||
|
||||
* Ignora el `targetWidth` y`targetHeight`
|
||||
|
||||
* `Camera.MediaType`No se admite.
|
||||
|
||||
* Ignora el `correctOrientation` parámetro.
|
||||
|
||||
* Ignora el `cameraDirection` parámetro.
|
||||
|
||||
### iOS rarezas
|
||||
|
||||
* Establecer `quality` por debajo de 50 para evitar errores de memoria en algunos dispositivos.
|
||||
|
||||
* Cuando se utiliza `destinationType.FILE_URI` , fotos se guardan en el directorio temporal de la aplicación. El contenido del directorio temporal de la aplicación se eliminará cuando finalice la aplicación.
|
||||
|
||||
### Rarezas Tizen
|
||||
|
||||
* opciones no compatibles
|
||||
|
||||
* siempre devuelve un identificador URI de archivo
|
||||
|
||||
### Windows Phone 7 y 8 rarezas
|
||||
|
||||
* Ignora el `allowEdit` parámetro.
|
||||
|
||||
* Ignora el `correctOrientation` parámetro.
|
||||
|
||||
* Ignora el `cameraDirection` parámetro.
|
||||
|
||||
* Ignora el `saveToPhotoAlbum` parámetro. IMPORTANTE: Todas las imágenes tomadas con la cámara wp7/8 cordova API siempre se copian en rollo de cámara del teléfono. Dependiendo de la configuración del usuario, esto podría significar también que la imagen es auto-subido a su OneDrive. Esto potencialmente podría significar que la imagen está disponible a una audiencia más amplia que su aplicación previsto. Si un bloqueador para su aplicación, usted necesitará aplicar el CameraCaptureTask como se documenta en msdn: <http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx> también puede comentar o votar hasta el tema relacionado en el [issue tracker de][3]
|
||||
|
||||
* Ignora el `mediaType` propiedad de `cameraOptions` como el SDK de Windows Phone no proporciona una manera para elegir vídeos fototeca.
|
||||
|
||||
[3]: https://issues.apache.org/jira/browse/CB-2083
|
||||
|
||||
## CameraError
|
||||
|
||||
onError función callback que proporciona un mensaje de error.
|
||||
|
||||
function(Message) {/ / Mostrar un mensaje útil}
|
||||
|
||||
|
||||
### Parámetros
|
||||
|
||||
* **mensaje**: el mensaje es proporcionado por código nativo del dispositivo. *(String)*
|
||||
|
||||
## cameraSuccess
|
||||
|
||||
onSuccess función callback que proporciona los datos de imagen.
|
||||
|
||||
function(ImageData) {/ / hacer algo con la imagen}
|
||||
|
||||
|
||||
### Parámetros
|
||||
|
||||
* **imageData**: codificación en Base64 de los datos de imagen, *o* el archivo de imagen URI, dependiendo de `cameraOptions` en vigor. *(String)*
|
||||
|
||||
### Ejemplo
|
||||
|
||||
Mostrar imagen / / function cameraCallback(imageData) {var imagen = document.getElementById('myImage');
|
||||
Image.src = "datos: image / jpeg; base64," + imageData;}
|
||||
|
||||
|
||||
## CameraPopoverHandle
|
||||
|
||||
Un identificador para el cuadro de diálogo popover creado por`navigator.camera.getPicture`.
|
||||
|
||||
### Métodos
|
||||
|
||||
* **setPosition**: establecer la posición de la popover.
|
||||
|
||||
### Plataformas soportadas
|
||||
|
||||
* iOS
|
||||
|
||||
### setPosition
|
||||
|
||||
Establecer la posición de la popover.
|
||||
|
||||
**Parámetros**:
|
||||
|
||||
* `cameraPopoverOptions`: el `CameraPopoverOptions` que especifican la nueva posición
|
||||
|
||||
### Ejemplo
|
||||
|
||||
var cameraPopoverHandle = navigator.camera.getPicture (onSuccess, onFail, {destinationType: Camera.DestinationType.FILE_URI, sourceType: Camera.PictureSourceType.PHOTOLIBRARY, popoverOptions: CameraPopoverOptions nuevo (300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)});
|
||||
|
||||
Vuelva a colocar el popover si cambia la orientación.
|
||||
Window.onorientationchange = function() {var cameraPopoverOptions = new CameraPopoverOptions (0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
|
||||
cameraPopoverHandle.setPosition(cameraPopoverOptions);
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverOptions
|
||||
|
||||
Sólo iOS parámetros que especifican la dirección ancla elemento ubicación y la flecha de la popover al seleccionar imágenes de biblioteca o álbum de un iPad.
|
||||
|
||||
{x: 0, y: 32, ancho: 320, altura: 480, arrowDir: Camera.PopoverArrowDirection.ARROW_ANY};
|
||||
|
||||
|
||||
### CameraPopoverOptions
|
||||
|
||||
* **x**: coordenadas de píxeles del elemento de la pantalla en la que anclar el popover x. *(Número)*
|
||||
|
||||
* **y**: coordenada píxeles del elemento de la pantalla en la que anclar el popover. *(Número)*
|
||||
|
||||
* **anchura**: anchura, en píxeles, del elemento sobre el que anclar el popover pantalla. *(Número)*
|
||||
|
||||
* **altura**: alto, en píxeles, del elemento sobre el que anclar el popover pantalla. *(Número)*
|
||||
|
||||
* **arrowDir**: dirección de la flecha en el popover debe apuntar. Definido en `Camera.PopoverArrowDirection` *(número)*
|
||||
|
||||
Camera.PopoverArrowDirection = {
|
||||
ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants
|
||||
ARROW_DOWN : 2,
|
||||
ARROW_LEFT : 4,
|
||||
ARROW_RIGHT : 8,
|
||||
ARROW_ANY : 15
|
||||
};
|
||||
|
||||
|
||||
Tenga en cuenta que puede cambiar el tamaño de la popover para ajustar la dirección de la flecha y orientación de la pantalla. Asegúrese de que para tener en cuenta los cambios de orientación cuando se especifica la ubicación del elemento de anclaje.
|
||||
|
||||
## Navigator.Camera.Cleanup
|
||||
|
||||
Elimina intermedio fotos tomadas por la cámara de almacenamiento temporal.
|
||||
|
||||
Navigator.Camera.cleanup (cameraSuccess, cameraError);
|
||||
|
||||
|
||||
### Descripción
|
||||
|
||||
Elimina intermedio archivos de imagen que se mantienen en depósito temporal después de llamar `camera.getPicture` . Se aplica sólo cuando el valor de `Camera.sourceType` es igual a `Camera.PictureSourceType.CAMERA` y el `Camera.destinationType` es igual a`Camera.DestinationType.FILE_URI`.
|
||||
|
||||
### Plataformas soportadas
|
||||
|
||||
* iOS
|
||||
|
||||
### Ejemplo
|
||||
|
||||
Navigator.Camera.cleanup (onSuccess, onFail);
|
||||
|
||||
function onSuccess() {console.log ("cámara limpieza éxito.")}
|
||||
|
||||
function onFail(message) {alert (' falló porque: ' + mensaje);}
|
||||
391
doc/fr/index.md
Normal file
391
doc/fr/index.md
Normal file
@@ -0,0 +1,391 @@
|
||||
<!---
|
||||
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.
|
||||
-->
|
||||
|
||||
# cordova-plugin-camera
|
||||
|
||||
Ce plugin définit un global `navigator.camera` objet qui fournit une API pour la prise de photos et de choisir des images de la bibliothèque d'images du système.
|
||||
|
||||
Bien que l'objet est attaché à la portée globale `navigator` , il n'est pas disponible jusqu'après la `deviceready` événement.
|
||||
|
||||
document.addEventListener (« deviceready », onDeviceReady, false) ;
|
||||
function onDeviceReady() {console.log(navigator.camera);}
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
Cordova plugin ajouter cordova-plugin-camera
|
||||
|
||||
|
||||
## navigator.camera.getPicture
|
||||
|
||||
Prend une photo à l'aide de la caméra, ou récupère une photo de la Galerie d'images de l'appareil. L'image est passé au rappel succès comme un codage base64 `String` , ou comme l'URI du fichier de l'image. La méthode elle-même retourne un `CameraPopoverHandle` objet qui permet de repositionner le kangourou de sélection de fichier.
|
||||
|
||||
navigator.camera.getPicture (cameraSuccess, cameraError, cameraOptions) ;
|
||||
|
||||
|
||||
### Description
|
||||
|
||||
Le `camera.getPicture` fonction ouvre l'application de caméra par défaut de l'appareil qui permet aux utilisateurs de prendre des photos. Ce comportement se produit par défaut, lorsque `Camera.sourceType` est égal à `Camera.PictureSourceType.CAMERA` . Une fois que l'utilisateur s'enclenche la photo, l'application appareil photo se ferme et l'application est restaurée.
|
||||
|
||||
Si `Camera.sourceType` est `Camera.PictureSourceType.PHOTOLIBRARY` ou `Camera.PictureSourceType.SAVEDPHOTOALBUM` , puis un dialogue affiche qui permet aux utilisateurs de sélectionner une image existante. Le `camera.getPicture` retourne un `CameraPopoverHandle` objet, ce qui permet de repositionner le dialogue de sélection d'image, par exemple, lorsque l'orientation de l'appareil change.
|
||||
|
||||
La valeur de retour est envoyée à la `cameraSuccess` la fonction de rappel, dans l'un des formats suivants, selon les `cameraOptions` :
|
||||
|
||||
* A `String` contenant l'image photo codée en base64.
|
||||
|
||||
* A `String` qui représente l'emplacement du fichier image sur le stockage local (par défaut).
|
||||
|
||||
Vous pouvez faire ce que vous voulez avec l'image codée ou URI, par exemple :
|
||||
|
||||
* Afficher l'image dans un `<img>` tag, comme dans l'exemple ci-dessous
|
||||
|
||||
* Enregistrer les données localement ( `LocalStorage` , [poids][1], etc..)
|
||||
|
||||
* Publier les données sur un serveur distant
|
||||
|
||||
[1]: http://brianleroux.github.com/lawnchair/
|
||||
|
||||
**NOTE**: la résolution de Photo sur les nouveaux appareils est assez bonne. Photos sélectionnées de la Galerie de l'appareil ne sont pas réduites à une baisse de la qualité, même si un `quality` paramètre est spécifié. Pour éviter les problèmes de mémoire commun, définissez `Camera.destinationType` à `FILE_URI` au lieu de`DATA_URL`.
|
||||
|
||||
### Plates-formes prises en charge
|
||||
|
||||
* Amazon Fire OS
|
||||
* Android
|
||||
* BlackBerry 10
|
||||
* Navigateur
|
||||
* Firefox OS
|
||||
* iOS
|
||||
* Paciarelli
|
||||
* Windows Phone 7 et 8
|
||||
* Windows 8
|
||||
|
||||
### Préférences (iOS)
|
||||
|
||||
* **CameraUsesGeolocation** (boolean, par défaut, false). Pour capturer des images JPEG, true pour obtenir des données de géolocalisation dans l'en-tête EXIF. Cela va déclencher une demande d'autorisations de géolocalisation si défini à true.
|
||||
|
||||
<preference name="CameraUsesGeolocation" value="false" />
|
||||
|
||||
|
||||
### Amazon Fire OS Quirks
|
||||
|
||||
Amazon Fire OS utilise des intentions pour lancer l'activité de l'appareil photo sur l'appareil pour capturer des images et sur les téléphones avec peu de mémoire, l'activité de Cordova peut être tuée. Dans ce scénario, l'image peut ne pas apparaître lorsque l'activité de cordova est restaurée.
|
||||
|
||||
### Quirks Android
|
||||
|
||||
Android utilise des intentions pour lancer l'activité de l'appareil photo sur l'appareil pour capturer des images et sur les téléphones avec peu de mémoire, l'activité de Cordova peut être tuée. Dans ce scénario, l'image peut ne pas apparaître lorsque l'activité de Cordova est restaurée.
|
||||
|
||||
### Bizarreries navigateur
|
||||
|
||||
Peut retourner uniquement les photos comme image codée en base64.
|
||||
|
||||
### Firefox OS Quirks
|
||||
|
||||
Appareil photo plugin est actuellement mis en œuvre à l'aide [d'Activités sur le Web][2].
|
||||
|
||||
[2]: https://hacks.mozilla.org/2013/01/introducing-web-activities/
|
||||
|
||||
### iOS Quirks
|
||||
|
||||
Y compris un JavaScript `alert()` dans les deux le rappel fonctions peuvent causer des problèmes. Envelopper l'alerte dans un `setTimeout()` pour permettre le sélecteur d'image iOS ou kangourou pour fermer entièrement avant que l'alerte s'affiche :
|
||||
|
||||
setTimeout(function() {/ / faire votre truc ici!}, 0) ;
|
||||
|
||||
|
||||
### Windows Phone 7 Quirks
|
||||
|
||||
Invoquant l'application native caméra alors que l'appareil est connecté via Zune ne fonctionne pas et déclenche un rappel de l'erreur.
|
||||
|
||||
### Bizarreries de paciarelli
|
||||
|
||||
Paciarelli prend uniquement en charge un `destinationType` de `Camera.DestinationType.FILE_URI` et un `sourceType` de`Camera.PictureSourceType.PHOTOLIBRARY`.
|
||||
|
||||
### Exemple
|
||||
|
||||
Prendre une photo, puis extrayez-la comme une image codée en base64 :
|
||||
|
||||
navigator.camera.getPicture (onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.DATA_URL
|
||||
}) ;
|
||||
|
||||
function onSuccess(imageData) {var image = document.getElementById('myImage') ;
|
||||
image.src = "données : image / jpeg ; base64," + imageData;}
|
||||
|
||||
function onFail(message) {alert (' a échoué car: "+ message);}
|
||||
|
||||
|
||||
Prendre une photo et récupérer l'emplacement du fichier de l'image :
|
||||
|
||||
navigator.camera.getPicture (onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.FILE_URI }) ;
|
||||
|
||||
function onSuccess(imageURI) {var image = document.getElementById('myImage') ;
|
||||
image.SRC = imageURI ;
|
||||
} function onFail(message) {alert (' a échoué car: "+ message);}
|
||||
|
||||
|
||||
## CameraOptions
|
||||
|
||||
Paramètres optionnels pour personnaliser les réglages de l'appareil.
|
||||
|
||||
{qualité : destinationType 75,: Camera.DestinationType.DATA_URL, TypeSource : Camera.PictureSourceType.CAMERA, allowEdit : encodingType vrai,: Camera.EncodingType.JPEG, targetWidth : 100, targetHeight : 100, popoverOptions : CameraPopoverOptions, saveToPhotoAlbum : false} ;
|
||||
|
||||
|
||||
### Options
|
||||
|
||||
* **qualité**: qualité de l'image enregistrée, exprimée en une gamme de 0 à 100, 100 étant généralement pleine résolution sans perte de compression de fichiers. La valeur par défaut est 50. *(Nombre)* (Notez que les informations sur la résolution de la caméra sont indisponibles).
|
||||
|
||||
* **destinationType**: choisissez le format de la valeur de retour. La valeur par défaut est FILE_URI. Définies dans `navigator.camera.DestinationType` *(nombre)*
|
||||
|
||||
Camera.DestinationType = {
|
||||
DATA_URL : 0, // Return image as base64-encoded string
|
||||
FILE_URI : 1, // Return image file URI
|
||||
NATIVE_URI : 2 // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
|
||||
};
|
||||
|
||||
|
||||
* **sourceType**: définissez la source de l'image. La valeur par défaut est la caméra. Définies dans `navigator.camera.PictureSourceType` *(nombre)*
|
||||
|
||||
Camera.PictureSourceType = {
|
||||
PHOTOLIBRARY : 0,
|
||||
CAMERA : 1,
|
||||
SAVEDPHOTOALBUM : 2
|
||||
};
|
||||
|
||||
|
||||
* **allowEdit**: permettre un montage simple d'image avant la sélection. *(Booléen)*
|
||||
|
||||
* **encodingType**: choisir le fichier image retournée de codage. Valeur par défaut est JPEG. Définies dans `navigator.camera.EncodingType` *(nombre)*
|
||||
|
||||
Camera.EncodingType = {
|
||||
JPEG : 0, // Return JPEG encoded image
|
||||
PNG : 1 // Return PNG encoded image
|
||||
};
|
||||
|
||||
|
||||
* **targetWidth**: largeur en pixels de l'image de l'échelle. Doit être utilisé avec **targetHeight**. Aspect ratio reste constant. *(Nombre)*
|
||||
|
||||
* **targetHeight**: hauteur en pixels de l'image de l'échelle. Doit être utilisé avec **targetWidth**. Aspect ratio reste constant. *(Nombre)*
|
||||
|
||||
* **mediaType**: définir le type de média pour choisir de. Ne fonctionne que quand `PictureSourceType` est `PHOTOLIBRARY` ou `SAVEDPHOTOALBUM` . Définies dans `nagivator.camera.MediaType` *(nombre)*
|
||||
|
||||
Camera.MediaType = {
|
||||
PICTURE: 0, // allow selection of still pictures only. PAR DÉFAUT. Will return format specified via DestinationType
|
||||
VIDEO: 1, // allow selection of video only, WILL ALWAYS RETURN FILE_URI
|
||||
ALLMEDIA : 2 // allow selection from all media types
|
||||
};
|
||||
|
||||
|
||||
* **correctOrientation**: faire pivoter l'image afin de corriger l'orientation de l'appareil lors de la capture. *(Booléen)*
|
||||
|
||||
* **saveToPhotoAlbum**: enregistrer l'image sur l'album photo sur l'appareil après la capture. *(Booléen)*
|
||||
|
||||
* **popoverOptions**: iOS uniquement des options qui spécifient l'emplacement de kangourou dans iPad. Défini dans`CameraPopoverOptions`.
|
||||
|
||||
* **cameraDirection**: choisissez la caméra à utiliser (ou dos-face). La valeur par défaut est de retour. Définies dans `navigator.camera.Direction` *(nombre)*
|
||||
|
||||
Camera.Direction = {
|
||||
BACK : 0, // Use the back-facing camera
|
||||
FRONT : 1 // Use the front-facing camera
|
||||
};
|
||||
|
||||
|
||||
### Amazon Fire OS Quirks
|
||||
|
||||
* Tout `cameraDirection` résultats dans le back-face photo de valeur.
|
||||
|
||||
* Ignore la `allowEdit` paramètre.
|
||||
|
||||
* `Camera.PictureSourceType.PHOTOLIBRARY`et `Camera.PictureSourceType.SAVEDPHOTOALBUM` les deux affichent le même album photo.
|
||||
|
||||
### Quirks Android
|
||||
|
||||
* Tout `cameraDirection` résultats dans le back-face photo de valeur.
|
||||
|
||||
* Ignore la `allowEdit` paramètre.
|
||||
|
||||
* `Camera.PictureSourceType.PHOTOLIBRARY`et `Camera.PictureSourceType.SAVEDPHOTOALBUM` les deux affichent le même album photo.
|
||||
|
||||
### BlackBerry 10 Quirks
|
||||
|
||||
* Ignore la `quality` paramètre.
|
||||
|
||||
* Ignore la `allowEdit` paramètre.
|
||||
|
||||
* `Camera.MediaType`n'est pas pris en charge.
|
||||
|
||||
* Ignore la `correctOrientation` paramètre.
|
||||
|
||||
* Ignore la `cameraDirection` paramètre.
|
||||
|
||||
### Firefox OS Quirks
|
||||
|
||||
* Ignore la `quality` paramètre.
|
||||
|
||||
* `Camera.DestinationType`est ignorée et est égal à `1` (URI du fichier image)
|
||||
|
||||
* Ignore la `allowEdit` paramètre.
|
||||
|
||||
* Ignore la `PictureSourceType` paramètre (utilisateur il choisit dans une fenêtre de dialogue)
|
||||
|
||||
* Ignore le`encodingType`
|
||||
|
||||
* Ignore la `targetWidth` et`targetHeight`
|
||||
|
||||
* `Camera.MediaType`n'est pas pris en charge.
|
||||
|
||||
* Ignore la `correctOrientation` paramètre.
|
||||
|
||||
* Ignore la `cameraDirection` paramètre.
|
||||
|
||||
### iOS Quirks
|
||||
|
||||
* La valeur `quality` inférieur à 50 pour éviter les erreurs de mémoire sur certains appareils.
|
||||
|
||||
* Lorsque vous utilisez `destinationType.FILE_URI` , les photos sont sauvegardées dans le répertoire temporaire de l'application. Le contenu du répertoire temporaire de l'application est supprimé lorsque l'application se termine.
|
||||
|
||||
### Bizarreries de paciarelli
|
||||
|
||||
* options non prises en charge
|
||||
|
||||
* retourne toujours un URI de fichier
|
||||
|
||||
### Windows Phone 7 et 8 Quirks
|
||||
|
||||
* Ignore la `allowEdit` paramètre.
|
||||
|
||||
* Ignore la `correctOrientation` paramètre.
|
||||
|
||||
* Ignore la `cameraDirection` paramètre.
|
||||
|
||||
* Ignore la `saveToPhotoAlbum` paramètre. IMPORTANT : Toutes les images prises avec la caméra de cordova wp7/8 API sont toujours copiés au rôle d'appareil photo du téléphone. Selon les paramètres de l'utilisateur, cela pourrait également signifier que l'image est auto-téléchargées à leur OneDrive. Potentiellement, cela pourrait signifier que l'image est disponible à un public plus large que votre application destinée. Si ce un bloqueur pour votre application, vous devrez implémenter le CameraCaptureTask tel que documenté sur msdn : <http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx> vous pouvez aussi commenter ou haut-vote la question connexe dans le [gestionnaire d'incidents][3]
|
||||
|
||||
* Ignore la `mediaType` propriété de `cameraOptions` comme le kit de développement Windows Phone ne fournit pas un moyen de choisir les vidéos de PHOTOLIBRARY.
|
||||
|
||||
[3]: https://issues.apache.org/jira/browse/CB-2083
|
||||
|
||||
## CameraError
|
||||
|
||||
fonction de rappel onError qui fournit un message d'erreur.
|
||||
|
||||
function(message) {/ / afficher un message utile}
|
||||
|
||||
|
||||
### Paramètres
|
||||
|
||||
* **message**: le message est fourni par du code natif de l'appareil. *(String)*
|
||||
|
||||
## cameraSuccess
|
||||
|
||||
fonction de rappel onSuccess qui fournit les données d'image.
|
||||
|
||||
function(ImageData) {/ / faire quelque chose avec l'image}
|
||||
|
||||
|
||||
### Paramètres
|
||||
|
||||
* **imageData**: codage Base64 de l'image, *ou* le fichier image URI, selon `cameraOptions` en vigueur. *(String)*
|
||||
|
||||
### Exemple
|
||||
|
||||
Afficher image / / function cameraCallback(imageData) {var image = document.getElementById('myImage') ;
|
||||
image.src = "données : image / jpeg ; base64," + imageData;}
|
||||
|
||||
|
||||
## CameraPopoverHandle
|
||||
|
||||
Un handle vers la boîte de dialogue de kangourou créé par`navigator.camera.getPicture`.
|
||||
|
||||
### Méthodes
|
||||
|
||||
* **setPosition**: définir la position de la kangourou.
|
||||
|
||||
### Plates-formes prises en charge
|
||||
|
||||
* iOS
|
||||
|
||||
### setPosition
|
||||
|
||||
Définir la position de la kangourou.
|
||||
|
||||
**Paramètres**:
|
||||
|
||||
* `cameraPopoverOptions`: la `CameraPopoverOptions` qui spécifie la nouvelle position
|
||||
|
||||
### Exemple
|
||||
|
||||
var cameraPopoverHandle = navigator.camera.getPicture (onSuccess, onFail, {destinationType : Camera.DestinationType.FILE_URI, TypeSource : Camera.PictureSourceType.PHOTOLIBRARY, popoverOptions : nouvelle CameraPopoverOptions (300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)}) ;
|
||||
|
||||
Repositionner le kangourou si l'orientation change.
|
||||
Window.onorientationchange = function() {var cameraPopoverOptions = new CameraPopoverOptions (0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY) ;
|
||||
cameraPopoverHandle.setPosition(cameraPopoverOptions) ;
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverOptions
|
||||
|
||||
iOS uniquement les paramètres qui spécifient la direction ancre élément emplacement et de la flèche de la kangourou lors de la sélection des images de la bibliothèque de l'iPad ou l'album.
|
||||
|
||||
{x: 0, y: 32, largeur : 320, hauteur : 480, arrowDir : Camera.PopoverArrowDirection.ARROW_ANY} ;
|
||||
|
||||
|
||||
### CameraPopoverOptions
|
||||
|
||||
* **x**: coordonnée de pixel de l'élément de l'écran sur lequel ancrer le kangourou x. *(Nombre)*
|
||||
|
||||
* **y**: coordonnée de y pixels de l'élément de l'écran sur lequel ancrer le kangourou. *(Nombre)*
|
||||
|
||||
* **largeur**: largeur, en pixels, de l'élément de l'écran sur lequel ancrer le kangourou. *(Nombre)*
|
||||
|
||||
* **hauteur**: hauteur, en pixels, de l'élément de l'écran sur lequel ancrer le kangourou. *(Nombre)*
|
||||
|
||||
* **arrowDir**: Direction de la flèche sur le kangourou doit pointer. Définies dans `Camera.PopoverArrowDirection` *(nombre)*
|
||||
|
||||
Camera.PopoverArrowDirection = {
|
||||
ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants
|
||||
ARROW_DOWN : 2,
|
||||
ARROW_LEFT : 4,
|
||||
ARROW_RIGHT : 8,
|
||||
ARROW_ANY : 15
|
||||
};
|
||||
|
||||
|
||||
Notez que la taille de la kangourou peut changer pour s'adapter à la direction de la flèche et l'orientation de l'écran. Assurez-vous que tenir compte des changements d'orientation lors de la spécification de l'emplacement d'élément d'ancrage.
|
||||
|
||||
## Navigator.Camera.Cleanup
|
||||
|
||||
Supprime les intermédiaires photos prises par la caméra de stockage temporaire.
|
||||
|
||||
Navigator.Camera.Cleanup (cameraSuccess, cameraError) ;
|
||||
|
||||
|
||||
### Description
|
||||
|
||||
Supprime les intermédiaires les fichiers image qui sont gardées en dépôt temporaire après avoir appelé `camera.getPicture` . S'applique uniquement lorsque la valeur de `Camera.sourceType` est égale à `Camera.PictureSourceType.CAMERA` et le `Camera.destinationType` est égal à`Camera.DestinationType.FILE_URI`.
|
||||
|
||||
### Plates-formes prises en charge
|
||||
|
||||
* iOS
|
||||
|
||||
### Exemple
|
||||
|
||||
Navigator.Camera.Cleanup (onSuccess, onFail) ;
|
||||
|
||||
fonction onSuccess() {console.log ("succès de caméra nettoyage.")}
|
||||
|
||||
function onFail(message) {alert (' a échoué car: "+ message);}
|
||||
434
doc/it/index.md
Normal file
434
doc/it/index.md
Normal file
@@ -0,0 +1,434 @@
|
||||
<!---
|
||||
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.
|
||||
-->
|
||||
|
||||
# cordova-plugin-camera
|
||||
|
||||
Questo plugin definisce un oggetto globale `navigator.camera`, che fornisce un'API per scattare foto e per aver scelto immagini dalla libreria di immagini del sistema.
|
||||
|
||||
Anche se l'oggetto è associato con ambito globale del `navigator`, non è disponibile fino a dopo l'evento `deviceready`.
|
||||
|
||||
document.addEventListener("deviceready", onDeviceReady, false);
|
||||
function onDeviceReady() {
|
||||
console.log(navigator.camera);
|
||||
}
|
||||
|
||||
|
||||
## Installazione
|
||||
|
||||
cordova plugin add cordova-plugin-camera
|
||||
|
||||
|
||||
## navigator.camera.getPicture
|
||||
|
||||
Prende una foto utilizzando la fotocamera, o recupera una foto dalla galleria di immagini del dispositivo. L'immagine è passata al callback di successo come `String` con codifica base64, o come l'URI per il file di immagine. Lo stesso metodo restituisce un oggetto `CameraPopoverHandle` che può essere utilizzato per riposizionare il Muffin di selezione file.
|
||||
|
||||
navigator.camera.getPicture( cameraSuccess, cameraError, cameraOptions );
|
||||
|
||||
|
||||
### Descrizione
|
||||
|
||||
La funzione `camera.getPicture` apre predefinito fotocamera applicazione il dispositivo che consente agli utenti di scattare foto. Questo comportamento si verifica per impostazione predefinita, quando `Camera.sourceType` è uguale a `Camera.PictureSourceType.CAMERA`. Una volta che l'utente scatta la foto, si chiude l'applicazione fotocamera e l'applicazione viene ripristinato.
|
||||
|
||||
Se `Camera.sourceType` è `Camera.PictureSourceType.PHOTOLIBRARY` o `Camera.PictureSourceType.SAVEDPHOTOALBUM`, una finestra di dialogo Visualizza che permette agli utenti di selezionare un'immagine esistente. La funzione `camera.getPicture` restituisce un oggetto `CameraPopoverHandle` che può essere utilizzato per riposizionare la finestra di selezione immagine, ad esempio, quando l'orientamento del dispositivo.
|
||||
|
||||
Il valore restituito viene inviato alla funzione di callback `cameraSuccess`, in uno dei seguenti formati, a seconda il `cameraOptions` specificato:
|
||||
|
||||
* A `String` contenente l'immagine della foto con codifica base64.
|
||||
|
||||
* A `String` che rappresenta il percorso del file di immagine su archiviazione locale (predefinito).
|
||||
|
||||
Si può fare quello che vuoi con l'immagine codificata o URI, ad esempio:
|
||||
|
||||
* Il rendering dell'immagine in un `<img>` tag, come nell'esempio qui sotto
|
||||
|
||||
* Salvare i dati localmente ( `LocalStorage` , [Lawnchair][1], ecc.)
|
||||
|
||||
* Inviare i dati a un server remoto
|
||||
|
||||
[1]: http://brianleroux.github.com/lawnchair/
|
||||
|
||||
**Nota**: risoluzione foto sui più recenti dispositivi è abbastanza buona. Foto selezionate dalla galleria del dispositivo non è percepiranno di qualità inferiore, anche se viene specificato un parametro di `quality`. Per evitare problemi di memoria comune, impostare `Camera.destinationType` `FILE_URI` piuttosto che `DATA_URL`.
|
||||
|
||||
### Piattaforme supportate
|
||||
|
||||
* Amazon fuoco OS
|
||||
* Android
|
||||
* BlackBerry 10
|
||||
* Browser
|
||||
* Firefox OS
|
||||
* iOS
|
||||
* Tizen
|
||||
* Windows Phone 7 e 8
|
||||
* Windows 8
|
||||
|
||||
### Preferenze (iOS)
|
||||
|
||||
* **CameraUsesGeolocation** (boolean, default è false). Per l'acquisizione di immagini JPEG, impostato su true per ottenere dati di geolocalizzazione nell'intestazione EXIF. Questo innescherà una richiesta per le autorizzazioni di geolocalizzazione, se impostato su true.
|
||||
|
||||
<preference name="CameraUsesGeolocation" value="false" />
|
||||
|
||||
|
||||
### Amazon fuoco OS stranezze
|
||||
|
||||
Amazon fuoco OS utilizza intenti a lanciare l'attività della fotocamera sul dispositivo per catturare immagini e sui telefoni con poca memoria, l'attività di Cordova può essere ucciso. In questo scenario, l'immagine potrebbe non apparire quando viene ripristinata l'attività di cordova.
|
||||
|
||||
### Stranezze Android
|
||||
|
||||
Android utilizza intenti a lanciare l'attività della fotocamera sul dispositivo per catturare immagini e sui telefoni con poca memoria, l'attività di Cordova può essere ucciso. In questo scenario, l'immagine potrebbe non apparire quando viene ripristinata l'attività di Cordova.
|
||||
|
||||
### Stranezze browser
|
||||
|
||||
Può restituire solo la foto come immagine con codifica base64.
|
||||
|
||||
### Firefox OS stranezze
|
||||
|
||||
Fotocamera plugin è attualmente implementato mediante [Web Activities][2].
|
||||
|
||||
[2]: https://hacks.mozilla.org/2013/01/introducing-web-activities/
|
||||
|
||||
### iOS stranezze
|
||||
|
||||
Compreso un JavaScript `alert()` in una delle funzioni di callback può causare problemi. Avvolgere l'avviso all'interno di un `setTimeout()` per consentire la selezione immagine iOS o muffin per chiudere completamente la prima che viene visualizzato l'avviso:
|
||||
|
||||
setTimeout(function() {
|
||||
// do your thing here!
|
||||
}, 0);
|
||||
|
||||
|
||||
### Windows Phone 7 stranezze
|
||||
|
||||
Richiamando l'applicazione nativa fotocamera mentre il dispositivo è collegato tramite Zune non funziona e innesca un callback di errore.
|
||||
|
||||
### Tizen stranezze
|
||||
|
||||
Tizen supporta solo a `destinationType` di `Camera.DestinationType.FILE_URI` e un `sourceType` di `Camera.PictureSourceType.PHOTOLIBRARY`.
|
||||
|
||||
### Esempio
|
||||
|
||||
Scattare una foto e recuperarla come un'immagine con codifica base64:
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.DATA_URL
|
||||
});
|
||||
|
||||
function onSuccess(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
|
||||
Scattare una foto e recuperare il percorso del file dell'immagine:
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.FILE_URI });
|
||||
|
||||
function onSuccess(imageURI) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = imageURI;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
|
||||
## CameraOptions
|
||||
|
||||
Parametri opzionali per personalizzare le impostazioni della fotocamera.
|
||||
|
||||
{ quality : 75,
|
||||
destinationType : Camera.DestinationType.DATA_URL,
|
||||
sourceType : Camera.PictureSourceType.CAMERA,
|
||||
allowEdit : true,
|
||||
encodingType: Camera.EncodingType.JPEG,
|
||||
targetWidth: 100,
|
||||
targetHeight: 100,
|
||||
popoverOptions: CameraPopoverOptions,
|
||||
saveToPhotoAlbum: false };
|
||||
|
||||
|
||||
### Opzioni
|
||||
|
||||
* **quality**: qualità dell'immagine salvata, espressa come un intervallo di 0-100, dove 100 è tipicamente piena risoluzione senza perdita di compressione file. Il valore predefinito è 50. *(Numero)* (Si noti che informazioni sulla risoluzione della fotocamera non sono disponibile).
|
||||
|
||||
* **destinationType**: Scegli il formato del valore restituito. Il valore predefinito è FILE_URI. Definito in `navigator.camera.DestinationType` *(numero)*
|
||||
|
||||
Camera.DestinationType = {
|
||||
DATA_URL : 0, // Return image as base64-encoded string
|
||||
FILE_URI : 1, // Return image file URI
|
||||
NATIVE_URI : 2 // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
|
||||
};
|
||||
|
||||
|
||||
* **sourceType**: impostare l'origine dell'immagine. Il valore predefinito è la fotocamera. Definito in `navigator.camera.PictureSourceType` *(numero)*
|
||||
|
||||
Camera.PictureSourceType = {
|
||||
PHOTOLIBRARY : 0,
|
||||
CAMERA : 1,
|
||||
SAVEDPHOTOALBUM : 2
|
||||
};
|
||||
|
||||
|
||||
* **Proprietà allowEdit**: consentire la semplice modifica dell'immagine prima di selezione. *(Booleano)*
|
||||
|
||||
* **encodingType**: scegliere il file immagine restituita di codifica. Predefinito è JPEG. Definito in `navigator.camera.EncodingType` *(numero)*
|
||||
|
||||
Camera.EncodingType = {
|
||||
JPEG : 0, // Return JPEG encoded image
|
||||
PNG : 1 // Return PNG encoded image
|
||||
};
|
||||
|
||||
|
||||
* **targetWidth**: larghezza in pixel all'immagine della scala. Deve essere usato con **targetHeight**. Proporzioni rimane costante. *(Numero)*
|
||||
|
||||
* **targetHeight**: altezza in pixel all'immagine della scala. Deve essere usato con **targetWidth**. Proporzioni rimane costante. *(Numero)*
|
||||
|
||||
* **mediaType**: impostare il tipo di supporto per scegliere da. Funziona solo quando `PictureSourceType` è `PHOTOLIBRARY` o `SAVEDPHOTOALBUM` . Definito in `nagivator.camera.MediaType` *(numero)*
|
||||
|
||||
Camera.MediaType = {
|
||||
PICTURE: 0, // allow selection of still pictures only. PER IMPOSTAZIONE PREDEFINITA. Will return format specified via DestinationType
|
||||
VIDEO: 1, // allow selection of video only, WILL ALWAYS RETURN FILE_URI
|
||||
ALLMEDIA : 2 // allow selection from all media types
|
||||
};
|
||||
|
||||
|
||||
* **correctOrientation**: ruotare l'immagine per correggere l'orientamento del dispositivo durante l'acquisizione. *(Booleano)*
|
||||
|
||||
* **saveToPhotoAlbum**: salvare l'immagine nell'album di foto sul dispositivo dopo la cattura. *(Booleano)*
|
||||
|
||||
* **popoverOptions**: solo iOS opzioni che specificano la posizione di muffin in iPad. Definito in`CameraPopoverOptions`.
|
||||
|
||||
* **cameraDirection**: scegliere la telecamera da utilizzare (o retro-frontale). Il valore predefinito è tornato. Definito in `navigator.camera.Direction` *(numero)*
|
||||
|
||||
Camera.Direction = {
|
||||
BACK : 0, // Use the back-facing camera
|
||||
FRONT : 1 // Use the front-facing camera
|
||||
};
|
||||
|
||||
|
||||
### Amazon fuoco OS stranezze
|
||||
|
||||
* Qualsiasi `cameraDirection` valore i risultati in una foto di lamatura.
|
||||
|
||||
* Ignora il `allowEdit` parametro.
|
||||
|
||||
* `Camera.PictureSourceType.PHOTOLIBRARY`e `Camera.PictureSourceType.SAVEDPHOTOALBUM` entrambi visualizzare l'album fotografico stesso.
|
||||
|
||||
### Stranezze Android
|
||||
|
||||
* Qualsiasi `cameraDirection` valore i risultati in una foto di lamatura.
|
||||
|
||||
* Ignora il `allowEdit` parametro.
|
||||
|
||||
* `Camera.PictureSourceType.PHOTOLIBRARY`e `Camera.PictureSourceType.SAVEDPHOTOALBUM` entrambi visualizzare l'album fotografico stesso.
|
||||
|
||||
### BlackBerry 10 capricci
|
||||
|
||||
* Ignora il `quality` parametro.
|
||||
|
||||
* Ignora il `allowEdit` parametro.
|
||||
|
||||
* `Camera.MediaType`non è supportato.
|
||||
|
||||
* Ignora il `correctOrientation` parametro.
|
||||
|
||||
* Ignora il `cameraDirection` parametro.
|
||||
|
||||
### Firefox OS stranezze
|
||||
|
||||
* Ignora il `quality` parametro.
|
||||
|
||||
* `Camera.DestinationType`viene ignorato e corrisponde a `1` (URI del file di immagine)
|
||||
|
||||
* Ignora il `allowEdit` parametro.
|
||||
|
||||
* Ignora il `PictureSourceType` parametro (utente ne sceglie in una finestra di dialogo)
|
||||
|
||||
* Ignora il`encodingType`
|
||||
|
||||
* Ignora le `targetWidth` e`targetHeight`
|
||||
|
||||
* `Camera.MediaType`non è supportato.
|
||||
|
||||
* Ignora il `correctOrientation` parametro.
|
||||
|
||||
* Ignora il `cameraDirection` parametro.
|
||||
|
||||
### iOS stranezze
|
||||
|
||||
* Impostare `quality` inferiore al 50 per evitare errori di memoria su alcuni dispositivi.
|
||||
|
||||
* Quando si utilizza `destinationType.FILE_URI` , foto vengono salvati nella directory temporanea dell'applicazione. Il contenuto della directory temporanea dell'applicazione viene eliminato quando l'applicazione termina.
|
||||
|
||||
### Tizen stranezze
|
||||
|
||||
* opzioni non supportate
|
||||
|
||||
* restituisce sempre un URI del FILE
|
||||
|
||||
### Windows Phone 7 e 8 stranezze
|
||||
|
||||
* Ignora il `allowEdit` parametro.
|
||||
|
||||
* Ignora il `correctOrientation` parametro.
|
||||
|
||||
* Ignora il `cameraDirection` parametro.
|
||||
|
||||
* Ignora il `saveToPhotoAlbum` parametro. IMPORTANTE: Tutte le immagini scattate con la fotocamera di cordova wp7/8 API vengono sempre copiate rotolo fotocamera del telefono cellulare. A seconda delle impostazioni dell'utente, questo potrebbe anche significare che l'immagine viene caricato in automatico a loro OneDrive. Questo potenzialmente potrebbe significare che l'immagine è disponibile a un pubblico più ampio di app destinate. Se questo un blocco dell'applicazione, sarà necessario implementare il CameraCaptureTask come documentato su msdn: <http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx> si può anche commentare o up-voto la questione correlata nel [tracciatore di problemi][3]
|
||||
|
||||
* Ignora la `mediaType` proprietà di `cameraOptions` come il SDK di Windows Phone non fornisce un modo per scegliere il video da PHOTOLIBRARY.
|
||||
|
||||
[3]: https://issues.apache.org/jira/browse/CB-2083
|
||||
|
||||
## CameraError
|
||||
|
||||
funzione di callback onError che fornisce un messaggio di errore.
|
||||
|
||||
function(message) {
|
||||
// Show a helpful message
|
||||
}
|
||||
|
||||
|
||||
### Parametri
|
||||
|
||||
* **message**: il messaggio è fornito dal codice nativo del dispositivo. *(String)*
|
||||
|
||||
## cameraSuccess
|
||||
|
||||
funzione di callback onSuccess che fornisce i dati di immagine.
|
||||
|
||||
function(imageData) {
|
||||
// Do something with the image
|
||||
}
|
||||
|
||||
|
||||
### Parametri
|
||||
|
||||
* **imageData**: Base64 codifica dei dati immagine, *o* il file di immagine URI, a seconda `cameraOptions` in vigore. *(String)*
|
||||
|
||||
### Esempio
|
||||
|
||||
// Show image
|
||||
//
|
||||
function cameraCallback(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverHandle
|
||||
|
||||
Un handle per la finestra di dialogo di muffin creato da `navigator.camera.getPicture`.
|
||||
|
||||
### Metodi
|
||||
|
||||
* **setPosition**: impostare la posizione dei muffin.
|
||||
|
||||
### Piattaforme supportate
|
||||
|
||||
* iOS
|
||||
|
||||
### setPosition
|
||||
|
||||
Impostare la posizione dei muffin.
|
||||
|
||||
**Parametri**:
|
||||
|
||||
* `cameraPopoverOptions`: il `CameraPopoverOptions` che specificare la nuova posizione
|
||||
|
||||
### Esempio
|
||||
|
||||
var cameraPopoverHandle = navigator.camera.getPicture(onSuccess, onFail,
|
||||
{ destinationType: Camera.DestinationType.FILE_URI,
|
||||
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
|
||||
popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)
|
||||
});
|
||||
|
||||
// Reposition the popover if the orientation changes.
|
||||
window.onorientationchange = function() {
|
||||
var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
|
||||
cameraPopoverHandle.setPosition(cameraPopoverOptions);
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverOptions
|
||||
|
||||
iOS solo parametri che specificano l'ancoraggio elemento posizione e freccia direzione il Muffin quando si selezionano le immagini dalla libreria un iPad o un album.
|
||||
|
||||
{ x : 0,
|
||||
y : 32,
|
||||
width : 320,
|
||||
height : 480,
|
||||
arrowDir : Camera.PopoverArrowDirection.ARROW_ANY
|
||||
};
|
||||
|
||||
|
||||
### CameraPopoverOptions
|
||||
|
||||
* **x**: pixel coordinata x dell'elemento dello schermo su cui ancorare il muffin. *(Numero)*
|
||||
|
||||
* **y**: coordinata y di pixel dell'elemento dello schermo su cui ancorare il muffin. *(Numero)*
|
||||
|
||||
* **width**: larghezza, in pixel, dell'elemento dello schermo su cui ancorare il muffin. *(Numero)*
|
||||
|
||||
* **height**: altezza, in pixel, dell'elemento dello schermo su cui ancorare il muffin. *(Numero)*
|
||||
|
||||
* **arrowDir**: direzione dovrebbe puntare la freccia il muffin. Definito in `Camera.PopoverArrowDirection` *(numero)*
|
||||
|
||||
Camera.PopoverArrowDirection = {
|
||||
ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants
|
||||
ARROW_DOWN : 2,
|
||||
ARROW_LEFT : 4,
|
||||
ARROW_RIGHT : 8,
|
||||
ARROW_ANY : 15
|
||||
};
|
||||
|
||||
|
||||
Si noti che la dimensione del muffin possa cambiare per regolare la direzione della freccia e l'orientamento dello schermo. Assicurarsi che tenere conto di modifiche di orientamento quando si specifica la posizione di elemento di ancoraggio.
|
||||
|
||||
## navigator.camera.cleanup
|
||||
|
||||
Rimuove intermedio foto scattate con la fotocamera da deposito temporaneo.
|
||||
|
||||
navigator.camera.cleanup( cameraSuccess, cameraError );
|
||||
|
||||
|
||||
### Descrizione
|
||||
|
||||
Rimuove i file di immagine intermedia che vengono tenuti in custodia temporanea dopo la chiamata a `camera.getPicture`. Si applica solo quando il valore di `Camera.sourceType` è uguale a `Camera.PictureSourceType.CAMERA` e il `Camera.destinationType` è uguale a `Camera.DestinationType.FILE_URI`.
|
||||
|
||||
### Piattaforme supportate
|
||||
|
||||
* iOS
|
||||
|
||||
### Esempio
|
||||
|
||||
navigator.camera.cleanup(onSuccess, onFail);
|
||||
|
||||
function onSuccess() {
|
||||
console.log("Camera cleanup success.")
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
434
doc/ja/index.md
Normal file
434
doc/ja/index.md
Normal file
@@ -0,0 +1,434 @@
|
||||
<!---
|
||||
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.
|
||||
-->
|
||||
|
||||
# cordova-plugin-camera
|
||||
|
||||
このプラグインは、写真を撮るため、システムのイメージ ライブラリからイメージを選択するために API を提供します、グローバル `navigator.camera` オブジェクトを定義します。
|
||||
|
||||
オブジェクトは、グローバル スコープの `ナビゲーター` に添付、それがないまで `deviceready` イベントの後。
|
||||
|
||||
document.addEventListener("deviceready", onDeviceReady, false);
|
||||
function onDeviceReady() {
|
||||
console.log(navigator.camera);
|
||||
}
|
||||
|
||||
|
||||
## インストール
|
||||
|
||||
cordova plugin add cordova-plugin-camera
|
||||
|
||||
|
||||
## navigator.camera.getPicture
|
||||
|
||||
カメラを使用して写真を取るか、デバイスの画像ギャラリーから写真を取得します。 イメージが渡されます成功時のコールバックを base64 エンコードされた `文字列`、または、URI としてイメージ ファイル。 メソッド自体はファイル選択ポップ オーバーの位置を変更するために使用できる `CameraPopoverHandle` オブジェクトを返します。
|
||||
|
||||
navigator.camera.getPicture( cameraSuccess, cameraError, cameraOptions );
|
||||
|
||||
|
||||
### 解説
|
||||
|
||||
`camera.getPicture` 関数は、ユーザーの写真をスナップすることができますデバイスのデフォルト カメラ アプリケーションを開きます。 `Camera.sourceType` が `Camera.PictureSourceType.CAMERA` と等しい場合既定では、この現象が発生します。 ユーザーは写真をスナップ、カメラ アプリケーションを閉じるし、アプリケーションが復元されます。
|
||||
|
||||
`Camera.sourceType` `Camera.PictureSourceType.PHOTOLIBRARY` または `Camera.PictureSourceType.SAVEDPHOTOALBUM` の場合、ダイアログ ボックスはユーザーを既存のイメージを選択することができますが表示されます。 `camera.getPicture` 関数は、デバイスの向きが変更されたとき、たとえば、イメージの選択ダイアログには、位置を変更するために使用することができます、`CameraPopoverHandle` オブジェクトを返します。
|
||||
|
||||
戻り値が `cameraSuccess` コールバック関数の指定 `cameraOptions` に応じて、次の形式のいずれかに送信されます。
|
||||
|
||||
* A `String` 写真の base64 でエンコードされたイメージを含んでいます。
|
||||
|
||||
* A `String` (既定値) のローカル記憶域上のイメージ ファイルの場所を表します。
|
||||
|
||||
自由に変更、エンコードされたイメージ、または URI などを行うことができます。
|
||||
|
||||
* イメージをレンダリングする `<img>` 以下の例のように、タグ
|
||||
|
||||
* ローカル データの保存 ( `LocalStorage` 、 [Lawnchair][1]など)。
|
||||
|
||||
* リモート サーバーにデータを投稿します。
|
||||
|
||||
[1]: http://brianleroux.github.com/lawnchair/
|
||||
|
||||
**注**: 新しいデバイス上の写真の解像度はかなり良いです。 デバイスのギャラリーから選択した写真は `quality` パラメーターが指定されて場合でも下方の品質に縮小されません。 一般的なメモリの問題を避けるために `DATA_URL` ではなく `FILE_URI` に `Camera.destinationType` を設定します。.
|
||||
|
||||
### サポートされているプラットフォーム
|
||||
|
||||
* アマゾン火 OS
|
||||
* アンドロイド
|
||||
* ブラックベリー 10
|
||||
* ブラウザー
|
||||
* Firefox の OS
|
||||
* iOS
|
||||
* Tizen
|
||||
* Windows Phone 7 と 8
|
||||
* Windows 8
|
||||
|
||||
### 環境設定 (iOS)
|
||||
|
||||
* **CameraUsesGeolocation**(ブール値、デフォルトは false)。 Jpeg 画像をキャプチャするため EXIF ヘッダーで地理位置情報データを取得する場合は true に設定します。 これは、場合地理位置情報のアクセス許可に対する要求をトリガーする true に設定します。
|
||||
|
||||
<preference name="CameraUsesGeolocation" value="false" />
|
||||
|
||||
|
||||
### アマゾン火 OS 癖
|
||||
|
||||
アマゾン火 OS イメージをキャプチャするデバイス上のカメラの活動を開始する意図を使用して、メモリの少ない携帯電話、コルドバ活動が殺されるかもしれない。 このシナリオではコルドバ活動が復元されると、イメージが表示されません。
|
||||
|
||||
### Android の癖
|
||||
|
||||
アンドロイド、イメージをキャプチャするデバイス上でカメラのアクティビティを開始する意図を使用し、メモリの少ない携帯電話、コルドバ活動が殺されるかもしれない。 このシナリオではコルドバ活動が復元されると、イメージが表示されません。
|
||||
|
||||
### ブラウザーの癖
|
||||
|
||||
Base64 エンコード イメージとして写真を返すのみことができます。
|
||||
|
||||
### Firefox OS 癖
|
||||
|
||||
カメラのプラグインは現在、[Web アクティビティ][2] を使用して実装されていた.
|
||||
|
||||
[2]: https://hacks.mozilla.org/2013/01/introducing-web-activities/
|
||||
|
||||
### iOS の癖
|
||||
|
||||
コールバック関数のいずれかの JavaScript `alert()` を含む問題が発生することができます。 IOS イメージ ピッカーまたは完全が終了するまで、警告が表示されますポップ オーバーを許可する `setTimeout()` 内でアラートをラップします。
|
||||
|
||||
setTimeout(function() {
|
||||
// do your thing here!
|
||||
}, 0);
|
||||
|
||||
|
||||
### Windows Phone 7 の癖
|
||||
|
||||
ネイティブ カメラ アプリケーションを呼び出すと、デバイスが Zune を介して接続されている動作しませんし、エラー コールバックをトリガーします。
|
||||
|
||||
### Tizen の癖
|
||||
|
||||
Tizen のみ `Camera.DestinationType.FILE_URI` の `destinationType` と `Camera.PictureSourceType.PHOTOLIBRARY` の `sourceType` をサポートしています.
|
||||
|
||||
### 例
|
||||
|
||||
写真を撮るし、base64 エンコード イメージとして取得します。
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.DATA_URL
|
||||
});
|
||||
|
||||
function onSuccess(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
|
||||
写真を撮るし、イメージのファイルの場所を取得します。
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.FILE_URI });
|
||||
|
||||
function onSuccess(imageURI) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = imageURI;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
|
||||
## CameraOptions
|
||||
|
||||
カメラの設定をカスタマイズするオプションのパラメーター。
|
||||
|
||||
{ quality : 75,
|
||||
destinationType : Camera.DestinationType.DATA_URL,
|
||||
sourceType : Camera.PictureSourceType.CAMERA,
|
||||
allowEdit : true,
|
||||
encodingType: Camera.EncodingType.JPEG,
|
||||
targetWidth: 100,
|
||||
targetHeight: 100,
|
||||
popoverOptions: CameraPopoverOptions,
|
||||
saveToPhotoAlbum: false };
|
||||
|
||||
|
||||
### オプション
|
||||
|
||||
* **quality**: 0-100、100 がファイルの圧縮から損失なしで通常のフル解像度の範囲で表される、保存されたイメージの品質。 既定値は 50 です。 *(数)*(カメラの解像度についての情報が利用できないことに注意してください)。
|
||||
|
||||
* **destinationType**: 戻り値の形式を選択します。既定値は FILE_URI です。定義されている `navigator.camera.DestinationType` *(番号)*
|
||||
|
||||
Camera.DestinationType = {
|
||||
DATA_URL : 0, // Return image as base64-encoded string
|
||||
FILE_URI : 1, // Return image file URI
|
||||
NATIVE_URI : 2 // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
|
||||
};
|
||||
|
||||
|
||||
* **sourceType**: 画像のソースを設定します。既定値は、カメラです。定義されている `navigator.camera.PictureSourceType` *(番号)*
|
||||
|
||||
Camera.PictureSourceType = {
|
||||
PHOTOLIBRARY : 0,
|
||||
CAMERA : 1,
|
||||
SAVEDPHOTOALBUM : 2
|
||||
};
|
||||
|
||||
|
||||
* **allowEdit**: 単純な選択の前に画像の編集を許可します。*(ブール値)*
|
||||
|
||||
* **encodingType**: 返されるイメージ ファイルのエンコーディングを選択します。デフォルトは JPEG です。定義されている `navigator.camera.EncodingType` *(番号)*
|
||||
|
||||
Camera.EncodingType = {
|
||||
JPEG : 0, // Return JPEG encoded image
|
||||
PNG : 1 // Return PNG encoded image
|
||||
};
|
||||
|
||||
|
||||
* **targetWidth**: スケール イメージにピクセル単位の幅。**TargetHeight**を使用する必要があります。縦横比は変わりません。*(数)*
|
||||
|
||||
* **targetHeight**: スケール イメージにピクセル単位の高さ。**TargetWidth**を使用する必要があります。縦横比は変わりません。*(数)*
|
||||
|
||||
* **mediaType**: から選択するメディアの種類を設定します。 場合にのみ働きます `PictureSourceType` は `PHOTOLIBRARY` または `SAVEDPHOTOALBUM` 。 定義されている `nagivator.camera.MediaType` *(番号)*
|
||||
|
||||
Camera.MediaType = {
|
||||
PICTURE: 0, // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
|
||||
VIDEO: 1, // allow selection of video only, WILL ALWAYS RETURN FILE_URI
|
||||
ALLMEDIA : 2 // allow selection from all media types
|
||||
};
|
||||
|
||||
|
||||
* **correctOrientation**: キャプチャ中に、デバイスの向きを修正する画像を回転させます。*(ブール値)*
|
||||
|
||||
* **saveToPhotoAlbum**: キャプチャ後、デバイス上のフォト アルバムに画像を保存します。*(ブール値)*
|
||||
|
||||
* **popoverOptions**: iPad のポップ オーバーの場所を指定する iOS のみのオプションです。定義されています。`CameraPopoverOptions`.
|
||||
|
||||
* **cameraDirection**: (前面または背面側) を使用するカメラを選択します。既定値は戻るです。定義されている `navigator.camera.Direction` *(番号)*
|
||||
|
||||
Camera.Direction = {
|
||||
BACK : 0, // Use the back-facing camera
|
||||
FRONT : 1 // Use the front-facing camera
|
||||
};
|
||||
|
||||
|
||||
### アマゾン火 OS 癖
|
||||
|
||||
* 任意 `cameraDirection` 背面写真で結果の値します。
|
||||
|
||||
* 無視、 `allowEdit` パラメーター。
|
||||
|
||||
* `Camera.PictureSourceType.PHOTOLIBRARY``Camera.PictureSourceType.SAVEDPHOTOALBUM`両方のアルバムが表示されます同じ写真。
|
||||
|
||||
### Android の癖
|
||||
|
||||
* 任意 `cameraDirection` 背面写真で結果の値します。
|
||||
|
||||
* 無視、 `allowEdit` パラメーター。
|
||||
|
||||
* `Camera.PictureSourceType.PHOTOLIBRARY``Camera.PictureSourceType.SAVEDPHOTOALBUM`両方のアルバムが表示されます同じ写真。
|
||||
|
||||
### ブラックベリー 10 癖
|
||||
|
||||
* 無視、 `quality` パラメーター。
|
||||
|
||||
* 無視、 `allowEdit` パラメーター。
|
||||
|
||||
* `Camera.MediaType`サポートされていません。
|
||||
|
||||
* 無視、 `correctOrientation` パラメーター。
|
||||
|
||||
* 無視、 `cameraDirection` パラメーター。
|
||||
|
||||
### Firefox OS 癖
|
||||
|
||||
* 無視、 `quality` パラメーター。
|
||||
|
||||
* `Camera.DestinationType`無視され、等しい `1` (イメージ ファイル URI)
|
||||
|
||||
* 無視、 `allowEdit` パラメーター。
|
||||
|
||||
* 無視、 `PictureSourceType` パラメーター (ユーザーが選択ダイアログ ウィンドウに)
|
||||
|
||||
* 無視します、`encodingType`
|
||||
|
||||
* 無視、 `targetWidth` と`targetHeight`
|
||||
|
||||
* `Camera.MediaType`サポートされていません。
|
||||
|
||||
* 無視、 `correctOrientation` パラメーター。
|
||||
|
||||
* 無視、 `cameraDirection` パラメーター。
|
||||
|
||||
### iOS の癖
|
||||
|
||||
* 設定 `quality` 一部のデバイスでメモリ不足エラーを避けるために 50 の下。
|
||||
|
||||
* 使用する場合 `destinationType.FILE_URI` 、写真、アプリケーションの一時ディレクトリに保存されます。アプリケーションの一時ディレクトリの内容は、アプリケーションの終了時に削除されます。
|
||||
|
||||
### Tizen の癖
|
||||
|
||||
* サポートされていないオプション
|
||||
|
||||
* 常にファイルの URI を返す
|
||||
|
||||
### Windows Phone 7 と 8 癖
|
||||
|
||||
* 無視、 `allowEdit` パラメーター。
|
||||
|
||||
* 無視、 `correctOrientation` パラメーター。
|
||||
|
||||
* 無視、 `cameraDirection` パラメーター。
|
||||
|
||||
* 無視、 `saveToPhotoAlbum` パラメーター。 重要: wp7/8 コルドバ カメラ API で撮影したすべての画像は携帯電話のカメラ巻き物に常にコピーします。 ユーザーの設定に応じて、これも、画像はその OneDrive に自動アップロードを意味できます。 イメージは意図したアプリより広い聴衆に利用できる可能性があります可能性があります。 場合は、このアプリケーションのブロッカー、msdn で説明されているように、CameraCaptureTask を実装する必要があります: <http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx>コメントにすることがありますもかアップ投票関連の問題を[課題追跡システム][3]で
|
||||
|
||||
* 無視、 `mediaType` のプロパティ `cameraOptions` として Windows Phone SDK には、フォト ライブラリからビデオを選択する方法は行いません。
|
||||
|
||||
[3]: https://issues.apache.org/jira/browse/CB-2083
|
||||
|
||||
## CameraError
|
||||
|
||||
エラー メッセージを提供する onError コールバック関数。
|
||||
|
||||
function(message) {
|
||||
// Show a helpful message
|
||||
}
|
||||
|
||||
|
||||
### パラメーター
|
||||
|
||||
* **message**: メッセージは、デバイスのネイティブ コードによって提供されます。*(文字列)*
|
||||
|
||||
## cameraSuccess
|
||||
|
||||
画像データを提供する onSuccess コールバック関数。
|
||||
|
||||
function(imageData) {
|
||||
// Do something with the image
|
||||
}
|
||||
|
||||
|
||||
### パラメーター
|
||||
|
||||
* **imagedata を扱う**: Base64 エンコード イメージのデータ、*または*画像ファイルによって URI の `cameraOptions` 効果。*(文字列)*
|
||||
|
||||
### 例
|
||||
|
||||
// Show image
|
||||
//
|
||||
function cameraCallback(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverHandle
|
||||
|
||||
`Navigator.camera.getPicture` によって作成されたポップオーバーパン ダイアログ ボックスへのハンドル.
|
||||
|
||||
### メソッド
|
||||
|
||||
* **setPosition**: ポップ オーバーの位置を設定します。
|
||||
|
||||
### サポートされているプラットフォーム
|
||||
|
||||
* iOS
|
||||
|
||||
### setPosition
|
||||
|
||||
ポップ オーバーの位置を設定します。
|
||||
|
||||
**パラメーター**:
|
||||
|
||||
* `cameraPopoverOptions`:、 `CameraPopoverOptions` の新しい位置を指定します。
|
||||
|
||||
### 例
|
||||
|
||||
var cameraPopoverHandle = navigator.camera.getPicture(onSuccess, onFail,
|
||||
{ destinationType: Camera.DestinationType.FILE_URI,
|
||||
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
|
||||
popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)
|
||||
});
|
||||
|
||||
// Reposition the popover if the orientation changes.
|
||||
window.onorientationchange = function() {
|
||||
var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
|
||||
cameraPopoverHandle.setPosition(cameraPopoverOptions);
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverOptions
|
||||
|
||||
iOS だけ指定パラメーターをポップ オーバーのアンカー要素の場所および矢印方向計算されたライブラリまたはアルバムから画像を選択するとき。
|
||||
|
||||
{ x : 0,
|
||||
y : 32,
|
||||
width : 320,
|
||||
height : 480,
|
||||
arrowDir : Camera.PopoverArrowDirection.ARROW_ANY
|
||||
};
|
||||
|
||||
|
||||
### CameraPopoverOptions
|
||||
|
||||
* **x**: ピクセルの x 座標画面要素にポップ オーバーのアンカーになります。*(数)*
|
||||
|
||||
* **y**: y ピクセル座標の画面要素にポップ オーバーのアンカーになります。*(数)*
|
||||
|
||||
* **width**: ポップ オーバーのアンカーになる上の画面要素のピクセル単位の幅。*(数)*
|
||||
|
||||
* **height**: ポップ オーバーのアンカーになる上の画面要素のピクセル単位の高さ。*(数)*
|
||||
|
||||
* **arrowDir**: 方向のポップ オーバーで矢印をポイントする必要があります。定義されている `Camera.PopoverArrowDirection` *(番号)*
|
||||
|
||||
Camera.PopoverArrowDirection = {
|
||||
ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants
|
||||
ARROW_DOWN : 2,
|
||||
ARROW_LEFT : 4,
|
||||
ARROW_RIGHT : 8,
|
||||
ARROW_ANY : 15
|
||||
};
|
||||
|
||||
|
||||
矢印の方向と、画面の向きを調整するポップ オーバーのサイズを変更可能性がありますに注意してください。 アンカー要素の位置を指定するときの方向の変化を考慮することを確認します。
|
||||
|
||||
## navigator.camera.cleanup
|
||||
|
||||
削除中間一時ストレージからカメラで撮影した写真。
|
||||
|
||||
navigator.camera.cleanup( cameraSuccess, cameraError );
|
||||
|
||||
|
||||
### 説明
|
||||
|
||||
`camera.getPicture` を呼び出した後一時記憶域に保存されている中間画像ファイルを削除します。 `Camera.sourceType` の値が `Camera.PictureSourceType.CAMERA` に等しい、`Camera.destinationType` が `Camera.DestinationType.FILE_URI` と等しいの場合にのみ適用されます。.
|
||||
|
||||
### サポートされているプラットフォーム
|
||||
|
||||
* iOS
|
||||
|
||||
### 例
|
||||
|
||||
navigator.camera.cleanup(onSuccess, onFail);
|
||||
|
||||
function onSuccess() {
|
||||
console.log("Camera cleanup success.")
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
434
doc/ko/index.md
Normal file
434
doc/ko/index.md
Normal file
@@ -0,0 +1,434 @@
|
||||
<!---
|
||||
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.
|
||||
-->
|
||||
|
||||
# cordova-plugin-camera
|
||||
|
||||
이 플러그인 시스템의 이미지 라이브러리에서 이미지를 선택 및 사진 촬영을 위한 API를 제공 하는 글로벌 `navigator.camera` 개체를 정의 합니다.
|
||||
|
||||
개체 `navigator` 글로벌 범위 첨부 아니에요 때까지 사용할 수 있는 `deviceready` 이벤트 후.
|
||||
|
||||
document.addEventListener("deviceready", onDeviceReady, false);
|
||||
function onDeviceReady() {
|
||||
console.log(navigator.camera);
|
||||
}
|
||||
|
||||
|
||||
## 설치
|
||||
|
||||
cordova plugin add cordova-plugin-camera
|
||||
|
||||
|
||||
## navigator.camera.getPicture
|
||||
|
||||
카메라를 사용 하 여 사진을 걸립니다 또는 소자의 이미지 갤러리에서 사진을 검색 합니다. 이미지는 성공 콜백에 전달 base64 인코딩된 `문자열` 또는 URI로 이미지 파일에 대 한. 방법 자체는 파일 선택 popover 위치를 사용할 수 있는 `CameraPopoverHandle` 개체를 반환 합니다.
|
||||
|
||||
navigator.camera.getPicture( cameraSuccess, cameraError, cameraOptions );
|
||||
|
||||
|
||||
### 설명
|
||||
|
||||
`Camera.getPicture` 함수 스냅 사진을 사용자가 소자의 기본 카메라 응용 프로그램을 엽니다. 이 문제는 `Camera.sourceType` `Camera.PictureSourceType.CAMERA` 경우 기본적으로 발생 합니다. 일단 사용자 스냅 사진, 카메라 응용 프로그램 종료 하 고 응용 프로그램 복원 됩니다.
|
||||
|
||||
`Camera.sourceType`은 `Camera.PictureSourceType.PHOTOLIBRARY` 또는 `Camera.PictureSourceType.SAVEDPHOTOALBUM`, 대화 상자가 사용자가 기존 이미지를 선택할 수 있도록 표시 됩니다. `camera.getPicture` 함수는 장치 방향 변경 될 때 이미지 선택 대화 상자, 예를 들어, 위치를 변경 하려면 사용할 수 있는 `CameraPopoverHandle` 개체를 반환 합니다.
|
||||
|
||||
반환 값은 `cameraSuccess` 콜백 함수 지정된 `cameraOptions`에 따라 다음 형식 중 하나에 전송 됩니다.
|
||||
|
||||
* A `String` base64 인코딩된 사진 이미지를 포함 합니다.
|
||||
|
||||
* A `String` 로컬 저장소 (기본값)의 이미지 파일 위치를 나타내는.
|
||||
|
||||
할 수 있는 당신이 원하는대로 인코딩된 이미지 또는 URI, 예를 들면:
|
||||
|
||||
* 렌더링 이미지는 `<img>` 아래 예제와 같이 태그
|
||||
|
||||
* 로컬로 데이터를 저장 ( `LocalStorage` , [Lawnchair][1], 등.)
|
||||
|
||||
* 원격 서버에 데이터 게시
|
||||
|
||||
[1]: http://brianleroux.github.com/lawnchair/
|
||||
|
||||
**참고**: 더 새로운 장치에 사진 해상도 아주 좋은. 소자의 갤러리에서 선택 된 사진 `품질` 매개 변수를 지정 하는 경우에 낮은 품질에 관하여 하지는. 일반적인 메모리 문제를 피하기 위해 `DATA_URL` 보다 `FILE_URI` `Camera.destinationType` 설정.
|
||||
|
||||
### 지원 되는 플랫폼
|
||||
|
||||
* 아마존 화재 운영 체제
|
||||
* 안 드 로이드
|
||||
* 블랙베리 10
|
||||
* 브라우저
|
||||
* Firefox 운영 체제
|
||||
* iOS
|
||||
* Tizen
|
||||
* Windows Phone 7과 8
|
||||
* 윈도우 8
|
||||
|
||||
### 환경 설정 (iOS)
|
||||
|
||||
* **CameraUsesGeolocation** (boolean, 기본값: false)입니다. 캡처 Jpeg, EXIF 헤더에 지리적 데이터를 true로 설정 합니다. 이 경우 위치 정보 사용 권한에 대 한 요청을 일으킬 것 이다 true로 설정 합니다.
|
||||
|
||||
<preference name="CameraUsesGeolocation" value="false" />
|
||||
|
||||
|
||||
### 아마존 화재 OS 단점
|
||||
|
||||
아마존 화재 OS 의도 사용 하 여 이미지 캡처 장치에서 카메라 활동을 시작 하 고 낮은 메모리와 휴대 전화에 코르 도우 바 활동 살해 수 있습니다. 코르도바 활동 복원 되 면이 시나리오에서는 이미지가 나타나지 않을 수 있습니다.
|
||||
|
||||
### 안 드 로이드 단점
|
||||
|
||||
안 드 로이드 의도 사용 하 여 이미지 캡처 장치에서 카메라 활동을 시작 하 고 낮은 메모리와 휴대 전화에 코르 도우 바 활동 살해 수 있습니다. 코르도바 활동 복원 되 면이 시나리오에서는 이미지가 나타나지 않을 수 있습니다.
|
||||
|
||||
### 브라우저 만지면
|
||||
|
||||
수 base64 인코딩 이미지로 사진을 반환 합니다.
|
||||
|
||||
### 파이어 폭스 OS 단점
|
||||
|
||||
카메라 플러그인은 현재 [웹 활동][2]를 사용 하 여 구현.
|
||||
|
||||
[2]: https://hacks.mozilla.org/2013/01/introducing-web-activities/
|
||||
|
||||
### iOS 단점
|
||||
|
||||
자바 `alert()`를 포함 하 여 콜백 함수 중 하나에 문제가 발생할 수 있습니다. 포장 허용 iOS 이미지 피커 또는 popover를 완벽 하 게 경고를 표시 하기 전에 닫습니다 `setTimeout()` 내에서 경고:
|
||||
|
||||
setTimeout(function() {
|
||||
// do your thing here!
|
||||
}, 0);
|
||||
|
||||
|
||||
### Windows Phone 7 단점
|
||||
|
||||
장치 Zune 통해 연결 된 동안 네이티브 카메라 응용 프로그램을 호출 하면 작동 하지 않습니다 하 고 오류 콜백 트리거합니다.
|
||||
|
||||
### Tizen 특수
|
||||
|
||||
`Camera.DestinationType.FILE_URI`의 `destinationType`와 `Camera.PictureSourceType.PHOTOLIBRARY`의 `sourceType` Tizen 지원.
|
||||
|
||||
### 예를 들어
|
||||
|
||||
촬영 및 base64 인코딩 이미지로 검색:
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.DATA_URL
|
||||
});
|
||||
|
||||
function onSuccess(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
|
||||
촬영 하 고 이미지의 파일 위치를 검색:
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.FILE_URI });
|
||||
|
||||
function onSuccess(imageURI) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = imageURI;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
|
||||
## CameraOptions
|
||||
|
||||
카메라 설정을 사용자 지정 하는 선택적 매개 변수.
|
||||
|
||||
{ quality : 75,
|
||||
destinationType : Camera.DestinationType.DATA_URL,
|
||||
sourceType : Camera.PictureSourceType.CAMERA,
|
||||
allowEdit : true,
|
||||
encodingType: Camera.EncodingType.JPEG,
|
||||
targetWidth: 100,
|
||||
targetHeight: 100,
|
||||
popoverOptions: CameraPopoverOptions,
|
||||
saveToPhotoAlbum: false };
|
||||
|
||||
|
||||
### 옵션
|
||||
|
||||
* **품질**: 범위 0-100, 100은 파일 압축에서 손실 없이 일반적으로 전체 해상도 저장된 된 이미지의 품질. 기본값은 50입니다. *(수)* (Note 카메라의 해상도 대 한 정보는 사용할 수 없습니다.)
|
||||
|
||||
* **destinationType**: 반환 값의 형식을 선택 합니다. 기본값은 FILE_URI입니다. 에 정의 된 `navigator.camera.DestinationType` *(수)*
|
||||
|
||||
Camera.DestinationType = {
|
||||
DATA_URL : 0, // Return image as base64-encoded string
|
||||
FILE_URI : 1, // Return image file URI
|
||||
NATIVE_URI : 2 // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
|
||||
};
|
||||
|
||||
|
||||
* **sourceType**: 그림의 소스를 설정 합니다. 기본값은 카메라입니다. 에 정의 된 `navigator.camera.PictureSourceType` *(수)*
|
||||
|
||||
Camera.PictureSourceType = {
|
||||
PHOTOLIBRARY : 0,
|
||||
CAMERA : 1,
|
||||
SAVEDPHOTOALBUM : 2
|
||||
};
|
||||
|
||||
|
||||
* **allowEdit**: 선택 하기 전에 이미지의 간단한 편집을 허용 합니다. *(부울)*
|
||||
|
||||
* **encodingType**: 반환 된 이미지 파일의 인코딩을 선택 합니다. 기본값은 JPEG입니다. 에 정의 된 `navigator.camera.EncodingType` *(수)*
|
||||
|
||||
Camera.EncodingType = {
|
||||
JPEG : 0, // Return JPEG encoded image
|
||||
PNG : 1 // Return PNG encoded image
|
||||
};
|
||||
|
||||
|
||||
* **targetWidth**: 스케일 이미지를 픽셀 너비. **TargetHeight**와 함께 사용 해야 합니다. 가로 세로 비율이 일정 하 게 유지 합니다. *(수)*
|
||||
|
||||
* **targetHeight**: 스케일 이미지를 픽셀 단위로 높이. **TargetWidth**와 함께 사용 해야 합니다. 가로 세로 비율이 일정 하 게 유지 합니다. *(수)*
|
||||
|
||||
* **mediaType**:에서 선택 미디어 유형을 설정 합니다. 때에 작동 `PictureSourceType` 는 `PHOTOLIBRARY` 또는 `SAVEDPHOTOALBUM` . 에 정의 된 `nagivator.camera.MediaType` *(수)*
|
||||
|
||||
Camera.MediaType = {
|
||||
PICTURE: 0, // allow selection of still pictures only. 기본입니다. Will return format specified via DestinationType
|
||||
VIDEO: 1, // allow selection of video only, WILL ALWAYS RETURN FILE_URI
|
||||
ALLMEDIA : 2 // allow selection from all media types
|
||||
};
|
||||
|
||||
|
||||
* **correctOrientation**: 캡처 도중 장치의 방향에 대 한 해결 하기 위해 이미지를 회전 합니다. *(부울)*
|
||||
|
||||
* **saveToPhotoAlbum**: 캡처 후 장치에서 사진 앨범에 이미지를 저장 합니다. *(부울)*
|
||||
|
||||
* **popoverOptions**: iPad에 popover 위치를 지정 하는 iOS 전용 옵션. 에 정의 된`CameraPopoverOptions`.
|
||||
|
||||
* **cameraDirection**: (앞 이나 뒤로-연결)를 사용 하 여 카메라를 선택 하십시오. 기본값은 다시. 에 정의 된 `navigator.camera.Direction` *(수)*
|
||||
|
||||
Camera.Direction = {
|
||||
BACK : 0, // Use the back-facing camera
|
||||
FRONT : 1 // Use the front-facing camera
|
||||
};
|
||||
|
||||
|
||||
### 아마존 화재 OS 단점
|
||||
|
||||
* 어떤 `cameraDirection` 다시 연결 사진에 결과 값.
|
||||
|
||||
* 무시는 `allowEdit` 매개 변수.
|
||||
|
||||
* `Camera.PictureSourceType.PHOTOLIBRARY`그리고 `Camera.PictureSourceType.SAVEDPHOTOALBUM` 둘 다 동일한 사진 앨범을 표시 합니다.
|
||||
|
||||
### 안 드 로이드 단점
|
||||
|
||||
* 어떤 `cameraDirection` 다시 연결 사진에 결과 값.
|
||||
|
||||
* 무시는 `allowEdit` 매개 변수.
|
||||
|
||||
* `Camera.PictureSourceType.PHOTOLIBRARY`그리고 `Camera.PictureSourceType.SAVEDPHOTOALBUM` 둘 다 동일한 사진 앨범을 표시 합니다.
|
||||
|
||||
### 블랙베리 10 단점
|
||||
|
||||
* 무시는 `quality` 매개 변수.
|
||||
|
||||
* 무시는 `allowEdit` 매개 변수.
|
||||
|
||||
* `Camera.MediaType`지원 되지 않습니다.
|
||||
|
||||
* 무시는 `correctOrientation` 매개 변수.
|
||||
|
||||
* 무시는 `cameraDirection` 매개 변수.
|
||||
|
||||
### 파이어 폭스 OS 단점
|
||||
|
||||
* 무시는 `quality` 매개 변수.
|
||||
|
||||
* `Camera.DestinationType`무시 되 고 `1` (이미지 파일 URI)
|
||||
|
||||
* 무시는 `allowEdit` 매개 변수.
|
||||
|
||||
* 무시는 `PictureSourceType` 매개 변수 (사용자가 선택 그것 대화 창에서)
|
||||
|
||||
* 무시 하는`encodingType`
|
||||
|
||||
* 무시는 `targetWidth` 와`targetHeight`
|
||||
|
||||
* `Camera.MediaType`지원 되지 않습니다.
|
||||
|
||||
* 무시는 `correctOrientation` 매개 변수.
|
||||
|
||||
* 무시는 `cameraDirection` 매개 변수.
|
||||
|
||||
### iOS 단점
|
||||
|
||||
* 설정 `quality` 일부 장치 메모리 오류를 피하기 위해 50 아래.
|
||||
|
||||
* 사용 하는 경우 `destinationType.FILE_URI` , 사진 응용 프로그램의 임시 디렉터리에 저장 됩니다. 응용 프로그램이 종료 될 때 응용 프로그램의 임시 디렉터리의 내용은 삭제 됩니다.
|
||||
|
||||
### Tizen 특수
|
||||
|
||||
* 지원 되지 않는 옵션
|
||||
|
||||
* 항상 파일 URI를 반환 합니다.
|
||||
|
||||
### Windows Phone 7, 8 특수
|
||||
|
||||
* 무시는 `allowEdit` 매개 변수.
|
||||
|
||||
* 무시는 `correctOrientation` 매개 변수.
|
||||
|
||||
* 무시는 `cameraDirection` 매개 변수.
|
||||
|
||||
* 무시는 `saveToPhotoAlbum` 매개 변수. 중요: 모든 이미지 API wp7/8 코르도바 카메라로 촬영 항상 복사 됩니다 휴대 전화의 카메라 롤에. 사용자의 설정에 따라이 또한 그들의 OneDrive에 자동 업로드 이미지는 의미. 이 잠재적으로 이미지는 당신의 애플 리 케이 션을 위한 보다 넓은 청중에 게 사용할 수 있는 의미. 이 경우 응용 프로그램에 대 한 차단, 당신은 msdn에 설명 대로 단말기를 구현 해야 합니다: <http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx> 수 있습니다 또한 의견 또는 [이슈 트래커][3] 에서 업-투표 관련된 문제
|
||||
|
||||
* 무시는 `mediaType` 속성을 `cameraOptions` 으로 Windows Phone SDK PHOTOLIBRARY에서 비디오를 선택 하는 방법을 제공 하지 않습니다.
|
||||
|
||||
[3]: https://issues.apache.org/jira/browse/CB-2083
|
||||
|
||||
## CameraError
|
||||
|
||||
오류 메시지를 제공 하는 onError 콜백 함수.
|
||||
|
||||
function(message) {
|
||||
// Show a helpful message
|
||||
}
|
||||
|
||||
|
||||
### 매개 변수
|
||||
|
||||
* **메시지**: 메시지는 장치의 네이티브 코드에 의해 제공 됩니다. *(문자열)*
|
||||
|
||||
## cameraSuccess
|
||||
|
||||
이미지 데이터를 제공 하는 onSuccess 콜백 함수.
|
||||
|
||||
function(imageData) {
|
||||
// Do something with the image
|
||||
}
|
||||
|
||||
|
||||
### 매개 변수
|
||||
|
||||
* **imageData**: Base64 인코딩은 이미지 데이터, *또는* 이미지 파일에 따라 URI의 `cameraOptions` 적용. *(문자열)*
|
||||
|
||||
### 예를 들어
|
||||
|
||||
// Show image
|
||||
//
|
||||
function cameraCallback(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverHandle
|
||||
|
||||
`navigator.camera.getPicture`에 의해 만들어진 popover 대화에 대 한 핸들.
|
||||
|
||||
### 메서드
|
||||
|
||||
* **setPosition**:는 popover의 위치를 설정 합니다.
|
||||
|
||||
### 지원 되는 플랫폼
|
||||
|
||||
* iOS
|
||||
|
||||
### setPosition
|
||||
|
||||
popover의 위치를 설정 합니다.
|
||||
|
||||
**매개 변수**:
|
||||
|
||||
* `cameraPopoverOptions`:는 `CameraPopoverOptions` 새 위치를 지정 하는
|
||||
|
||||
### 예를 들어
|
||||
|
||||
var cameraPopoverHandle = navigator.camera.getPicture(onSuccess, onFail,
|
||||
{ destinationType: Camera.DestinationType.FILE_URI,
|
||||
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
|
||||
popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)
|
||||
});
|
||||
|
||||
// Reposition the popover if the orientation changes.
|
||||
window.onorientationchange = function() {
|
||||
var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
|
||||
cameraPopoverHandle.setPosition(cameraPopoverOptions);
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverOptions
|
||||
|
||||
iOS 전용 매개 변수 iPad의 보관 함 또는 앨범에서 이미지를 선택 하면 앵커 요소 위치와 화살표의 방향으로 popover 지정 하는.
|
||||
|
||||
{ x : 0,
|
||||
y : 32,
|
||||
width : 320,
|
||||
height : 480,
|
||||
arrowDir : Camera.PopoverArrowDirection.ARROW_ANY
|
||||
};
|
||||
|
||||
|
||||
### CameraPopoverOptions
|
||||
|
||||
* **x**: x는 popover 앵커는 화면 요소의 픽셀 좌표. *(수)*
|
||||
|
||||
* **y**: y 픽셀 좌표는 popover 앵커는 화면 요소입니다. *(수)*
|
||||
|
||||
* **폭**: 폭 (픽셀)는 popover 앵커는 화면 요소. *(수)*
|
||||
|
||||
* **높이**: 높이 (픽셀)는 popover 앵커는 화면 요소. *(수)*
|
||||
|
||||
* **arrowDir**: 방향 화살표는 popover 가리켜야 합니다. 에 정의 된 `Camera.PopoverArrowDirection` *(수)*
|
||||
|
||||
Camera.PopoverArrowDirection = {
|
||||
ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants
|
||||
ARROW_DOWN : 2,
|
||||
ARROW_LEFT : 4,
|
||||
ARROW_RIGHT : 8,
|
||||
ARROW_ANY : 15
|
||||
};
|
||||
|
||||
|
||||
참고는 popover의 크기 조정 화살표 방향 및 화면 방향 변경 될 수 있습니다. 앵커 요소 위치를 지정 하는 경우 방향 변경에 대 한 계정에 있는지 확인 합니다.
|
||||
|
||||
## navigator.camera.cleanup
|
||||
|
||||
제거 임시 저장소에서 카메라로 찍은 사진을 중간.
|
||||
|
||||
navigator.camera.cleanup( cameraSuccess, cameraError );
|
||||
|
||||
|
||||
### 설명
|
||||
|
||||
`camera.getPicture`를 호출한 후 임시 저장소에 보관 됩니다 중간 이미지 파일을 제거 합니다. `Camera.sourceType` 값은 `Camera.PictureSourceType.CAMERA` 및 `Camera.destinationType`와 `Camera.DestinationType.FILE_URI` 때만 적용 됩니다..
|
||||
|
||||
### 지원 되는 플랫폼
|
||||
|
||||
* iOS
|
||||
|
||||
### 예를 들어
|
||||
|
||||
navigator.camera.cleanup(onSuccess, onFail);
|
||||
|
||||
function onSuccess() {
|
||||
console.log("Camera cleanup success.")
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
434
doc/pl/index.md
Normal file
434
doc/pl/index.md
Normal file
@@ -0,0 +1,434 @@
|
||||
<!---
|
||||
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.
|
||||
-->
|
||||
|
||||
# cordova-plugin-camera
|
||||
|
||||
Ten plugin definiuje obiekt globalny `navigator.camera`, który dostarcza API do robienia zdjęć i wybór zdjęć z biblioteki obrazów systemu.
|
||||
|
||||
Mimo, że obiekt jest dołączony do globalnego zakresu `navigator`, to nie dostępne dopiero po zdarzeniu `deviceready`.
|
||||
|
||||
document.addEventListener("deviceready", onDeviceReady, false);
|
||||
function onDeviceReady() {
|
||||
console.log(navigator.camera);
|
||||
}
|
||||
|
||||
|
||||
## Instalacja
|
||||
|
||||
cordova plugin add cordova-plugin-camera
|
||||
|
||||
|
||||
## navigator.camera.getPicture
|
||||
|
||||
Ma zdjęcia za pomocą aparatu, lub pobiera zdjęcia z urządzenia Galeria zdjęć. Obraz jest przekazywany do wywołania zwrotnego sukces jako kodowane algorytmem base64 `ciąg`, lub identyfikator URI dla pliku obrazu. Sama metoda zwraca obiekt `CameraPopoverHandle`, który może służyć do zmiany położenia pliku wyboru popover.
|
||||
|
||||
navigator.camera.getPicture( cameraSuccess, cameraError, cameraOptions );
|
||||
|
||||
|
||||
### Opis
|
||||
|
||||
Funkcja `camera.getPicture` otwiera urządzenia domyślnej aplikacji aparat fotograficzny ów pozwala użytkownik wobec chwycić zębami kino. To zachowanie występuje domyślnie, gdy `Camera.sourceType` jest równa `Camera.PictureSourceType.CAMERA`. Gdy użytkownik zaskoczy zdjęcie, ten aparat fotograficzny applicationâ zamyka i aplikacji jest przywracany.
|
||||
|
||||
Jeśli `Camera.sourceType` jest równe `Camera.PictureSourceType.PHOTOLIBRARY` lub `Camera.PictureSourceType.SAVEDPHOTOALBUM`, wtedy zostanie wyświetlone okno dialogowe pozwalające użytkownikowi na wybór istniejącego obrazu. Funkcja `camera.getPicture` zwraca obiekt `CameraPopoverHandle`, który obsługuje zmianę położenia okna wyboru obrazu, np. po zmianie orientacji urządzenia.
|
||||
|
||||
Zwracana wartość jest wysyłany do funkcji wywołania zwrotnego `cameraSuccess`, w jednym z następujących formatów, w zależności od określonego `cameraOptions`:
|
||||
|
||||
* `String` zawierający obraz zakodowany przy pomocy base64.
|
||||
|
||||
* `String` reprezentujący lokalizację pliku obrazu w lokalnym magazynie (domyślnie).
|
||||
|
||||
Może rób, co chcesz z zakodowany obraz lub identyfikatora URI, na przykład:
|
||||
|
||||
* Przedstawić obraz w tagu `<img>`, jak w przykładzie poniżej
|
||||
|
||||
* Zapisać lokalnie dane (`LocalStorage`, [Lawnchair][1], etc.)
|
||||
|
||||
* Wysłać dane na zdalny serwer
|
||||
|
||||
[1]: http://brianleroux.github.com/lawnchair/
|
||||
|
||||
**Uwaga**: zdjęcie rozdzielczości na nowsze urządzenia jest bardzo dobry. Zdjęcia wybrane z galerii urządzenia są nie przeskalowanych w dół do niższej jakości, nawet jeśli określono parametr `quality`. Aby uniknąć typowych problemów z pamięci, zestaw `Camera.destinationType` `FILE_URI` zamiast `DATA_URL`.
|
||||
|
||||
### Obsługiwane platformy
|
||||
|
||||
* Amazon Fire OS
|
||||
* Android
|
||||
* BlackBerry 10
|
||||
* Przeglądarka
|
||||
* Firefox OS
|
||||
* iOS
|
||||
* Tizen
|
||||
* Windows Phone 7 i 8
|
||||
* Windows 8
|
||||
|
||||
### Preferencje (iOS)
|
||||
|
||||
* **CameraUsesGeolocation** (boolean, wartość domyślna to false). Do przechwytywania JPEG, zestaw do true, aby uzyskać danych geolokalizacyjnych w nagłówku EXIF. To spowoduje wniosek o geolokalizacji uprawnienia, jeśli zestaw na wartość true.
|
||||
|
||||
<preference name="CameraUsesGeolocation" value="false" />
|
||||
|
||||
|
||||
### Amazon ogień OS dziwactwa
|
||||
|
||||
Amazon ogień OS używa intencje do rozpoczęcia działalności aparatu na urządzenie do przechwytywania obrazów, i na telefony z pamięci, Cordova aktywność może zostać zabity. W tym scenariuszu obraz mogą nie być wyświetlane po przywróceniu aktywności cordova.
|
||||
|
||||
### Dziwactwa Androida
|
||||
|
||||
Android używa intencje do rozpoczęcia działalności aparatu na urządzenie do przechwytywania obrazów, i na telefony z pamięci, Cordova aktywność może zostać zabity. W tym scenariuszu obraz mogą nie być wyświetlane po przywróceniu aktywności Cordova.
|
||||
|
||||
### Quirks przeglądarki
|
||||
|
||||
Może zwracać tylko zdjęcia jako obraz w formacie algorytmem base64.
|
||||
|
||||
### Firefox OS dziwactwa
|
||||
|
||||
Aparat plugin jest obecnie implementowane za pomocą [Działania sieci Web][2].
|
||||
|
||||
[2]: https://hacks.mozilla.org/2013/01/introducing-web-activities/
|
||||
|
||||
### Dziwactwa iOS
|
||||
|
||||
W jednej z funkcji wywołania zwrotnego w tym JavaScript `alert()` może powodować problemy. Owinąć w `setTimeout()` umożliwia wybór obrazu iOS lub popover całkowicie zamknąć zanim wyświetli alert alert:
|
||||
|
||||
setTimeout(function() {
|
||||
// do your thing here!
|
||||
}, 0);
|
||||
|
||||
|
||||
### Dziwactwa Windows Phone 7
|
||||
|
||||
Wywoływanie aparat native aplikacji, podczas gdy urządzenie jest podłączone przez Zune nie działa i powoduje błąd wywołania zwrotnego.
|
||||
|
||||
### Dziwactwa Tizen
|
||||
|
||||
Tizen obsługuje tylko `destinationType` z `Camera.DestinationType.FILE_URI` i `sourceType` z `Camera.PictureSourceType.PHOTOLIBRARY`.
|
||||
|
||||
### Przykład
|
||||
|
||||
Zrób zdjęcie i pobrać go jako kodowane algorytmem base64 obrazu:
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.DATA_URL
|
||||
});
|
||||
|
||||
function onSuccess(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
|
||||
Zrób zdjęcie i pobrać lokalizacji pliku obrazu:
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.FILE_URI });
|
||||
|
||||
function onSuccess(imageURI) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = imageURI;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
|
||||
## CameraOptions
|
||||
|
||||
Opcjonalne parametry, aby dostosować ustawienia aparatu.
|
||||
|
||||
{ quality : 75,
|
||||
destinationType : Camera.DestinationType.DATA_URL,
|
||||
sourceType : Camera.PictureSourceType.CAMERA,
|
||||
allowEdit : true,
|
||||
encodingType: Camera.EncodingType.JPEG,
|
||||
targetWidth: 100,
|
||||
targetHeight: 100,
|
||||
popoverOptions: CameraPopoverOptions,
|
||||
saveToPhotoAlbum: false };
|
||||
|
||||
|
||||
### Opcje
|
||||
|
||||
* **quality**: Jakość zapisywanego obrazu, wyrażona w przedziale 0-100, gdzie 100 zazwyczaj jest maksymalną rozdzielczością bez strat w czasie kompresji pliku. Wartością domyślną jest 50. *(Liczba)* (Pamiętaj, że informacja o rozdzielczości aparatu jest niedostępna.)
|
||||
|
||||
* **destinationType**: Wybierz format zwracanej wartości. Wartością domyślną jest FILE_URI. Zdefiniowane w `navigator.camera.DestinationType` *(numer)*
|
||||
|
||||
Camera.DestinationType = {
|
||||
DATA_URL : 0, // Return image as base64-encoded string
|
||||
FILE_URI : 1, // Return image file URI
|
||||
NATIVE_URI : 2 // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
|
||||
};
|
||||
|
||||
|
||||
* **sourceType**: Ustaw źródło obrazu. Wartością domyślną jest aparat fotograficzny. Zdefiniowane w `navigator.camera.PictureSourceType` *(numer)*
|
||||
|
||||
Camera.PictureSourceType = {
|
||||
PHOTOLIBRARY : 0,
|
||||
CAMERA : 1,
|
||||
SAVEDPHOTOALBUM : 2
|
||||
};
|
||||
|
||||
|
||||
* **allowEdit**: Pozwala na prostą edycję obrazu przed zaznaczeniem. *(Boolean)*
|
||||
|
||||
* **encodingType**: Wybierz plik obrazu zwracany jest kodowanie. Domyślnie jest JPEG. Zdefiniowane w `navigator.camera.EncodingType` *(numer)*
|
||||
|
||||
Camera.EncodingType = {
|
||||
JPEG : 0, // Return JPEG encoded image
|
||||
PNG : 1 // Return PNG encoded image
|
||||
};
|
||||
|
||||
|
||||
* **targetWidth**: Szerokość w pikselach skalowanego obrazu. Musi być użyte z **targetHeight**. Współczynnik proporcji pozostaje stały. *(Liczba)*
|
||||
|
||||
* **targetHeight**: Wysokość w pikselach skalowanego obrazu. Musi być użyte z **targetWidth**. Współczynnik proporcji pozostaje stały. *(Liczba)*
|
||||
|
||||
* **mediaType**: Ustawia typ nośnika, z którego będzie wybrany. Działa tylko wtedy, gdy `PictureSourceType` jest `PHOTOLIBRARY` lub `SAVEDPHOTOALBUM`. Zdefiniowane w `nagivator.camera.MediaType` *(Liczba)*
|
||||
|
||||
Camera.MediaType = {
|
||||
PICTURE: 0, // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
|
||||
VIDEO: 1, // allow selection of video only, WILL ALWAYS RETURN FILE_URI
|
||||
ALLMEDIA : 2 // allow selection from all media types
|
||||
};
|
||||
|
||||
|
||||
* **correctOrientation**: Obraca obraz aby skorygować orientację urządzenia podczas przechwytywania. *(Boolean)*
|
||||
|
||||
* **saveToPhotoAlbum**: Po przechwyceniu zapisuje na urządzeniu obraz w albumie na zdjęcia. *(Boolean)*
|
||||
|
||||
* **popoverOptions**: Opcja tylko dla platformy iOS, która określa położenie wyskakującego okna na iPadzie. Zdefiniowane w `CameraPopoverOptions`.
|
||||
|
||||
* **cameraDirection**: Wybierz aparat do korzystania (lub z powrotem przodem). Wartością domyślną jest z powrotem. Zdefiniowane w `navigator.camera.Direction` *(numer)*
|
||||
|
||||
Camera.Direction = {
|
||||
BACK : 0, // Use the back-facing camera
|
||||
FRONT : 1 // Use the front-facing camera
|
||||
};
|
||||
|
||||
|
||||
### Amazon ogień OS dziwactwa
|
||||
|
||||
* Jakakolwiek wartość w `cameraDirection` skutkuje użyciem tylnej kamery.
|
||||
|
||||
* Parametr `allowEdit` jest ignorowany.
|
||||
|
||||
* Oba parametry `Camera.PictureSourceType.PHOTOLIBRARY` oraz `Camera.PictureSourceType.SAVEDPHOTOALBUM` wyświetlają ten sam album ze zdjęciami.
|
||||
|
||||
### Dziwactwa Androida
|
||||
|
||||
* Jakakolwiek wartość w `cameraDirection` skutkuje użyciem tylnej kamery.
|
||||
|
||||
* Parametr `allowEdit` jest ignorowany.
|
||||
|
||||
* Oba parametry `Camera.PictureSourceType.PHOTOLIBRARY` oraz `Camera.PictureSourceType.SAVEDPHOTOALBUM` wyświetlają ten sam album ze zdjęciami.
|
||||
|
||||
### Jeżyna 10 dziwactwa
|
||||
|
||||
* Parametr `quality` jest ignorowany.
|
||||
|
||||
* Parametr `allowEdit` jest ignorowany.
|
||||
|
||||
* Nie jest wspierane `Camera.MediaType`.
|
||||
|
||||
* Parametr `correctOrientation` jest ignorowany.
|
||||
|
||||
* Parametr `cameraDirection` jest ignorowany.
|
||||
|
||||
### Firefox OS dziwactwa
|
||||
|
||||
* Parametr `quality` jest ignorowany.
|
||||
|
||||
* `Camera.DestinationType`jest ignorowane i jest równa `1` (plik obrazu URI)
|
||||
|
||||
* Parametr `allowEdit` jest ignorowany.
|
||||
|
||||
* Ignoruje `PictureSourceType` parametr (użytkownik wybiera go w oknie dialogowym)
|
||||
|
||||
* Ignoruje`encodingType`
|
||||
|
||||
* Ignoruje `targetWidth` i`targetHeight`
|
||||
|
||||
* Nie jest wspierane `Camera.MediaType`.
|
||||
|
||||
* Parametr `correctOrientation` jest ignorowany.
|
||||
|
||||
* Parametr `cameraDirection` jest ignorowany.
|
||||
|
||||
### Dziwactwa iOS
|
||||
|
||||
* Ustaw `quality` poniżej 50 aby uniknąć błędów pamięci na niektórych urządzeniach.
|
||||
|
||||
* Podczas korzystania z `destinationType.FILE_URI` , zdjęcia są zapisywane w katalogu tymczasowego stosowania. Zawartość katalogu tymczasowego stosowania jest usuwany po zakończeniu aplikacji.
|
||||
|
||||
### Dziwactwa Tizen
|
||||
|
||||
* opcje nie są obsługiwane
|
||||
|
||||
* zawsze zwraca FILE URI
|
||||
|
||||
### Windows Phone 7 i 8 dziwactwa
|
||||
|
||||
* Parametr `allowEdit` jest ignorowany.
|
||||
|
||||
* Parametr `correctOrientation` jest ignorowany.
|
||||
|
||||
* Parametr `cameraDirection` jest ignorowany.
|
||||
|
||||
* Ignoruje `saveToPhotoAlbum` parametr. Ważne: Wszystkie zdjęcia zrobione aparatem wp7/8 cordova API są zawsze kopiowane do telefonu w kamerze. W zależności od ustawień użytkownika może to też oznaczać że obraz jest automatycznie przesłane do ich OneDrive. Potencjalnie może to oznaczać, że obraz jest dostępne dla szerszego grona odbiorców niż Twoja aplikacja przeznaczona. Jeśli ten bloker aplikacji, trzeba będzie wdrożenie CameraCaptureTask, opisane na msdn: <http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx> można także komentarz lub górę głosowanie powiązanych kwestii w [śledzenia błędów][3]
|
||||
|
||||
* Ignoruje `mediaType` Właściwość `cameraOptions` jako SDK Windows Phone nie umożliwiają wybór filmów z PHOTOLIBRARY.
|
||||
|
||||
[3]: https://issues.apache.org/jira/browse/CB-2083
|
||||
|
||||
## CameraError
|
||||
|
||||
funkcja wywołania zwrotnego PrzyBłędzie, która zawiera komunikat o błędzie.
|
||||
|
||||
function(message) {
|
||||
// Show a helpful message
|
||||
}
|
||||
|
||||
|
||||
### Parametry
|
||||
|
||||
* **message**: Natywny kod komunikatu zapewniany przez urządzenie. *(Ciąg znaków)*
|
||||
|
||||
## cameraSuccess
|
||||
|
||||
onSuccess funkcji wywołania zwrotnego, który dostarcza dane obrazu.
|
||||
|
||||
function(imageData) {
|
||||
// Do something with the image
|
||||
}
|
||||
|
||||
|
||||
### Parametry
|
||||
|
||||
* **imageData**: Dane obrazu kodowane przy pomocy Base64 *lub* URI pliku obrazu, w zależności od użycia `cameraOptions`. *(Ciąg znaków)*
|
||||
|
||||
### Przykład
|
||||
|
||||
// Show image
|
||||
//
|
||||
function cameraCallback(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverHandle
|
||||
|
||||
Uchwyt do okna dialogowego popover, stworzony przez `navigator.camera.getPicture`.
|
||||
|
||||
### Metody
|
||||
|
||||
* **setPosition**: Ustawia pozycję wyskakującego okna.
|
||||
|
||||
### Obsługiwane platformy
|
||||
|
||||
* iOS
|
||||
|
||||
### setPosition
|
||||
|
||||
Ustaw pozycję popover.
|
||||
|
||||
**Parametry**:
|
||||
|
||||
* `cameraPopoverOptions`: `CameraPopoverOptions`, która określa nową pozycję
|
||||
|
||||
### Przykład
|
||||
|
||||
var cameraPopoverHandle = navigator.camera.getPicture(onSuccess, onFail,
|
||||
{ destinationType: Camera.DestinationType.FILE_URI,
|
||||
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
|
||||
popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)
|
||||
});
|
||||
|
||||
// Reposition the popover if the orientation changes.
|
||||
window.onorientationchange = function() {
|
||||
var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
|
||||
cameraPopoverHandle.setPosition(cameraPopoverOptions);
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverOptions
|
||||
|
||||
tylko do iOS parametrami, które określić kotwicy element lokalizacji i strzałka kierunku popover, przy wyborze zdjęć z iPad biblioteki lub album.
|
||||
|
||||
{ x : 0,
|
||||
y : 32,
|
||||
width : 320,
|
||||
height : 480,
|
||||
arrowDir : Camera.PopoverArrowDirection.ARROW_ANY
|
||||
};
|
||||
|
||||
|
||||
### CameraPopoverOptions
|
||||
|
||||
* **x**: współrzędna piksela x elementu ekranu, na którym zakotwiczone jest wyskakujące okno. *(Liczba)*
|
||||
|
||||
* **y**: współrzędna piksela y elementu ekranu, na którym zakotwiczone jest wyskakujące okno. *(Liczba)*
|
||||
|
||||
* **width**: szerokość w pikselach elementu ekranu, na którym zakotwiczone jest wyskakujące okno. *(Liczba)*
|
||||
|
||||
* **height**: wysokość w pikselach elementu ekranu, na którym zakotwiczone jest wyskakujące okno. *(Liczba)*
|
||||
|
||||
* **arrowDir**: Kierunek, który powinna wskazywać strzałka na wyskakującym oknie. Zdefiniowane w `Camera.PopoverArrowDirection` *(Liczba)*
|
||||
|
||||
Camera.PopoverArrowDirection = {
|
||||
ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants
|
||||
ARROW_DOWN : 2,
|
||||
ARROW_LEFT : 4,
|
||||
ARROW_RIGHT : 8,
|
||||
ARROW_ANY : 15
|
||||
};
|
||||
|
||||
|
||||
Należy pamiętać, że rozmiar popover może zmienić aby zmienić kierunek strzałki i orientacji ekranu. Upewnij się uwzględnić zmiany orientacji podczas określania położenia elementu kotwicy.
|
||||
|
||||
## navigator.camera.cleanup
|
||||
|
||||
Usuwa pośrednie zdjęcia zrobione przez aparat z czasowego składowania.
|
||||
|
||||
navigator.camera.cleanup( cameraSuccess, cameraError );
|
||||
|
||||
|
||||
### Opis
|
||||
|
||||
Usuwa pliki obrazów pośrednich, które są przechowywane w pamięci tymczasowej po wywołaniu `camera.getPicture`. Ma zastosowanie tylko, gdy wartość `Camera.sourceType` jest równa `Camera.PictureSourceType.CAMERA` i `Camera.destinationType` jest równa `Camera.DestinationType.FILE_URI`.
|
||||
|
||||
### Obsługiwane platformy
|
||||
|
||||
* iOS
|
||||
|
||||
### Przykład
|
||||
|
||||
navigator.camera.cleanup(onSuccess, onFail);
|
||||
|
||||
function onSuccess() {
|
||||
console.log("Camera cleanup success.")
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
417
doc/ru/index.md
Normal file
417
doc/ru/index.md
Normal file
@@ -0,0 +1,417 @@
|
||||
<!---
|
||||
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.
|
||||
-->
|
||||
|
||||
# cordova-plugin-camera
|
||||
|
||||
Этот плагин предоставляет API для съемки и для выбора изображения из библиотеки изображений системы.
|
||||
|
||||
cordova plugin add cordova-plugin-camera
|
||||
|
||||
|
||||
## navigator.camera.getPicture
|
||||
|
||||
Снимает фотографию с помощью камеры, или получает фотографию из галереи изображений устройства. Изображение передается на функцию обратного вызова успешного завершения как `String` в base64-кодировке, или как URI указывающего на файл изображения. Метод возвращает объект `CameraPopoverHandle`, который может использоваться для перемещения инструмента выбора файла.
|
||||
|
||||
navigator.camera.getPicture( cameraSuccess, cameraError, cameraOptions );
|
||||
|
||||
|
||||
### Описание
|
||||
|
||||
Функция `camera.getPicture` открывает приложение камеры устройства, которое позволяет снимать фотографии. Это происходит по умолчанию, когда `Camera.sourceType` равно `Camera.PictureSourceType.CAMERA` . Как только пользователь делает снимок,приложение камеры закрывается и приложение восстанавливается.
|
||||
|
||||
Если `Camera.sourceType` является `Camera.PictureSourceType.PHOTOLIBRARY` или `Camera.PictureSourceType.SAVEDPHOTOALBUM` , то показывается диалоговое окно, которое позволяет пользователям выбрать существующее изображение. Функция `camera.getPicture` возвращает объект `CameraPopoverHandle` объект, который может использоваться для перемещения диалога выбора изображения, например, при изменении ориентации устройства.
|
||||
|
||||
Возвращаемое значение отправляется в функцию обратного вызова `cameraSuccess` в одном из следующих форматов, в зависимости от параметра `cameraOptions` :
|
||||
|
||||
* A объект `String` содержащий фото изображение в base64-кодировке.
|
||||
|
||||
* Объект `String` представляющий расположение файла изображения на локальном хранилище (по умолчанию).
|
||||
|
||||
Вы можете сделать все, что угодно вы хотите с закодированным изображением или URI, например:
|
||||
|
||||
* Отобразить изображение с помощью тега `<img>`, как показано в примере ниже
|
||||
|
||||
* Сохранять данные локально (`LocalStorage`, [Lawnchair][1], и т.д.)
|
||||
|
||||
* Отправлять данные на удаленный сервер
|
||||
|
||||
[1]: http://brianleroux.github.com/lawnchair/
|
||||
|
||||
**Примечание**: разрешение фото на более новых устройствах является достаточно хорошим. Фотографии из галереи устройства не масштабируются к более низкому качеству, даже если указан параметр `quality`. Чтобы избежать общих проблем с памятью, установите `Camera.destinationType` в `FILE_URI` вместо `DATA_URL`.
|
||||
|
||||
### Поддерживаемые платформы
|
||||
|
||||
* Amazon Fire OS
|
||||
* Android
|
||||
* BlackBerry 10
|
||||
* Обозреватель
|
||||
* Firefox OS
|
||||
* iOS
|
||||
* Tizen
|
||||
* Windows Phone 7 и 8
|
||||
* Windows 8
|
||||
|
||||
### Предпочтения (iOS)
|
||||
|
||||
* **CameraUsesGeolocation** (логическое значение, по умолчанию false). Для захвата изображения JPEG, значение true, чтобы получить данные геопозиционирования в заголовке EXIF. Это вызовет запрос на разрешения геолокации, если задано значение true.
|
||||
|
||||
<preference name="CameraUsesGeolocation" value="false" />
|
||||
|
||||
|
||||
### Особенности Amazon Fire OS
|
||||
|
||||
Amazon Fire OS используют намерения для запуска активности камеры на устройстве для съемки фотографий, и на устройствах с низким объемам памяти, активность Cordova может быть завершена. В этом случае изображение может не появиться при восстановлении активности Cordova.
|
||||
|
||||
### Особенности Android
|
||||
|
||||
Android используют намерения для запуска активности камеры на устройстве для съемки фотографий, и на устройствах с низким объемам памяти, активность Cordova может быть завершена. В этом случае изображение может не появиться при восстановлении активности Cordova.
|
||||
|
||||
### Браузер причуды
|
||||
|
||||
Может возвращать только фотографии как изображения в кодировке base64.
|
||||
|
||||
### Особенности Firefox OS
|
||||
|
||||
Плагин Camera на данный момент реализован с использованием [Web Activities][2].
|
||||
|
||||
[2]: https://hacks.mozilla.org/2013/01/introducing-web-activities/
|
||||
|
||||
### Особенности iOS
|
||||
|
||||
Включение функции JavaScript `alert()` в любой из функций обратного вызова функции может вызвать проблемы. Оберните вызов alert в `setTimeout()` для позволения окну выбора изображений iOS полностью закрыться перед отображение оповещения:
|
||||
|
||||
setTimeout(function() {/ / ваши вещи!}, 0);
|
||||
|
||||
|
||||
### Особенности Windows Phone 7
|
||||
|
||||
Вызов встроенного приложения камеры, в то время как устройство подключено к Zune не работает, и инициирует обратный вызов для ошибки.
|
||||
|
||||
### Особенности Tizen
|
||||
|
||||
Tizen поддерживает только значение `destinationType` равное `Camera.DestinationType.FILE_URI` и значение `sourceType` равное `Camera.PictureSourceType.PHOTOLIBRARY`.
|
||||
|
||||
### Пример
|
||||
|
||||
Сделайте фотографию и получите его как изображение в base64-кодировке:
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.DATA_URL
|
||||
});
|
||||
|
||||
function onSuccess(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
|
||||
Сделайте фотографию и получить расположение файла с изображением:
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.FILE_URI });
|
||||
|
||||
function onSuccess(imageURI) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = imageURI;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
|
||||
## CameraOptions
|
||||
|
||||
Необязательные параметры для настройки параметров камеры.
|
||||
|
||||
{ quality : 75,
|
||||
destinationType : Camera.DestinationType.DATA_URL,
|
||||
sourceType : Camera.PictureSourceType.CAMERA,
|
||||
allowEdit : true,
|
||||
encodingType: Camera.EncodingType.JPEG,
|
||||
targetWidth: 100,
|
||||
targetHeight: 100,
|
||||
popoverOptions: CameraPopoverOptions,
|
||||
saveToPhotoAlbum: false };
|
||||
|
||||
|
||||
### Параметры
|
||||
|
||||
* **quality**: качество сохраняемого изображения, выражается в виде числа в диапазоне от 0 до 100, где 100 является обычно полным изображением без потери качества при сжатии. Значение по умолчанию — 50. *(Число)* (Обратите внимание, что информация о разрешении камеры недоступна.)
|
||||
|
||||
* **параметр destinationType**: выберите формат возвращаемого значения. Значение по умолчанию — FILE_URI. Определяется в `navigator.camera.DestinationType` *(число)*
|
||||
|
||||
Camera.DestinationType = {
|
||||
DATA_URL: 0, / / возвращение изображения в base64-кодировке строки
|
||||
FILE_URI: 1, / / возврат файла изображения URI
|
||||
NATIVE_URI: 2 / / возвращение образа собственного URI (например, Библиотека активов: / / на iOS или содержание: / / на андроиде)
|
||||
};
|
||||
|
||||
|
||||
* **тип источника**: установить источник рисунка. По умолчанию используется камера. Определяется в `navigator.camera.PictureSourceType` *(число)*
|
||||
|
||||
Camera.PictureSourceType = {
|
||||
PHOTOLIBRARY: 0,
|
||||
CAMERA: 1,
|
||||
SAVEDPHOTOALBUM: 2
|
||||
};
|
||||
|
||||
|
||||
* **allowEdit**: позволит редактирование изображения средствами телефона перед окончательным выбором изображения. *(Логический)*
|
||||
|
||||
* **Тип_шифрования**: выберите возвращенный файл в кодировку. Значение по умолчанию — JPEG. Определяется в `navigator.camera.EncodingType` *(число)*
|
||||
|
||||
Camera.EncodingType = {
|
||||
JPEG: 0, // возвращает изображение в формате JPEG
|
||||
PNG: 1 // возвращает рисунок в формате PNG
|
||||
};
|
||||
|
||||
|
||||
* **targetWidth**: ширина изображения в пикселах к которой необходимо осуществить масштабирование. Это значение должно использоваться совместно с **targetHeight**. Пропорции изображения останутся неизменными. *(Число)*
|
||||
|
||||
* **targetHeight**: высота изображения в пикселах к которой необходимо осуществить масштабирование. Это значение должно использоваться совместно с **targetWidth**. Пропорции изображения останутся неизменными. *(Число)*
|
||||
|
||||
* **тип носителя**: Установите источник получения изображения, из которого надо выбрать изображение. Работает только если `PictureSourceType` равно `PHOTOLIBRARY` или `SAVEDPHOTOALBUM` . Определяется в `nagivator.camera.MediaType` *(число)*
|
||||
|
||||
Camera.MediaType = {
|
||||
PICTURE: 0, / / разрешить выбор только сохраненных изображений. DEFAULT. Will return format specified via DestinationType
|
||||
VIDEO: 1, // allow selection of video only, WILL ALWAYS RETURN FILE_URI
|
||||
ALLMEDIA : 2 // allow selection from all media types
|
||||
};
|
||||
|
||||
|
||||
* **correctOrientation**: вращает изображение, чтобы внести исправления к ориентации устройства во время захвата. *(Логический)*
|
||||
|
||||
* **saveToPhotoAlbum**: сохранить изображение в фотоальбом на устройстве после захвата. *(Логическое)*
|
||||
|
||||
* **popoverOptions**: только для iOS параметры, которые определяют местоположение инструмента в iPad. Определены в`CameraPopoverOptions`.
|
||||
|
||||
* **cameraDirection**: выбрать камеру для использования (передней или задней стороне). Значение по умолчанию — обратно. Определяется в `navigator.camera.Direction` *(число)*
|
||||
|
||||
Camera.Direction = {
|
||||
BACK : 0, // Use the back-facing camera
|
||||
FRONT : 1 // Use the front-facing camera
|
||||
};
|
||||
|
||||
|
||||
### Особенности Amazon Fire OS
|
||||
|
||||
* Любое значение `cameraDirection` возвращает фотографию сделанную задней камерой.
|
||||
|
||||
* Игнорирует параметр `allowEdit`.
|
||||
|
||||
* Оба параметра `Camera.PictureSourceType.PHOTOLIBRARY` и `Camera.PictureSourceType.SAVEDPHOTOALBUM` отображают один и тот же фотоальбом.
|
||||
|
||||
### Особенности Android
|
||||
|
||||
* Любое значение `cameraDirection` возвращает фотографию сделанную задней камерой.
|
||||
|
||||
* Игнорирует параметр `allowEdit`.
|
||||
|
||||
* Оба параметра `Camera.PictureSourceType.PHOTOLIBRARY` и `Camera.PictureSourceType.SAVEDPHOTOALBUM` отображают один и тот же фотоальбом.
|
||||
|
||||
### Особенности BlackBerry 10
|
||||
|
||||
* Игнорирует `quality` параметр.
|
||||
|
||||
* Игнорирует параметр `allowEdit`.
|
||||
|
||||
* `Camera.MediaType` не поддерживается.
|
||||
|
||||
* Игнорирует параметр `correctOrientation`.
|
||||
|
||||
* Игнорирует параметр `cameraDirection`.
|
||||
|
||||
### Особенности Firefox OS
|
||||
|
||||
* Игнорирует `quality` параметр.
|
||||
|
||||
* Значение `Camera.DestinationType` игнорируется и равно `1` (URI для файла изображения)
|
||||
|
||||
* Игнорирует параметр `allowEdit`.
|
||||
|
||||
* Игнорирует параметр `PictureSourceType` (пользователь выбирает его в диалоговом окне)
|
||||
|
||||
* Игнорирует параметр `encodingType`
|
||||
|
||||
* Игнорирует `targetWidth` и `targetHeight`
|
||||
|
||||
* `Camera.MediaType` не поддерживается.
|
||||
|
||||
* Игнорирует параметр `correctOrientation`.
|
||||
|
||||
* Игнорирует параметр `cameraDirection`.
|
||||
|
||||
### Особенности iOS
|
||||
|
||||
* Установите `quality` ниже 50, для того чтобы избежать ошибок памяти на некоторых устройствах.
|
||||
|
||||
* При использовании `destinationType.FILE_URI` , фотографии сохраняются во временном каталоге приложения. Содержимое приложения временного каталога удаляется при завершении приложения.
|
||||
|
||||
### Особенности Tizen
|
||||
|
||||
* options, не поддерживается
|
||||
|
||||
* всегда возвращает URI файла
|
||||
|
||||
### Особенности Windows Phone 7 и 8
|
||||
|
||||
* Игнорирует параметр `allowEdit`.
|
||||
|
||||
* Игнорирует параметр `correctOrientation`.
|
||||
|
||||
* Игнорирует параметр `cameraDirection`.
|
||||
|
||||
* Игнорирует `saveToPhotoAlbum` параметр. Важно: Все изображения, снятые камерой wp7/8 cordova API всегда копируются в рулон камеры телефона. В зависимости от параметров пользователя это также может означать, что изображение автоматически загружены на их OneDrive. Потенциально это может означать, что этот образ доступен для более широкой аудитории, чем ваше приложение предназначено. Если этот блокатор для вашего приложения, вам нужно будет осуществить CameraCaptureTask, как описано на сайте msdn: <http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx> вы можете также комментарий или вверх голосование связанный с этим вопрос [отслеживания][3]
|
||||
|
||||
* Игнорирует свойство `mediaType` объекта `cameraOptions` так как Windows Phone SDK не предоставляет способ выбрать видео из PHOTOLIBRARY.
|
||||
|
||||
[3]: https://issues.apache.org/jira/browse/CB-2083
|
||||
|
||||
## CameraError
|
||||
|
||||
Функция обратного вызова вызываемая в случае возникновения ошибки.
|
||||
|
||||
function(message) {
|
||||
// Show a helpful message
|
||||
}
|
||||
|
||||
|
||||
### Параметры
|
||||
|
||||
* **сообщение**: сообщение об ошибке предоставляемое платформой устройства. *(Строка)*
|
||||
|
||||
## cameraSuccess
|
||||
|
||||
Функция обратного вызова onSuccess, получающая данные изображения.
|
||||
|
||||
function(imageData) {
|
||||
// Do something with the image
|
||||
}
|
||||
|
||||
|
||||
### Параметры
|
||||
|
||||
* **imageData**: Данные изображения в Base64 кодировке, *или* URI, в зависимости от применяемых параметров `cameraOptions`. *(Строка)*
|
||||
|
||||
### Пример
|
||||
|
||||
// Show image
|
||||
//
|
||||
function cameraCallback(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverHandle
|
||||
|
||||
Дескриптор диалогового окна инструмента, созданный `navigator.camera.getPicture`.
|
||||
|
||||
### Методы
|
||||
|
||||
* **setPosition**: Задайте положение инструмента выбора изображения.
|
||||
|
||||
### Поддерживаемые платформы
|
||||
|
||||
* iOS
|
||||
|
||||
### setPosition
|
||||
|
||||
Устанавливает положение инструмента выбора изображения.
|
||||
|
||||
**Параметры**:
|
||||
|
||||
* `cameraPopoverOptions`: Объект `CameraPopoverOptions`, определяющий новое положение
|
||||
|
||||
### Пример
|
||||
|
||||
var cameraPopoverHandle = navigator.camera.getPicture(onSuccess, onFail,
|
||||
{ destinationType: Camera.DestinationType.FILE_URI,
|
||||
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
|
||||
popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)
|
||||
});
|
||||
|
||||
// Reposition the popover if the orientation changes.
|
||||
window.onorientationchange = function() {
|
||||
var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
|
||||
cameraPopoverHandle.setPosition(cameraPopoverOptions);
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverOptions
|
||||
|
||||
Параметры только для iOS, которые определяют расположение элемента привязки и направление стрелки инструмента при выборе изображений из библиотеки изображений iPad или альбома.
|
||||
|
||||
{x: 0, y: 32, ширина: 320, высота: 480, arrowDir: Camera.PopoverArrowDirection.ARROW_ANY};
|
||||
|
||||
|
||||
### CameraPopoverOptions
|
||||
|
||||
* **x**: x координата в пикселях элемента экрана, на котором закрепить инструмента. *(Число)*
|
||||
|
||||
* **x**: y координата в пикселях элемента экрана, на котором закрепить инструмента. *(Число)*
|
||||
|
||||
* **width**: ширина в пикселях элемента экрана, на котором закрепить инструмент выбора изображения. *(Число)*
|
||||
|
||||
* **height**: высота в пикселях элемента экрана, на котором закрепить инструмент выбора изображения. *(Число)*
|
||||
|
||||
* **arrowDir**: Направление, куда должна указывать стрелка на инструменте. Определено в `Camera.PopoverArrowDirection` *(число)*
|
||||
|
||||
Camera.PopoverArrowDirection = {
|
||||
ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants
|
||||
ARROW_DOWN : 2,
|
||||
ARROW_LEFT : 4,
|
||||
ARROW_RIGHT : 8,
|
||||
ARROW_ANY : 15
|
||||
};
|
||||
|
||||
|
||||
Обратите внимание, что размер инструмента может изменяться для корректировки в зависимости направлении стрелки и ориентации экрана. Убедитесь, что учитываете возможные изменения ориентации при указании расположения элемента привязки.
|
||||
|
||||
## navigator.camera.cleanup
|
||||
|
||||
Удаляет промежуточные фотографии, сделанные камерой из временного хранилища.
|
||||
|
||||
navigator.camera.cleanup( cameraSuccess, cameraError );
|
||||
|
||||
|
||||
### Описание
|
||||
|
||||
Удаляет промежуточные файлы изображений, которые хранятся во временном хранилище после вызова метода `camera.getPicture` . Применяется только тогда, когда значение `Camera.sourceType` равно `Camera.PictureSourceType.CAMERA` и `Camera.destinationType` равняется `Camera.DestinationType.FILE_URI`.
|
||||
|
||||
### Поддерживаемые платформы
|
||||
|
||||
* iOS
|
||||
|
||||
### Пример
|
||||
|
||||
navigator.camera.cleanup(onSuccess, onFail);
|
||||
|
||||
function onSuccess() {
|
||||
console.log("Camera cleanup success.")
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
435
doc/zh/index.md
Normal file
435
doc/zh/index.md
Normal file
@@ -0,0 +1,435 @@
|
||||
<!---
|
||||
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.
|
||||
-->
|
||||
|
||||
# cordova-plugin-camera
|
||||
|
||||
這個外掛程式定義了一個全球 `navigator.camera` 物件,它提供了 API,拍照,從系統的圖像庫中選擇圖像。
|
||||
|
||||
雖然該物件附加到全球範圍內 `導航器`,它不可用直到 `deviceready` 事件之後。
|
||||
|
||||
document.addEventListener("deviceready", onDeviceReady, false);
|
||||
function onDeviceReady() {
|
||||
console.log(navigator.camera);
|
||||
}
|
||||
|
||||
|
||||
## 安裝
|
||||
|
||||
cordova plugin add cordova-plugin-camera
|
||||
|
||||
|
||||
## navigator.camera.getPicture
|
||||
|
||||
需要一張照片,使用相機,或從設備的圖像庫檢索一張照片。 圖像被傳遞給成功回檔的 base64 編碼 `String`,或作為 URI 為影像檔。 該方法本身返回一個 `CameraPopoverHandle` 物件,它可以用來重新置放檔選擇氣泡框。
|
||||
|
||||
navigator.camera.getPicture( cameraSuccess, cameraError, cameraOptions );
|
||||
|
||||
|
||||
### 說明
|
||||
|
||||
`camera.getPicture` 函數打開該設備的預設攝像頭應用程式,允許使用者拍照。 `Camera.sourceType` 等於 `Camera.PictureSourceType.CAMERA` 時,預設情況下,發生此行為。 一旦使用者打斷了他的照片,相機應用程式關閉,且應用程式還原。
|
||||
|
||||
如果 `Camera.sourceType` 是 `Camera.PictureSourceType.PHOTOLIBRARY` 或 `Camera.PictureSourceType.SAVEDPHOTOALBUM`,然後顯示一個對話方塊,允許使用者選擇一個現有的圖像。 `camera.getPicture` 函數返回一個 `CameraPopoverHandle` 物件,它可以用於重新置放圖像選擇的對話方塊,例如,當設備的方向變化。
|
||||
|
||||
傳回值是發送到 `cameraSuccess` 回呼函數中,在以下的格式,具體取決於指定的 `cameraOptions` 之一:
|
||||
|
||||
* A `String` 包含的 base64 編碼的照片圖像。
|
||||
|
||||
* A `String` 表示在本機存放區 (預設值) 上的影像檔位置。
|
||||
|
||||
你可以做任何你想要的編碼的圖像或 URI,例如:
|
||||
|
||||
* 呈現在圖像 `<img>` 標記,如下面的示例所示
|
||||
|
||||
* 保存本地的資料 ( `LocalStorage` , [Lawnchair][1],等等.)
|
||||
|
||||
* 將資料發佈到遠端伺服器
|
||||
|
||||
[1]: http://brianleroux.github.com/lawnchair/
|
||||
|
||||
**注**: 在更新設備上的照片解析度是很好。 選擇從設備的庫的照片是不壓縮螢幕使其以較低的品質,即使指定了一個 `quality` 參數。 要避免常見的記憶體問題,請將 `Camera.destinationType` 設置為 `FILE_URI`,而不是 `DATA_URL`.
|
||||
|
||||
### 支援的平臺
|
||||
|
||||
* 亞馬遜火 OS
|
||||
* Android 系統
|
||||
* 黑莓 10
|
||||
* 瀏覽器
|
||||
* 火狐瀏覽器的作業系統
|
||||
* iOS
|
||||
* 泰
|
||||
* Windows Phone 7 和 8
|
||||
* Windows 8
|
||||
|
||||
### 首選項 (iOS)
|
||||
|
||||
* **CameraUsesGeolocation**(布林值,預設值為 false)。 用於捕獲 jpeg 檔,設置為 true,以在 EXIF 頭資訊中獲取地理定位資料。 這將觸發請求的地理位置的許可權,如果設置為 true。
|
||||
|
||||
<preference name="CameraUsesGeolocation" value="false" />
|
||||
|
||||
|
||||
### 亞馬遜火 OS 怪癖
|
||||
|
||||
亞馬遜火 OS 使用意圖啟動相機活動設備來捕捉圖像上, 和手機上記憶體不足,科爾多瓦活動可能被殺害。 在這種情況下,可能不會顯示圖像時恢復了科爾多瓦活動。
|
||||
|
||||
### Android 的怪癖
|
||||
|
||||
Android 使用意圖以啟動相機活動設備來捕捉圖像上, 和手機上記憶體不足,科爾多瓦活動可能被殺害。 在這種情況下,可能不會顯示圖像時恢復了科爾多瓦活動。
|
||||
|
||||
### 瀏覽器的怪癖
|
||||
|
||||
可以只返回照片作為 base64 編碼的圖像。
|
||||
|
||||
### 火狐瀏覽器作業系統的怪癖
|
||||
|
||||
觀景窗外掛程式目前實施使用 [Web 活動][2].
|
||||
|
||||
[2]: https://hacks.mozilla.org/2013/01/introducing-web-activities/
|
||||
|
||||
### iOS 的怪癖
|
||||
|
||||
包括 JavaScript `alert ()` 中的回呼函數會導致問題。 包裝內 `setTimeout()` 允許 iOS 圖像選取器或氣泡框以完全關閉之前,警報將顯示警報:
|
||||
|
||||
setTimeout(function() {
|
||||
// do your thing here!
|
||||
}, 0);
|
||||
|
||||
|
||||
### Windows Phone 7 的怪癖
|
||||
|
||||
調用本機攝像頭應用程式,而通過 Zune 所連接的設備不能工作,並且觸發錯誤回檔。
|
||||
|
||||
### 泰怪癖
|
||||
|
||||
泰只支援 `destinationType` 的 `Camera.DestinationType.FILE_URI` 和 `Camera.PictureSourceType.PHOTOLIBRARY` 的 `sourceType`.
|
||||
|
||||
### 示例
|
||||
|
||||
拍一張照片,並檢索它作為一個 base64 編碼的圖像:
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.DATA_URL
|
||||
});
|
||||
|
||||
function onSuccess(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
|
||||
拍一張照片和檢索圖像的檔位置:
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.FILE_URI });
|
||||
|
||||
function onSuccess(imageURI) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = imageURI;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
|
||||
## CameraOptions
|
||||
|
||||
要自訂相機設置的可選參數。
|
||||
|
||||
{ quality : 75,
|
||||
destinationType : Camera.DestinationType.DATA_URL,
|
||||
sourceType : Camera.PictureSourceType.CAMERA,
|
||||
allowEdit : true,
|
||||
encodingType: Camera.EncodingType.JPEG,
|
||||
targetWidth: 100,
|
||||
targetHeight: 100,
|
||||
popoverOptions: CameraPopoverOptions,
|
||||
saveToPhotoAlbum: false };
|
||||
|
||||
|
||||
### 選項
|
||||
|
||||
* **品質**: 保存的圖像,表示為範圍 0-100,100,是通常全解析度,無損失從檔案壓縮的品質。 預設值為 50。 *(人數)*(請注意相機的解析度有關的資訊是不可用)。
|
||||
|
||||
* **可**: 選擇傳回值的格式。預設值是 FILE_URI。定義在 `navigator.camera.DestinationType` *(人數)*
|
||||
|
||||
Camera.DestinationType = {
|
||||
DATA_URL : 0, // Return image as base64-encoded string
|
||||
FILE_URI : 1, // Return image file URI
|
||||
NATIVE_URI : 2 // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
|
||||
};
|
||||
|
||||
|
||||
* **時**: 設置圖片的來源。預設值是觀景窗。定義在 `navigator.camera.PictureSourceType` *(人數)*
|
||||
|
||||
Camera.PictureSourceType = {
|
||||
PHOTOLIBRARY : 0,
|
||||
CAMERA : 1,
|
||||
SAVEDPHOTOALBUM : 2
|
||||
};
|
||||
|
||||
|
||||
* **allowEdit**: 允許簡單編輯前選擇圖像。*(布林)*
|
||||
|
||||
* **encodingType**: 選擇返回的影像檔的編碼。預設值為 JPEG。定義在 `navigator.camera.EncodingType` *(人數)*
|
||||
|
||||
Camera.EncodingType = {
|
||||
JPEG : 0, // Return JPEG encoded image
|
||||
PNG : 1 // Return PNG encoded image
|
||||
};
|
||||
|
||||
|
||||
* **targetWidth**: 向尺度圖像的圖元寬度。必須用**targetHeight**。縱橫比保持不變。*(人數)*
|
||||
|
||||
* **targetHeight**: 以圖元為單位向尺度圖像的高度。必須用**targetWidth**。縱橫比保持不變。*(人數)*
|
||||
|
||||
* **媒體類型**: 設置的媒體,從選擇類型。 時才起作用 `PictureSourceType` 是 `PHOTOLIBRARY` 或 `SAVEDPHOTOALBUM` 。 定義在 `nagivator.camera.MediaType` *(人數)*
|
||||
|
||||
Camera.MediaType = {
|
||||
PICTURE: 0, // allow selection of still pictures only. 預設情況。 Will return format specified via DestinationType
|
||||
VIDEO: 1, // allow selection of video only, WILL ALWAYS RETURN FILE_URI
|
||||
ALLMEDIA : 2 // allow selection from all media types
|
||||
};
|
||||
|
||||
|
||||
* **correctOrientation**: 旋轉圖像,該設備時捕獲的定向的正確。*(布林)*
|
||||
|
||||
* **saveToPhotoAlbum**: 將圖像保存到相冊在設備上捕獲後。*(布林)*
|
||||
|
||||
* **popoverOptions**: 只有 iOS 在 iPad 中指定氣泡框位置的選項。在中定義`CameraPopoverOptions`.
|
||||
|
||||
* **cameraDirection**: 選擇相機以使用 (前面或後面-面向)。預設值是背。定義在 `navigator.camera.Direction` *(人數)*
|
||||
|
||||
Camera.Direction = {
|
||||
BACK : 0, // Use the back-facing camera
|
||||
FRONT : 1 // Use the front-facing camera
|
||||
};
|
||||
|
||||
|
||||
### 亞馬遜火 OS 怪癖
|
||||
|
||||
* 任何 `cameraDirection` 值回朝的照片中的結果。
|
||||
|
||||
* 忽略 `allowEdit` 參數。
|
||||
|
||||
* `Camera.PictureSourceType.PHOTOLIBRARY`和 `Camera.PictureSourceType.SAVEDPHOTOALBUM` 都顯示相同的相冊。
|
||||
|
||||
### Android 的怪癖
|
||||
|
||||
* 任何 `cameraDirection` 值結果在背面的照片。
|
||||
|
||||
* 忽略 `allowEdit` 參數。
|
||||
|
||||
* `Camera.PictureSourceType.PHOTOLIBRARY`和 `Camera.PictureSourceType.SAVEDPHOTOALBUM` 都顯示相同的寫真集。
|
||||
|
||||
### 黑莓 10 的怪癖
|
||||
|
||||
* 忽略 `quality` 參數。
|
||||
|
||||
* 忽略 `allowEdit` 參數。
|
||||
|
||||
* `Camera.MediaType`不受支援。
|
||||
|
||||
* 忽略 `correctOrientation` 參數。
|
||||
|
||||
* 忽略 `cameraDirection` 參數。
|
||||
|
||||
### 火狐瀏覽器作業系統的怪癖
|
||||
|
||||
* 忽略 `quality` 參數。
|
||||
|
||||
* `Camera.DestinationType`將被忽略並且等於 `1` (影像檔的 URI)
|
||||
|
||||
* 忽略 `allowEdit` 參數。
|
||||
|
||||
* 忽略 `PictureSourceType` 參數 (使用者選擇它在對話方塊視窗中)
|
||||
|
||||
* 忽略`encodingType`
|
||||
|
||||
* 忽略了 `targetWidth` 和`targetHeight`
|
||||
|
||||
* `Camera.MediaType`不受支援。
|
||||
|
||||
* 忽略 `correctOrientation` 參數。
|
||||
|
||||
* 忽略 `cameraDirection` 參數。
|
||||
|
||||
### iOS 的怪癖
|
||||
|
||||
* 設置 `quality` 低於 50,避免在某些設備上的記憶體不足錯誤。
|
||||
|
||||
* 當使用 `destinationType.FILE_URI` ,照片都保存在應用程式的臨時目錄。應用程式結束時,將刪除該應用程式的臨時目錄中的內容。
|
||||
|
||||
### 泰怪癖
|
||||
|
||||
* 不支援的選項
|
||||
|
||||
* 總是返回一個檔的 URI
|
||||
|
||||
### Windows Phone 7 和 8 的怪癖
|
||||
|
||||
* 忽略 `allowEdit` 參數。
|
||||
|
||||
* 忽略 `correctOrientation` 參數。
|
||||
|
||||
* 忽略 `cameraDirection` 參數。
|
||||
|
||||
* 忽略 `saveToPhotoAlbum` 參數。 重要: 使用 wp7/8 科爾多瓦攝像頭 API 拍攝的所有圖像總是都複製到手機的相機膠捲。 根據使用者的設置,這可能也意味著圖像是自動上傳到他們另。 這有可能意味著的圖像,可以比你的應用程式的目的更多的觀眾。 如果此阻滯劑您的應用程式,您將需要實現 CameraCaptureTask 在 msdn 上記載: [HTTP://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx][3]你可能還評論或在[問題追蹤器][4]的向上投票的相關的問題
|
||||
|
||||
* 忽略了 `mediaType` 屬性的 `cameraOptions` 作為 Windows Phone SDK 並不提供從 PHOTOLIBRARY 中選擇視頻的方法。
|
||||
|
||||
[3]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx
|
||||
[4]: https://issues.apache.org/jira/browse/CB-2083
|
||||
|
||||
## CameraError
|
||||
|
||||
onError 的回呼函數提供了一條錯誤訊息。
|
||||
|
||||
function(message) {
|
||||
// Show a helpful message
|
||||
}
|
||||
|
||||
|
||||
### 參數
|
||||
|
||||
* **message**: 消息提供的設備的本機代碼。*(String)*
|
||||
|
||||
## cameraSuccess
|
||||
|
||||
提供的圖像資料的 onSuccess 回呼函數。
|
||||
|
||||
function(imageData) {
|
||||
// Do something with the image
|
||||
}
|
||||
|
||||
|
||||
### 參數
|
||||
|
||||
* **imageData**: Base64 編碼進行編碼的圖像資料,*或*影像檔的 URI,取決於 `cameraOptions` 效果。*(String)*
|
||||
|
||||
### 示例
|
||||
|
||||
// Show image
|
||||
//
|
||||
function cameraCallback(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverHandle
|
||||
|
||||
由 `navigator.camera.getPicture` 創建的氣泡框對話方塊的控制碼.
|
||||
|
||||
### 方法
|
||||
|
||||
* **setPosition**: 設置氣泡框的位置。
|
||||
|
||||
### 支援的平臺
|
||||
|
||||
* iOS
|
||||
|
||||
### setPosition
|
||||
|
||||
設置氣泡框的位置。
|
||||
|
||||
**參數**:
|
||||
|
||||
* `cameraPopoverOptions`: `CameraPopoverOptions` ,指定新的位置
|
||||
|
||||
### 示例
|
||||
|
||||
var cameraPopoverHandle = navigator.camera.getPicture(onSuccess, onFail,
|
||||
{ destinationType: Camera.DestinationType.FILE_URI,
|
||||
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
|
||||
popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)
|
||||
});
|
||||
|
||||
// Reposition the popover if the orientation changes.
|
||||
window.onorientationchange = function() {
|
||||
var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
|
||||
cameraPopoverHandle.setPosition(cameraPopoverOptions);
|
||||
}
|
||||
|
||||
|
||||
## CameraPopoverOptions
|
||||
|
||||
iOS 僅指定氣泡框的錨元素的位置和箭頭方向,從 iPad 庫或專輯選擇圖像時的參數。
|
||||
|
||||
{ x : 0,
|
||||
y : 32,
|
||||
width : 320,
|
||||
height : 480,
|
||||
arrowDir : Camera.PopoverArrowDirection.ARROW_ANY
|
||||
};
|
||||
|
||||
|
||||
### CameraPopoverOptions
|
||||
|
||||
* **x**: x 螢幕元素到其錨定氣泡框上的圖元座標。*(人數)*
|
||||
|
||||
* **y**: 螢幕元素到其錨定氣泡框上的 y 圖元座標。*(人數)*
|
||||
|
||||
* **width**: 寬度以圖元為單位),到其錨定氣泡框上的螢幕元素。*(人數)*
|
||||
|
||||
* **height**: 高度以圖元為單位),到其錨定氣泡框上的螢幕元素。*(人數)*
|
||||
|
||||
* **arrowDir**: 氣泡框上的箭頭應指向的方向。定義在 `Camera.PopoverArrowDirection` *(人數)*
|
||||
|
||||
Camera.PopoverArrowDirection = {
|
||||
ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants
|
||||
ARROW_DOWN : 2,
|
||||
ARROW_LEFT : 4,
|
||||
ARROW_RIGHT : 8,
|
||||
ARROW_ANY : 15
|
||||
};
|
||||
|
||||
|
||||
請注意氣泡框的大小可能會更改箭頭的方向和螢幕的方向進行調整。 請確保帳戶方向更改時指定錨元素位置。
|
||||
|
||||
## navigator.camera.cleanup
|
||||
|
||||
刪除中間從臨時存儲攝像機所拍攝的照片。
|
||||
|
||||
navigator.camera.cleanup( cameraSuccess, cameraError );
|
||||
|
||||
|
||||
### 描述
|
||||
|
||||
刪除保留在臨時存儲在調用 `camera.getPicture` 後的中間的影像檔。 適用只有當 `Camera.sourceType` 的值等於 `Camera.PictureSourceType.CAMERA` 和 `Camera.destinationType` 等於 `Camera.DestinationType.FILE_URI`.
|
||||
|
||||
### 支援的平臺
|
||||
|
||||
* iOS
|
||||
|
||||
### 示例
|
||||
|
||||
navigator.camera.cleanup(onSuccess, onFail);
|
||||
|
||||
function onSuccess() {
|
||||
console.log("Camera cleanup success.")
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
---
|
||||
license: 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.
|
||||
---
|
||||
|
||||
camera.cleanup
|
||||
=================
|
||||
|
||||
Cleans up the image files that were taken by the camera, that were stored in a temporary storage location.
|
||||
|
||||
navigator.camera.cleanup( cameraSuccess, cameraError );
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
Cleans up the image files stored in the temporary storage location, when the function `camera.getPicture` is used with `Camera.sourceType = Camera.PictureSourceType.CAMERA` and `Camera.destinationType = Camera.DestinationType.FILE_URI`
|
||||
|
||||
|
||||
Supported Platforms
|
||||
-------------------
|
||||
|
||||
- iOS
|
||||
|
||||
|
||||
Example
|
||||
-------------
|
||||
|
||||
navigator.camera.cleanup(onSuccess, onFail);
|
||||
|
||||
function onSuccess() {
|
||||
console.log("Camera cleanup success.")
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
---
|
||||
license: 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.
|
||||
---
|
||||
|
||||
camera.getPicture
|
||||
=================
|
||||
|
||||
Takes a photo using the camera or retrieves a photo from the device's album.
|
||||
The image is passed to the success callback as a base64 encoded `String` or as the URI of an image file.
|
||||
The method itself returns a CameraPopoverHandle object, which can be used to reposition the file selection popover.
|
||||
|
||||
navigator.camera.getPicture( cameraSuccess, cameraError, [ cameraOptions ] );
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
Function `camera.getPicture` opens the device's default camera application so that the user can take a picture (if `Camera.sourceType = Camera.PictureSourceType.CAMERA`, which is the default). Once the photo is taken, the camera application closes and your application is restored.
|
||||
|
||||
If `Camera.sourceType = Camera.PictureSourceType.PHOTOLIBRARY` or `Camera.PictureSourceType.SAVEDPHOTOALBUM`, then a photo chooser dialog is shown, from which a photo from the album can be selected. A `CameraPopoverHandle` object, which can be used to reposition the photo chooser dialog (eg. when the device orientation changes) is returned by `camera.getPicture`.
|
||||
|
||||
The return value will be sent to the `cameraSuccess` function, in one of the following formats, depending on the `cameraOptions` you specify:
|
||||
|
||||
- A `String` containing the Base64 encoded photo image.
|
||||
- A `String` representing the image file location on local storage (default).
|
||||
|
||||
You can do whatever you want with the encoded image or URI, for example:
|
||||
|
||||
- Render the image in an `<img>` tag _(see example below)_
|
||||
- Save the data locally (`LocalStorage`, [Lawnchair](http://brianleroux.github.com/lawnchair/), etc)
|
||||
- Post the data to a remote server
|
||||
|
||||
__Note:__ The image quality of pictures taken using the camera on newer devices is quite good, and images from the Photo Album will not be downscaled to a lower quality, even if a quality parameter is specified. ___Encoding such images using Base64 has caused memory issues on many newer devices. Therefore, using FILE\_URI as the 'Camera.destinationType' is highly recommended.___
|
||||
|
||||
Supported Platforms
|
||||
-------------------
|
||||
|
||||
- Android
|
||||
- Blackberry WebWorks (OS 5.0 and higher)
|
||||
- iOS
|
||||
- Windows Phone 7 and 8
|
||||
- Bada 1.2
|
||||
- webOS
|
||||
- Tizen
|
||||
- Windows 8
|
||||
|
||||
iOS Quirks
|
||||
----------
|
||||
|
||||
Including a JavaScript alert() in either of the callback functions can cause problems. Wrap the alert in a setTimeout() to allow the iOS image picker or popover to fully close before the alert is displayed:
|
||||
|
||||
setTimeout(function() {
|
||||
// do your thing here!
|
||||
}, 0);
|
||||
|
||||
Windows Phone 7 Quirks
|
||||
----------------------
|
||||
|
||||
Invoking the native camera application while your device is connected
|
||||
via Zune will not work, and the error callback will be triggered.
|
||||
|
||||
Tizen Quirks
|
||||
----------------------
|
||||
|
||||
Only 'destinationType: Camera.DestinationType.FILE_URI' and 'sourceType: Camera.PictureSourceType.PHOTOLIBRARY' are supported.
|
||||
|
||||
Quick Example
|
||||
-------------
|
||||
|
||||
Take photo and retrieve Base64-encoded image:
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.DATA_URL
|
||||
});
|
||||
|
||||
function onSuccess(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
Take photo and retrieve image file location:
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
|
||||
destinationType: Camera.DestinationType.FILE_URI });
|
||||
|
||||
function onSuccess(imageURI) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = imageURI;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
|
||||
Full Example
|
||||
------------
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Capture Photo</title>
|
||||
|
||||
<script type="text/javascript" charset="utf-8" src="cordova-x.x.x.js"></script>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
|
||||
var pictureSource; // picture source
|
||||
var destinationType; // sets the format of returned value
|
||||
|
||||
// Wait for Cordova to connect with the device
|
||||
//
|
||||
document.addEventListener("deviceready",onDeviceReady,false);
|
||||
|
||||
// Cordova is ready to be used!
|
||||
//
|
||||
function onDeviceReady() {
|
||||
pictureSource=navigator.camera.PictureSourceType;
|
||||
destinationType=navigator.camera.DestinationType;
|
||||
}
|
||||
|
||||
// Called when a photo is successfully retrieved
|
||||
//
|
||||
function onPhotoDataSuccess(imageData) {
|
||||
// Uncomment to view the base64 encoded image data
|
||||
// console.log(imageData);
|
||||
|
||||
// Get image handle
|
||||
//
|
||||
var smallImage = document.getElementById('smallImage');
|
||||
|
||||
// Unhide image elements
|
||||
//
|
||||
smallImage.style.display = 'block';
|
||||
|
||||
// Show the captured photo
|
||||
// The inline CSS rules are used to resize the image
|
||||
//
|
||||
smallImage.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
// Called when a photo is successfully retrieved
|
||||
//
|
||||
function onPhotoURISuccess(imageURI) {
|
||||
// Uncomment to view the image file URI
|
||||
// console.log(imageURI);
|
||||
|
||||
// Get image handle
|
||||
//
|
||||
var largeImage = document.getElementById('largeImage');
|
||||
|
||||
// Unhide image elements
|
||||
//
|
||||
largeImage.style.display = 'block';
|
||||
|
||||
// Show the captured photo
|
||||
// The inline CSS rules are used to resize the image
|
||||
//
|
||||
largeImage.src = imageURI;
|
||||
}
|
||||
|
||||
// A button will call this function
|
||||
//
|
||||
function capturePhoto() {
|
||||
// Take picture using device camera and retrieve image as base64-encoded string
|
||||
navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50,
|
||||
destinationType: destinationType.DATA_URL });
|
||||
}
|
||||
|
||||
// A button will call this function
|
||||
//
|
||||
function capturePhotoEdit() {
|
||||
// Take picture using device camera, allow edit, and retrieve image as base64-encoded string
|
||||
navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 20, allowEdit: true,
|
||||
destinationType: destinationType.DATA_URL });
|
||||
}
|
||||
|
||||
// A button will call this function
|
||||
//
|
||||
function getPhoto(source) {
|
||||
// Retrieve image file location from specified source
|
||||
navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 50,
|
||||
destinationType: destinationType.FILE_URI,
|
||||
sourceType: source });
|
||||
}
|
||||
|
||||
// Called if something bad happens.
|
||||
//
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<button onclick="capturePhoto();">Capture Photo</button> <br>
|
||||
<button onclick="capturePhotoEdit();">Capture Editable Photo</button> <br>
|
||||
<button onclick="getPhoto(pictureSource.PHOTOLIBRARY);">From Photo Library</button><br>
|
||||
<button onclick="getPhoto(pictureSource.SAVEDPHOTOALBUM);">From Photo Album</button><br>
|
||||
<img style="display:none;width:60px;height:60px;" id="smallImage" src="" />
|
||||
<img style="display:none;" id="largeImage" src="" />
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,97 +0,0 @@
|
||||
---
|
||||
license: 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.
|
||||
---
|
||||
|
||||
Camera
|
||||
======
|
||||
|
||||
> The `camera` object provides access to the device's default camera application.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
- camera.getPicture
|
||||
- camera.cleanup
|
||||
|
||||
Permissions
|
||||
-----------
|
||||
|
||||
### Android
|
||||
|
||||
#### app/res/xml/config.xml
|
||||
|
||||
<plugin name="Camera" value="org.apache.cordova.CameraLauncher" />
|
||||
|
||||
#### app/AndroidManifest
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
### Bada
|
||||
|
||||
#### manifest.xml
|
||||
|
||||
<Privilege>
|
||||
<Name>CAMERA</Name>
|
||||
</Privilege>
|
||||
<Privilege>
|
||||
<Name>RECORDING</Name>
|
||||
</Privilege>
|
||||
|
||||
### BlackBerry WebWorks
|
||||
|
||||
#### www/plugins.xml
|
||||
|
||||
<plugin name="Camera" value="org.apache.cordova.camera.Camera" />
|
||||
|
||||
#### www/config.xml
|
||||
|
||||
<feature id="blackberry.media.camera" />
|
||||
|
||||
<rim:permissions>
|
||||
<rim:permit>use_camera</rim:permit>
|
||||
</rim:permissions>
|
||||
|
||||
### iOS
|
||||
|
||||
#### config.xml
|
||||
|
||||
<plugin name="Camera" value="CDVCamera" />
|
||||
|
||||
### webOS
|
||||
|
||||
No permissions are required.
|
||||
|
||||
### Windows Phone
|
||||
|
||||
#### Properties/WPAppManifest.xml
|
||||
|
||||
<Capabilities>
|
||||
<Capability Name="ID_CAP_ISV_CAMERA" />
|
||||
<Capability Name="ID_HW_FRONTCAMERA" />
|
||||
</Capabilities>
|
||||
|
||||
Reference: [Application Manifest for Windows Phone](http://msdn.microsoft.com/en-us/library/ff769509%28v=vs.92%29.aspx)
|
||||
|
||||
### Tizen
|
||||
|
||||
#### config.xml
|
||||
|
||||
<feature name="http://tizen.org/api/application" required="true"/>
|
||||
<feature name="http://tizen.org/api/application.launch" required="true"/>
|
||||
|
||||
Reference: [Application Manifest for Tizen Web Application](https://developer.tizen.org/help/topic/org.tizen.help.gs/Creating%20a%20Project.html?path=0_1_1_3#8814682_CreatingaProject-EditingconfigxmlFeatures)
|
||||
@@ -1,68 +0,0 @@
|
||||
---
|
||||
license: 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.
|
||||
---
|
||||
|
||||
CameraPopoverHandle
|
||||
===================
|
||||
|
||||
A handle to the popover dialog created by `camera.getPicture`.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
- __setPosition:__ Set the position of the popover.
|
||||
|
||||
Supported Platforms
|
||||
-------------------
|
||||
|
||||
- iOS
|
||||
|
||||
setPosition
|
||||
-----------
|
||||
|
||||
Set the position of the popover.
|
||||
|
||||
__Parameters:__
|
||||
- cameraPopoverOptions - the CameraPopoverOptions specifying the new position
|
||||
|
||||
Quick Example
|
||||
-------------
|
||||
|
||||
var cameraPopoverOptions = new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
|
||||
cameraPopoverHandle.setPosition(cameraPopoverOptions);
|
||||
|
||||
Full Example
|
||||
------------
|
||||
|
||||
function onSuccess(imageData) {
|
||||
// Do stuff with the image!
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed to get the picture: ' + message);
|
||||
}
|
||||
|
||||
var cameraPopoverHandle = navigator.camera.getPicture(onSuccess, onFail,
|
||||
{ destinationType: Camera.DestinationType.FILE_URI,
|
||||
sourceType: Camera.PictureSourceType.PHOTOLIBRARY });
|
||||
|
||||
// Reposition the popover if the orientation changes.
|
||||
window.onorientationchange = function() {
|
||||
var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, 0);
|
||||
cameraPopoverHandle.setPosition(cameraPopoverOptions);
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
---
|
||||
license: 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.
|
||||
---
|
||||
|
||||
CameraPopoverOptions
|
||||
====================
|
||||
|
||||
Parameters only used by iOS to specify the anchor element location and arrow direction of popover used on iPad when selecting images from the library or album.
|
||||
|
||||
{ x : 0,
|
||||
y : 32,
|
||||
width : 320,
|
||||
height : 480,
|
||||
arrowDir : Camera.PopoverArrowDirection.ARROW_ANY
|
||||
};
|
||||
|
||||
CameraPopoverOptions
|
||||
--------------------
|
||||
|
||||
- __x:__ x pixel coordinate of element on the screen to anchor popover onto. (`Number`)
|
||||
|
||||
- __y:__ y pixel coordinate of element on the screen to anchor popover onto. (`Number`)
|
||||
|
||||
- __width:__ width, in pixels, of the element on the screen to anchor popover onto. (`Number`)
|
||||
|
||||
- __height:__ height, in pixels, of the element on the screen to anchor popover onto. (`Number`)
|
||||
|
||||
- __arrowDir:__ Direction the arrow on the popover should point. Defined in Camera.PopoverArrowDirection (`Number`)
|
||||
|
||||
Camera.PopoverArrowDirection = {
|
||||
ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants
|
||||
ARROW_DOWN : 2,
|
||||
ARROW_LEFT : 4,
|
||||
ARROW_RIGHT : 8,
|
||||
ARROW_ANY : 15
|
||||
};
|
||||
|
||||
Note that the size of the popover may change to adjust to the direction of the arrow and orientation of the screen. Make sure to account for orientation changes when specifying the anchor element location.
|
||||
|
||||
Quick Example
|
||||
-------------
|
||||
|
||||
var popover = new CameraPopoverOptions(300,300,100,100,Camera.PopoverArrowDirection.ARROW_ANY);
|
||||
var options = { quality: 50, destinationType: Camera.DestinationType.DATA_URL,sourceType: Camera.PictureSource.SAVEDPHOTOALBUM, popoverOptions : popover };
|
||||
|
||||
navigator.camera.getPicture(onSuccess, onFail, options);
|
||||
|
||||
function onSuccess(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
|
||||
function onFail(message) {
|
||||
alert('Failed because: ' + message);
|
||||
}
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
---
|
||||
license: 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.
|
||||
---
|
||||
|
||||
cameraOptions
|
||||
=============
|
||||
|
||||
Optional parameters to customize the camera settings.
|
||||
|
||||
{ quality : 75,
|
||||
destinationType : Camera.DestinationType.DATA_URL,
|
||||
sourceType : Camera.PictureSourceType.CAMERA,
|
||||
allowEdit : true,
|
||||
encodingType: Camera.EncodingType.JPEG,
|
||||
targetWidth: 100,
|
||||
targetHeight: 100,
|
||||
popoverOptions: CameraPopoverOptions,
|
||||
saveToPhotoAlbum: false };
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
- __quality:__ Quality of saved image. Range is [0, 100]. (`Number`)
|
||||
|
||||
- __destinationType:__ Choose the format of the return value. Defined in navigator.camera.DestinationType (`Number`)
|
||||
|
||||
Camera.DestinationType = {
|
||||
DATA_URL : 0, // Return image as base64 encoded string
|
||||
FILE_URI : 1, // Return image file URI
|
||||
NATIVE_URI : 2 // Return image native URI (eg. assets-library:// on iOS or content:// on Android)
|
||||
};
|
||||
|
||||
- __sourceType:__ Set the source of the picture. Defined in nagivator.camera.PictureSourceType (`Number`)
|
||||
|
||||
Camera.PictureSourceType = {
|
||||
PHOTOLIBRARY : 0,
|
||||
CAMERA : 1,
|
||||
SAVEDPHOTOALBUM : 2
|
||||
};
|
||||
|
||||
- __allowEdit:__ Allow simple editing of image before selection. (`Boolean`)
|
||||
|
||||
- __encodingType:__ Choose the encoding of the returned image file. Defined in navigator.camera.EncodingType (`Number`)
|
||||
|
||||
Camera.EncodingType = {
|
||||
JPEG : 0, // Return JPEG encoded image
|
||||
PNG : 1 // Return PNG encoded image
|
||||
};
|
||||
|
||||
- __targetWidth:__ Width in pixels to scale image. Must be used with targetHeight. Aspect ratio is maintained. (`Number`)
|
||||
- __targetHeight:__ Height in pixels to scale image. Must be used with targetWidth. Aspect ratio is maintained. (`Number`)
|
||||
|
||||
- __mediaType:__ Set the type of media to select from. Only works when PictureSourceType is PHOTOLIBRARY or SAVEDPHOTOALBUM. Defined in nagivator.camera.MediaType (`Number`)
|
||||
|
||||
Camera.MediaType = {
|
||||
PICTURE: 0, // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
|
||||
VIDEO: 1, // allow selection of video only, WILL ALWAYS RETURN FILE_URI
|
||||
ALLMEDIA : 2 // allow selection from all media types
|
||||
};
|
||||
|
||||
- __correctOrientation:__ Rotate the image to correct for the orientation of the device during capture. (`Boolean`)
|
||||
- __saveToPhotoAlbum:__ Save the image to the photo album on the device after capture. (`Boolean`)
|
||||
- __popoverOptions:__ iOS only options to specify popover location in iPad. Defined in CameraPopoverOptions.
|
||||
- __cameraDirection:__ Choose the camera to use (front- or back-facing). Defined in navigator.camera.Direction (`Number`)
|
||||
|
||||
Camera.Direction = {
|
||||
BACK : 0, // Use the back-facing camera
|
||||
FRONT : 1 // Use the front-facing camera
|
||||
};
|
||||
|
||||
Android Quirks
|
||||
--------------
|
||||
|
||||
- Ignores the `allowEdit` parameter.
|
||||
- Camera.PictureSourceType.PHOTOLIBRARY and Camera.PictureSourceType.SAVEDPHOTOALBUM both display the same photo album.
|
||||
|
||||
BlackBerry Quirks
|
||||
-----------------
|
||||
|
||||
- Ignores the `quality` parameter.
|
||||
- Ignores the `sourceType` parameter.
|
||||
- Ignores the `allowEdit` parameter.
|
||||
- Application must have key injection permissions to close native Camera application after photo is taken.
|
||||
- Using Large image sizes may result in inability to encode image on later model devices with high resolution cameras (e.g. Torch 9800).
|
||||
- Camera.MediaType is not supported.
|
||||
- Ignores the `correctOrientation` parameter.
|
||||
- Ignores the `cameraDirection` parameter.
|
||||
|
||||
webOS Quirks
|
||||
-----------
|
||||
|
||||
- Ignores the `quality` parameter.
|
||||
- Ignores the `sourceType` parameter.
|
||||
- Ignores the `allowEdit` parameter.
|
||||
- Camera.MediaType is not supported.
|
||||
- Ignores the `correctOrientation` parameter.
|
||||
- Ignores the `saveToPhotoAlbum` parameter.
|
||||
- Ignores the `cameraDirection` parameter.
|
||||
|
||||
iOS Quirks
|
||||
--------------
|
||||
|
||||
- Set `quality` below 50 to avoid memory error on some devices.
|
||||
- When `destinationType.FILE_URI` is used, photos are saved in the application's temporary directory.
|
||||
|
||||
Windows Phone 7 and 8 Quirks
|
||||
--------------
|
||||
|
||||
- Ignores the `allowEdit` parameter.
|
||||
- Ignores the `correctOrientation` parameter.
|
||||
- Ignores the `cameraDirection` parameter.
|
||||
|
||||
Bada 1.2 Quirks
|
||||
--------------
|
||||
- options not supported
|
||||
- always returns a FILE URI
|
||||
|
||||
Tizen Quirks
|
||||
--------------
|
||||
- options not supported
|
||||
- always returns a FILE URI
|
||||
@@ -1,42 +0,0 @@
|
||||
---
|
||||
license: 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.
|
||||
---
|
||||
|
||||
cameraSuccess
|
||||
=============
|
||||
|
||||
onSuccess callback function that provides the image data.
|
||||
|
||||
function(imageData) {
|
||||
// Do something with the image
|
||||
}
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
- __imageData:__ Base64 encoding of the image data, OR the image file URI, depending on `cameraOptions` used. (`String`)
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
// Show image
|
||||
//
|
||||
function cameraCallback(imageData) {
|
||||
var image = document.getElementById('myImage');
|
||||
image.src = "data:image/jpeg;base64," + imageData;
|
||||
}
|
||||
46
package.json
Normal file
46
package.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "cordova-plugin-camera",
|
||||
"version": "1.1.0",
|
||||
"description": "Cordova Camera Plugin",
|
||||
"cordova": {
|
||||
"id": "cordova-plugin-camera",
|
||||
"platforms": [
|
||||
"firefoxos",
|
||||
"android",
|
||||
"amazon-fireos",
|
||||
"ubuntu",
|
||||
"ios",
|
||||
"blackberry10",
|
||||
"wp7",
|
||||
"wp8",
|
||||
"windows8",
|
||||
"browser",
|
||||
"windows"
|
||||
]
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git-wip-us.apache.org/repos/asf/cordova-plugin-camera.git"
|
||||
},
|
||||
"keywords": [
|
||||
"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"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"cordova-plugin-file": ">=2.0.0"
|
||||
},
|
||||
"author": "Apache Software Foundation",
|
||||
"license": "Apache 2.0"
|
||||
}
|
||||
142
plugin.xml
142
plugin.xml
@@ -1,13 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
id="org.apache.cordova.core.camera"
|
||||
version="0.2.1">
|
||||
xmlns:rim="http://www.blackberry.com/ns/widgets"
|
||||
id="cordova-plugin-camera"
|
||||
version="1.1.0">
|
||||
<name>Camera</name>
|
||||
<description>Cordova Camera Plugin</description>
|
||||
<license>Apache 2.0</license>
|
||||
<keywords>cordova,camera</keywords>
|
||||
<repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-camera.git</repo>
|
||||
<issue>https://issues.apache.org/jira/browse/CB/component/12320645</issue>
|
||||
|
||||
<js-module src="www/CameraConstants.js" name="Camera">
|
||||
<clobbers target="Camera" />
|
||||
@@ -23,6 +44,19 @@
|
||||
<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="/*">
|
||||
@@ -35,6 +69,8 @@
|
||||
</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" />
|
||||
@@ -42,28 +78,79 @@
|
||||
|
||||
</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="/*">
|
||||
<feature name="Camera">
|
||||
<param name="ios-package" value="CDVCamera" />
|
||||
</feature>
|
||||
<preference name="CameraUsesGeolocation" value="false" />
|
||||
</config-file>
|
||||
|
||||
<js-module src="www/ios/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
||||
<clobbers target="CameraPopoverHandle" />
|
||||
</js-module>
|
||||
|
||||
<header-file src="src/ios/UIImage+CropScaleOrientation.h" />
|
||||
<source-file src="src/ios/UIImage+CropScaleOrientation.m" />
|
||||
<header-file src="src/ios/CDVCamera.h" />
|
||||
<source-file src="src/ios/CDVCamera.m" />
|
||||
<header-file src="src/ios/CDVJpegHeaderWriter.h" />
|
||||
<source-file src="src/ios/CDVJpegHeaderWriter.m" />
|
||||
<header-file src="src/ios/CDVExif.h" />
|
||||
<framework src="ImageIO.framework" weak="true" />
|
||||
<framework src="CoreLocation.framework" />
|
||||
<framework src="CoreGraphics.framework" />
|
||||
<framework src="AssetsLibrary.framework" />
|
||||
<source-file src="src/ios/CDVJpegHeaderWriter.m" />
|
||||
<header-file src="src/ios/CDVExif.h" />
|
||||
<framework src="ImageIO.framework" weak="true" />
|
||||
<framework src="CoreLocation.framework" />
|
||||
<framework src="CoreGraphics.framework" />
|
||||
<framework src="AssetsLibrary.framework" />
|
||||
<framework src="MobileCoreServices.framework" />
|
||||
<framework src="CoreGraphics.framework" />
|
||||
|
||||
<config-file target="*-Info.plist" parent="NSLocationWhenInUseUsageDescription">
|
||||
<string></string>
|
||||
</config-file>
|
||||
|
||||
</platform>
|
||||
|
||||
<!-- blackberry10 -->
|
||||
@@ -72,10 +159,14 @@
|
||||
<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 -->
|
||||
@@ -122,9 +213,6 @@
|
||||
<!-- windows8 -->
|
||||
<platform name="windows8">
|
||||
|
||||
<dependency id="org.apache.cordova.core.file"
|
||||
url="https://git-wip-us.apache.org/repos/asf/cordova-plugin-file"
|
||||
commit="master" subdir="/" />
|
||||
<config-file target="package.appxmanifest" parent="/Package/Capabilities">
|
||||
<Capability Name="picturesLibrary" />
|
||||
<DeviceCapability Name="webcam" />
|
||||
@@ -132,10 +220,38 @@
|
||||
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
||||
<clobbers target="CameraPopoverHandle" />
|
||||
</js-module>
|
||||
<js-module src="src/windows8/CameraProxy.js" name="CameraProxy">
|
||||
<js-module src="src/windows/CameraProxy.js" name="CameraProxy">
|
||||
<merges target="" />
|
||||
</js-module>
|
||||
|
||||
</platform>
|
||||
|
||||
<!-- browser -->
|
||||
<platform name="browser">
|
||||
<config-file target="config.xml" parent="/*">
|
||||
<feature name="Camera">
|
||||
<param name="browser-package" value="Camera" />
|
||||
</feature>
|
||||
</config-file>
|
||||
|
||||
<js-module src="src/browser/CameraProxy.js" name="CameraProxy">
|
||||
<runs />
|
||||
</js-module>
|
||||
</platform>
|
||||
|
||||
<!-- windows -->
|
||||
<platform name="windows">
|
||||
<config-file target="package.appxmanifest" parent="/Package/Capabilities">
|
||||
<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">
|
||||
<merges target="" />
|
||||
</js-module>
|
||||
</platform>
|
||||
|
||||
|
||||
|
||||
</plugin>
|
||||
|
||||
795
src/android/CameraLauncher.java
Executable file → Normal file
795
src/android/CameraLauncher.java
Executable file → Normal file
@@ -24,11 +24,12 @@ import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.cordova.ExifHelper;
|
||||
import org.apache.cordova.DirectoryManager;
|
||||
import org.apache.cordova.FileHelper;
|
||||
import org.apache.cordova.CallbackContext;
|
||||
import org.apache.cordova.CordovaPlugin;
|
||||
import org.apache.cordova.LOG;
|
||||
@@ -37,21 +38,23 @@ import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.CompressFormat;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Bitmap.CompressFormat;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import android.content.pm.PackageManager;
|
||||
/**
|
||||
* This class launches the camera view, allows the user to take a picture, closes the camera view,
|
||||
* and returns the captured image. When the camera view is closed, the screen displayed before
|
||||
@@ -61,7 +64,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
|
||||
private static final int DATA_URL = 0; // Return base64 encoded string
|
||||
private static final int FILE_URI = 1; // Return file uri (content://media/external/images/media/2 for Android)
|
||||
private static final int NATIVE_URI = 2; // On Android, this is the same as FILE_URI
|
||||
private static final int NATIVE_URI = 2; // On Android, this is the same as FILE_URI
|
||||
|
||||
private static final int PHOTOLIBRARY = 0; // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
|
||||
private static final int CAMERA = 1; // Take picture from camera
|
||||
@@ -79,6 +82,9 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
|
||||
private static final String LOG_TAG = "CameraLauncher";
|
||||
|
||||
//Where did this come from?
|
||||
private static final int CROP_CAMERA = 100;
|
||||
|
||||
private int mQuality; // Compression quality hint (0-100: 0=low quality & high compression, 100=compress of max quality)
|
||||
private int targetWidth; // desired width of the image
|
||||
private int targetHeight; // desired height of the image
|
||||
@@ -87,38 +93,23 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
private int mediaType; // What type of media to retrieve
|
||||
private boolean saveToPhotoAlbum; // Should the picture be saved to the device's photo album
|
||||
private boolean correctOrientation; // Should the pictures orientation be corrected
|
||||
//private boolean allowEdit; // Should we allow the user to crop the image. UNUSED.
|
||||
private boolean orientationCorrected; // Has the picture's orientation been corrected
|
||||
private boolean allowEdit; // Should we allow the user to crop the image.
|
||||
|
||||
public CallbackContext callbackContext;
|
||||
private int numPics;
|
||||
|
||||
private MediaScannerConnection conn; // Used to update gallery app with newly-written files
|
||||
private Uri scanMe; // Uri of image to be added to content store
|
||||
|
||||
//This should never be null!
|
||||
//private CordovaInterface cordova;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public CameraLauncher() {
|
||||
}
|
||||
|
||||
// public void setContext(CordovaInterface mCtx) {
|
||||
// super.setContext(mCtx);
|
||||
// if (CordovaInterface.class.isInstance(mCtx))
|
||||
// cordova = (CordovaInterface) mCtx;
|
||||
// else
|
||||
// LOG.d(LOG_TAG, "ERROR: You must use the CordovaInterface for this to work correctly. Please implement it in your activity");
|
||||
// }
|
||||
private Uri croppedUri;
|
||||
|
||||
/**
|
||||
* Executes the request and returns PluginResult.
|
||||
*
|
||||
* @param action The action to execute.
|
||||
* @param args JSONArry of arguments for the plugin.
|
||||
* @param action The action to execute.
|
||||
* @param args JSONArry of arguments for the plugin.
|
||||
* @param callbackContext The callback id used when calling back into JavaScript.
|
||||
* @return A PluginResult object with a status and message.
|
||||
* @return A PluginResult object with a status and message.
|
||||
*/
|
||||
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
|
||||
this.callbackContext = callbackContext;
|
||||
@@ -140,7 +131,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
this.targetHeight = args.getInt(4);
|
||||
this.encodingType = args.getInt(5);
|
||||
this.mediaType = args.getInt(6);
|
||||
//this.allowEdit = args.getBoolean(7); // This field is unused.
|
||||
this.allowEdit = args.getBoolean(7);
|
||||
this.correctOrientation = args.getBoolean(8);
|
||||
this.saveToPhotoAlbum = args.getBoolean(9);
|
||||
|
||||
@@ -158,7 +149,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
this.takePicture(destType, encodingType);
|
||||
}
|
||||
else if ((srcType == PHOTOLIBRARY) || (srcType == SAVEDPHOTOALBUM)) {
|
||||
this.getImage(srcType, destType);
|
||||
this.getImage(srcType, destType, encodingType);
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
@@ -182,6 +173,24 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
// LOCAL METHODS
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
private String getTempDirectoryPath() {
|
||||
File cache = null;
|
||||
|
||||
// SD Card Mounted
|
||||
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
||||
cache = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
|
||||
"/Android/data/" + cordova.getActivity().getPackageName() + "/cache/");
|
||||
}
|
||||
// Use internal storage
|
||||
else {
|
||||
cache = cordova.getActivity().getCacheDir();
|
||||
}
|
||||
|
||||
// Create the cache directory if it doesn't exist
|
||||
cache.mkdirs();
|
||||
return cache.getAbsolutePath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a picture with the camera.
|
||||
* When an image is captured or the camera view is cancelled, the result is returned
|
||||
@@ -200,8 +209,8 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
// Save the number of images currently on disk for later
|
||||
this.numPics = queryImgDB(whichContentStore()).getCount();
|
||||
|
||||
// Display camera
|
||||
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
|
||||
// Let's use the intent and see what happens
|
||||
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
|
||||
// Specify file so that large image is captured and returned
|
||||
File photo = createCaptureFile(encodingType);
|
||||
@@ -209,7 +218,17 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
this.imageUri = Uri.fromFile(photo);
|
||||
|
||||
if (this.cordova != null) {
|
||||
this.cordova.startActivityForResult((CordovaPlugin) this, intent, (CAMERA + 1) * 16 + returnType + 1);
|
||||
// Let's check to make sure the camera is actually installed. (Legacy Nexus 7 code)
|
||||
PackageManager mPm = this.cordova.getActivity().getPackageManager();
|
||||
if(intent.resolveActivity(mPm) != null)
|
||||
{
|
||||
|
||||
this.cordova.startActivityForResult((CordovaPlugin) this, intent, (CAMERA + 1) * 16 + returnType + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG.d(LOG_TAG, "Error: You don't have a default camera. Your device may not be CTS complaint.");
|
||||
}
|
||||
}
|
||||
// else
|
||||
// LOG.d(LOG_TAG, "ERROR: You must use the CordovaInterface for this to work correctly. Please implement it in your activity");
|
||||
@@ -224,48 +243,385 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
private File createCaptureFile(int encodingType) {
|
||||
File photo = null;
|
||||
if (encodingType == JPEG) {
|
||||
photo = new File(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()), ".Pic.jpg");
|
||||
photo = new File(getTempDirectoryPath(), ".Pic.jpg");
|
||||
} else if (encodingType == PNG) {
|
||||
photo = new File(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()), ".Pic.png");
|
||||
photo = new File(getTempDirectoryPath(), ".Pic.png");
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid Encoding Type: " + encodingType);
|
||||
}
|
||||
return photo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get image from photo library.
|
||||
*
|
||||
* @param quality Compression quality hint (0-100: 0=low quality & high compression, 100=compress of max quality)
|
||||
* @param srcType The album to get image from.
|
||||
* @param returnType Set the type of image to return.
|
||||
* @param encodingType
|
||||
*/
|
||||
// TODO: Images selected from SDCARD don't display correctly, but from CAMERA ALBUM do!
|
||||
public void getImage(int srcType, int returnType) {
|
||||
// TODO: Images from kitkat filechooser not going into crop function
|
||||
public void getImage(int srcType, int returnType, int encodingType) {
|
||||
Intent intent = new Intent();
|
||||
String title = GET_PICTURE;
|
||||
croppedUri = null;
|
||||
if (this.mediaType == PICTURE) {
|
||||
intent.setType("image/*");
|
||||
if (this.allowEdit) {
|
||||
intent.setAction(Intent.ACTION_PICK);
|
||||
intent.putExtra("crop", "true");
|
||||
if (targetWidth > 0) {
|
||||
intent.putExtra("outputX", targetWidth);
|
||||
}
|
||||
if (targetHeight > 0) {
|
||||
intent.putExtra("outputY", targetHeight);
|
||||
}
|
||||
if (targetHeight > 0 && targetWidth > 0 && targetWidth == targetHeight) {
|
||||
intent.putExtra("aspectX", 1);
|
||||
intent.putExtra("aspectY", 1);
|
||||
}
|
||||
File photo = createCaptureFile(encodingType);
|
||||
croppedUri = Uri.fromFile(photo);
|
||||
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, croppedUri);
|
||||
} else {
|
||||
intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
}
|
||||
} else if (this.mediaType == VIDEO) {
|
||||
intent.setType("video/*");
|
||||
title = GET_VIDEO;
|
||||
intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
} else if (this.mediaType == ALLMEDIA) {
|
||||
// I wanted to make the type 'image/*, video/*' but this does not work on all versions
|
||||
// of android so I had to go with the wildcard search.
|
||||
intent.setType("*/*");
|
||||
title = GET_All;
|
||||
intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
}
|
||||
else if (this.mediaType == VIDEO) {
|
||||
intent.setType("video/*");
|
||||
title = GET_VIDEO;
|
||||
}
|
||||
else if (this.mediaType == ALLMEDIA) {
|
||||
// I wanted to make the type 'image/*, video/*' but this does not work on all versions
|
||||
// of android so I had to go with the wildcard search.
|
||||
intent.setType("*/*");
|
||||
title = GET_All;
|
||||
}
|
||||
|
||||
intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
if (this.cordova != null) {
|
||||
this.cordova.startActivityForResult((CordovaPlugin) this, Intent.createChooser(intent,
|
||||
new String(title)), (srcType + 1) * 16 + returnType + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Brings up the UI to perform crop on passed image URI
|
||||
*
|
||||
* @param picUri
|
||||
*/
|
||||
private void performCrop(Uri picUri, int destType, Intent cameraIntent) {
|
||||
try {
|
||||
Intent cropIntent = new Intent("com.android.camera.action.CROP");
|
||||
// indicate image type and Uri
|
||||
cropIntent.setDataAndType(picUri, "image/*");
|
||||
// set crop properties
|
||||
cropIntent.putExtra("crop", "true");
|
||||
|
||||
// indicate output X and Y
|
||||
if (targetWidth > 0) {
|
||||
cropIntent.putExtra("outputX", targetWidth);
|
||||
}
|
||||
if (targetHeight > 0) {
|
||||
cropIntent.putExtra("outputY", targetHeight);
|
||||
}
|
||||
if (targetHeight > 0 && targetWidth > 0 && targetWidth == targetHeight) {
|
||||
cropIntent.putExtra("aspectX", 1);
|
||||
cropIntent.putExtra("aspectY", 1);
|
||||
}
|
||||
// create new file handle to get full resolution crop
|
||||
croppedUri = Uri.fromFile(new File(getTempDirectoryPath(), System.currentTimeMillis() + ".jpg"));
|
||||
cropIntent.putExtra("output", croppedUri);
|
||||
|
||||
// start the activity - we handle returning in onActivityResult
|
||||
|
||||
if (this.cordova != null) {
|
||||
this.cordova.startActivityForResult((CordovaPlugin) this,
|
||||
cropIntent, CROP_CAMERA + destType);
|
||||
}
|
||||
} catch (ActivityNotFoundException anfe) {
|
||||
Log.e(LOG_TAG, "Crop operation not supported on this device");
|
||||
try {
|
||||
processResultFromCamera(destType, cameraIntent);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
Log.e(LOG_TAG, "Unable to write to file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies all needed transformation to the image received from the camera.
|
||||
*
|
||||
* @param destType In which form should we return the image
|
||||
* @param intent An Intent, which can return result data to the caller (various data can be attached to Intent "extras").
|
||||
*/
|
||||
private void processResultFromCamera(int destType, Intent intent) throws IOException {
|
||||
int rotate = 0;
|
||||
|
||||
// Create an ExifHelper to save the exif data that is lost during compression
|
||||
ExifHelper exif = new ExifHelper();
|
||||
String sourcePath;
|
||||
try {
|
||||
if(allowEdit && croppedUri != null)
|
||||
{
|
||||
sourcePath = FileHelper.stripFileProtocol(croppedUri.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
sourcePath = getTempDirectoryPath() + "/.Pic.jpg";
|
||||
}
|
||||
|
||||
//We don't support PNG, so let's not pretend we do
|
||||
exif.createInFile(getTempDirectoryPath() + "/.Pic.jpg");
|
||||
exif.readExifData();
|
||||
rotate = exif.getOrientation();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Bitmap bitmap = null;
|
||||
Uri uri = null;
|
||||
|
||||
// If sending base64 image back
|
||||
if (destType == DATA_URL) {
|
||||
if(croppedUri != null) {
|
||||
bitmap = getScaledBitmap(FileHelper.stripFileProtocol(croppedUri.toString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
bitmap = getScaledBitmap(FileHelper.stripFileProtocol(imageUri.toString()));
|
||||
}
|
||||
if (bitmap == null) {
|
||||
// Try to get the bitmap from intent.
|
||||
bitmap = (Bitmap)intent.getExtras().get("data");
|
||||
}
|
||||
|
||||
// Double-check the bitmap.
|
||||
if (bitmap == null) {
|
||||
Log.d(LOG_TAG, "I either have a null image path or bitmap");
|
||||
this.failPicture("Unable to create bitmap!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (rotate != 0 && this.correctOrientation) {
|
||||
bitmap = getRotatedBitmap(rotate, bitmap, exif);
|
||||
}
|
||||
|
||||
this.processPicture(bitmap);
|
||||
checkForDuplicateImage(DATA_URL);
|
||||
}
|
||||
|
||||
// If sending filename back
|
||||
else if (destType == FILE_URI || destType == NATIVE_URI) {
|
||||
uri = Uri.fromFile(new File(getTempDirectoryPath(), System.currentTimeMillis() + ".jpg"));
|
||||
|
||||
if (this.saveToPhotoAlbum) {
|
||||
//Create a URI on the filesystem so that we can write the file.
|
||||
uri = Uri.fromFile(new File(getPicutresPath()));
|
||||
} else {
|
||||
uri = Uri.fromFile(new File(getTempDirectoryPath(), System.currentTimeMillis() + ".jpg"));
|
||||
}
|
||||
|
||||
if (uri == null) {
|
||||
this.failPicture("Error capturing image - no media storage found.");
|
||||
return;
|
||||
}
|
||||
|
||||
// If all this is true we shouldn't compress the image.
|
||||
if (this.targetHeight == -1 && this.targetWidth == -1 && this.mQuality == 100 &&
|
||||
!this.correctOrientation) {
|
||||
writeUncompressedImage(uri);
|
||||
|
||||
this.callbackContext.success(uri.toString());
|
||||
} else {
|
||||
bitmap = getScaledBitmap(FileHelper.stripFileProtocol(imageUri.toString()));
|
||||
|
||||
if (rotate != 0 && this.correctOrientation) {
|
||||
bitmap = getRotatedBitmap(rotate, bitmap, exif);
|
||||
}
|
||||
|
||||
// Add compressed version of captured image to returned media store Uri
|
||||
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, this.mQuality, os);
|
||||
os.close();
|
||||
|
||||
// Restore exif data to file
|
||||
if (this.encodingType == JPEG) {
|
||||
String exifPath;
|
||||
exifPath = uri.getPath();
|
||||
exif.createOutFile(exifPath);
|
||||
exif.writeExifData();
|
||||
}
|
||||
|
||||
//Broadcast change to File System on MediaStore
|
||||
if(this.saveToPhotoAlbum) {
|
||||
refreshGallery(uri);
|
||||
}
|
||||
|
||||
|
||||
// Send Uri back to JavaScript for viewing image
|
||||
this.callbackContext.success(uri.toString());
|
||||
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
this.cleanup(FILE_URI, this.imageUri, uri, bitmap);
|
||||
bitmap = null;
|
||||
}
|
||||
|
||||
private String getPicutresPath()
|
||||
{
|
||||
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
|
||||
String imageFileName = "IMG_" + timeStamp + ".jpg";
|
||||
File storageDir = Environment.getExternalStoragePublicDirectory(
|
||||
Environment.DIRECTORY_PICTURES);
|
||||
String galleryPath = storageDir.getAbsolutePath() + "/" + imageFileName;
|
||||
return galleryPath;
|
||||
}
|
||||
|
||||
private void refreshGallery(Uri contentUri)
|
||||
{
|
||||
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
|
||||
mediaScanIntent.setData(contentUri);
|
||||
this.cordova.getActivity().sendBroadcast(mediaScanIntent);
|
||||
}
|
||||
|
||||
|
||||
private String ouputModifiedBitmap(Bitmap bitmap, Uri uri) throws IOException {
|
||||
// Create an ExifHelper to save the exif data that is lost during compression
|
||||
String modifiedPath = getTempDirectoryPath() + "/modified.jpg";
|
||||
|
||||
OutputStream os = new FileOutputStream(modifiedPath);
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, this.mQuality, os);
|
||||
os.close();
|
||||
|
||||
// Some content: URIs do not map to file paths (e.g. picasa).
|
||||
String realPath = FileHelper.getRealPath(uri, this.cordova);
|
||||
ExifHelper exif = new ExifHelper();
|
||||
if (realPath != null && this.encodingType == JPEG) {
|
||||
try {
|
||||
exif.createInFile(realPath);
|
||||
exif.readExifData();
|
||||
if (this.correctOrientation && this.orientationCorrected) {
|
||||
exif.resetOrientation();
|
||||
}
|
||||
exif.createOutFile(modifiedPath);
|
||||
exif.writeExifData();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return modifiedPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies all needed transformation to the image received from the gallery.
|
||||
*
|
||||
* @param destType In which form should we return the image
|
||||
* @param intent An Intent, which can return result data to the caller (various data can be attached to Intent "extras").
|
||||
*/
|
||||
private void processResultFromGallery(int destType, Intent intent) {
|
||||
Uri uri = intent.getData();
|
||||
if (uri == null) {
|
||||
if (croppedUri != null) {
|
||||
uri = croppedUri;
|
||||
} else {
|
||||
this.failPicture("null data from photo library");
|
||||
return;
|
||||
}
|
||||
}
|
||||
int rotate = 0;
|
||||
|
||||
// If you ask for video or all media type you will automatically get back a file URI
|
||||
// and there will be no attempt to resize any returned data
|
||||
if (this.mediaType != PICTURE) {
|
||||
this.callbackContext.success(uri.toString());
|
||||
}
|
||||
else {
|
||||
// This is a special case to just return the path as no scaling,
|
||||
// rotating, nor compressing needs to be done
|
||||
if (this.targetHeight == -1 && this.targetWidth == -1 &&
|
||||
(destType == FILE_URI || destType == NATIVE_URI) && !this.correctOrientation) {
|
||||
this.callbackContext.success(uri.toString());
|
||||
} else {
|
||||
String uriString = uri.toString();
|
||||
// Get the path to the image. Makes loading so much easier.
|
||||
String mimeType = FileHelper.getMimeType(uriString, this.cordova);
|
||||
// If we don't have a valid image so quit.
|
||||
if (!("image/jpeg".equalsIgnoreCase(mimeType) || "image/png".equalsIgnoreCase(mimeType))) {
|
||||
Log.d(LOG_TAG, "I either have a null image path or bitmap");
|
||||
this.failPicture("Unable to retrieve path to picture!");
|
||||
return;
|
||||
}
|
||||
Bitmap bitmap = null;
|
||||
try {
|
||||
bitmap = getScaledBitmap(uriString);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (bitmap == null) {
|
||||
Log.d(LOG_TAG, "I either have a null image path or bitmap");
|
||||
this.failPicture("Unable to create bitmap!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.correctOrientation) {
|
||||
rotate = getImageOrientation(uri);
|
||||
if (rotate != 0) {
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.setRotate(rotate);
|
||||
try {
|
||||
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||
this.orientationCorrected = true;
|
||||
} catch (OutOfMemoryError oom) {
|
||||
this.orientationCorrected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If sending base64 image back
|
||||
if (destType == DATA_URL) {
|
||||
this.processPicture(bitmap);
|
||||
}
|
||||
|
||||
// If sending filename back
|
||||
else if (destType == FILE_URI || destType == NATIVE_URI) {
|
||||
// Did we modify the image?
|
||||
if ( (this.targetHeight > 0 && this.targetWidth > 0) ||
|
||||
(this.correctOrientation && this.orientationCorrected) ) {
|
||||
try {
|
||||
String modifiedPath = this.ouputModifiedBitmap(bitmap, uri);
|
||||
// The modified image is cached by the app in order to get around this and not have to delete you
|
||||
// application cache I'm adding the current system time to the end of the file url.
|
||||
this.callbackContext.success("file://" + modifiedPath + "?" + System.currentTimeMillis());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
this.failPicture("Error retrieving image.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.callbackContext.success(uri.toString());
|
||||
}
|
||||
}
|
||||
if (bitmap != null) {
|
||||
bitmap.recycle();
|
||||
bitmap = null;
|
||||
}
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the camera view exits.
|
||||
*
|
||||
@@ -276,106 +632,47 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
*/
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||
|
||||
// Get src and dest types from request code
|
||||
// Get src and dest types from request code for a Camera Activity
|
||||
int srcType = (requestCode / 16) - 1;
|
||||
int destType = (requestCode % 16) - 1;
|
||||
int rotate = 0;
|
||||
|
||||
// If Camera Crop
|
||||
if (requestCode >= CROP_CAMERA) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
|
||||
// Because of the inability to pass through multiple intents, this hack will allow us
|
||||
// to pass arcane codes back.
|
||||
destType = requestCode - CROP_CAMERA;
|
||||
try {
|
||||
processResultFromCamera(destType, intent);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(LOG_TAG, "Unable to write to file");
|
||||
}
|
||||
|
||||
}// If cancelled
|
||||
else if (resultCode == Activity.RESULT_CANCELED) {
|
||||
this.failPicture("Camera cancelled.");
|
||||
}
|
||||
|
||||
// If something else
|
||||
else {
|
||||
this.failPicture("Did not complete!");
|
||||
}
|
||||
}
|
||||
// If CAMERA
|
||||
if (srcType == CAMERA) {
|
||||
else if (srcType == CAMERA) {
|
||||
// If image available
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
try {
|
||||
// Create an ExifHelper to save the exif data that is lost during compression
|
||||
ExifHelper exif = new ExifHelper();
|
||||
try {
|
||||
if (this.encodingType == JPEG) {
|
||||
exif.createInFile(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()) + "/.Pic.jpg");
|
||||
exif.readExifData();
|
||||
rotate = exif.getOrientation();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
if(this.allowEdit)
|
||||
{
|
||||
Uri tmpFile = Uri.fromFile(new File(getTempDirectoryPath(), ".Pic.jpg"));
|
||||
performCrop(tmpFile, destType, intent);
|
||||
}
|
||||
|
||||
Bitmap bitmap = null;
|
||||
Uri uri = null;
|
||||
|
||||
// If sending base64 image back
|
||||
if (destType == DATA_URL) {
|
||||
bitmap = getScaledBitmap(FileHelper.stripFileProtocol(imageUri.toString()));
|
||||
if (bitmap == null) {
|
||||
// Try to get the bitmap from intent.
|
||||
bitmap = (Bitmap)intent.getExtras().get("data");
|
||||
}
|
||||
|
||||
// Double-check the bitmap.
|
||||
if (bitmap == null) {
|
||||
Log.d(LOG_TAG, "I either have a null image path or bitmap");
|
||||
this.failPicture("Unable to create bitmap!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (rotate != 0 && this.correctOrientation) {
|
||||
bitmap = getRotatedBitmap(rotate, bitmap, exif);
|
||||
}
|
||||
|
||||
this.processPicture(bitmap);
|
||||
checkForDuplicateImage(DATA_URL);
|
||||
else {
|
||||
this.processResultFromCamera(destType, intent);
|
||||
}
|
||||
|
||||
// If sending filename back
|
||||
else if (destType == FILE_URI || destType == NATIVE_URI) {
|
||||
if (this.saveToPhotoAlbum) {
|
||||
Uri inputUri = getUriFromMediaStore();
|
||||
//Just because we have a media URI doesn't mean we have a real file, we need to make it
|
||||
uri = Uri.fromFile(new File(FileHelper.getRealPath(inputUri, this.cordova)));
|
||||
} else {
|
||||
uri = Uri.fromFile(new File(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()), System.currentTimeMillis() + ".jpg"));
|
||||
}
|
||||
|
||||
if (uri == null) {
|
||||
this.failPicture("Error capturing image - no media storage found.");
|
||||
}
|
||||
|
||||
// If all this is true we shouldn't compress the image.
|
||||
if (this.targetHeight == -1 && this.targetWidth == -1 && this.mQuality == 100 &&
|
||||
!this.correctOrientation) {
|
||||
writeUncompressedImage(uri);
|
||||
|
||||
this.callbackContext.success(uri.toString());
|
||||
} else {
|
||||
bitmap = getScaledBitmap(FileHelper.stripFileProtocol(imageUri.toString()));
|
||||
|
||||
if (rotate != 0 && this.correctOrientation) {
|
||||
bitmap = getRotatedBitmap(rotate, bitmap, exif);
|
||||
}
|
||||
|
||||
// Add compressed version of captured image to returned media store Uri
|
||||
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, this.mQuality, os);
|
||||
os.close();
|
||||
|
||||
// Restore exif data to file
|
||||
if (this.encodingType == JPEG) {
|
||||
String exifPath;
|
||||
if (this.saveToPhotoAlbum) {
|
||||
exifPath = FileHelper.getRealPath(uri, this.cordova);
|
||||
} else {
|
||||
exifPath = uri.getPath();
|
||||
}
|
||||
exif.createOutFile(exifPath);
|
||||
exif.writeExifData();
|
||||
}
|
||||
|
||||
}
|
||||
// Send Uri back to JavaScript for viewing image
|
||||
this.callbackContext.success(uri.toString());
|
||||
}
|
||||
|
||||
this.cleanup(FILE_URI, this.imageUri, uri, bitmap);
|
||||
bitmap = null;
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
this.failPicture("Error capturing image.");
|
||||
@@ -392,108 +689,10 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
this.failPicture("Did not complete!");
|
||||
}
|
||||
}
|
||||
|
||||
// If retrieving photo from library
|
||||
else if ((srcType == PHOTOLIBRARY) || (srcType == SAVEDPHOTOALBUM)) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
Uri uri = intent.getData();
|
||||
|
||||
// If you ask for video or all media type you will automatically get back a file URI
|
||||
// and there will be no attempt to resize any returned data
|
||||
if (this.mediaType != PICTURE) {
|
||||
this.callbackContext.success(uri.toString());
|
||||
}
|
||||
else {
|
||||
// This is a special case to just return the path as no scaling,
|
||||
// rotating, nor compressing needs to be done
|
||||
if (this.targetHeight == -1 && this.targetWidth == -1 &&
|
||||
(destType == FILE_URI || destType == NATIVE_URI) && !this.correctOrientation) {
|
||||
this.callbackContext.success(uri.toString());
|
||||
} else {
|
||||
String uriString = uri.toString();
|
||||
// Get the path to the image. Makes loading so much easier.
|
||||
String mimeType = FileHelper.getMimeType(uriString, this.cordova);
|
||||
// If we don't have a valid image so quit.
|
||||
if (!("image/jpeg".equalsIgnoreCase(mimeType) || "image/png".equalsIgnoreCase(mimeType))) {
|
||||
Log.d(LOG_TAG, "I either have a null image path or bitmap");
|
||||
this.failPicture("Unable to retrieve path to picture!");
|
||||
return;
|
||||
}
|
||||
Bitmap bitmap = null;
|
||||
try {
|
||||
bitmap = getScaledBitmap(uriString);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (bitmap == null) {
|
||||
Log.d(LOG_TAG, "I either have a null image path or bitmap");
|
||||
this.failPicture("Unable to create bitmap!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.correctOrientation) {
|
||||
rotate = getImageOrientation(uri);
|
||||
if (rotate != 0) {
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.setRotate(rotate);
|
||||
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||
}
|
||||
}
|
||||
|
||||
// If sending base64 image back
|
||||
if (destType == DATA_URL) {
|
||||
this.processPicture(bitmap);
|
||||
}
|
||||
|
||||
// If sending filename back
|
||||
else if (destType == FILE_URI || destType == NATIVE_URI) {
|
||||
// Do we need to scale the returned file
|
||||
if (this.targetHeight > 0 && this.targetWidth > 0) {
|
||||
try {
|
||||
// Create an ExifHelper to save the exif data that is lost during compression
|
||||
String resizePath = DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()) + "/resize.jpg";
|
||||
// Some content: URIs do not map to file paths (e.g. picasa).
|
||||
String realPath = FileHelper.getRealPath(uri, this.cordova);
|
||||
ExifHelper exif = new ExifHelper();
|
||||
if (realPath != null && this.encodingType == JPEG) {
|
||||
try {
|
||||
exif.createInFile(realPath);
|
||||
exif.readExifData();
|
||||
rotate = exif.getOrientation();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
OutputStream os = new FileOutputStream(resizePath);
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, this.mQuality, os);
|
||||
os.close();
|
||||
|
||||
// Restore exif data to file
|
||||
if (realPath != null && this.encodingType == JPEG) {
|
||||
exif.createOutFile(resizePath);
|
||||
exif.writeExifData();
|
||||
}
|
||||
|
||||
// The resized image is cached by the app in order to get around this and not have to delete you
|
||||
// application cache I'm adding the current system time to the end of the file url.
|
||||
this.callbackContext.success("file://" + resizePath + "?" + System.currentTimeMillis());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
this.failPicture("Error retrieving image.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.callbackContext.success(uri.toString());
|
||||
}
|
||||
}
|
||||
if (bitmap != null) {
|
||||
bitmap.recycle();
|
||||
bitmap = null;
|
||||
}
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
if (resultCode == Activity.RESULT_OK && intent != null) {
|
||||
this.processResultFromGallery(destType, intent);
|
||||
}
|
||||
else if (resultCode == Activity.RESULT_CANCELED) {
|
||||
this.failPicture("Selection cancelled.");
|
||||
@@ -505,14 +704,18 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
}
|
||||
|
||||
private int getImageOrientation(Uri uri) {
|
||||
String[] cols = { MediaStore.Images.Media.ORIENTATION };
|
||||
Cursor cursor = cordova.getActivity().getContentResolver().query(uri,
|
||||
cols, null, null, null);
|
||||
int rotate = 0;
|
||||
if (cursor != null) {
|
||||
cursor.moveToPosition(0);
|
||||
rotate = cursor.getInt(0);
|
||||
cursor.close();
|
||||
String[] cols = { MediaStore.Images.Media.ORIENTATION };
|
||||
try {
|
||||
Cursor cursor = cordova.getActivity().getContentResolver().query(uri,
|
||||
cols, null, null, null);
|
||||
if (cursor != null) {
|
||||
cursor.moveToPosition(0);
|
||||
rotate = cursor.getInt(0);
|
||||
cursor.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// You can get an IllegalArgumentException if ContentProvider doesn't support querying for orientation.
|
||||
}
|
||||
return rotate;
|
||||
}
|
||||
@@ -532,8 +735,20 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
} else {
|
||||
matrix.setRotate(rotate, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);
|
||||
}
|
||||
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||
exif.resetOrientation();
|
||||
|
||||
try
|
||||
{
|
||||
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||
exif.resetOrientation();
|
||||
}
|
||||
catch (OutOfMemoryError oom)
|
||||
{
|
||||
// You can run out of memory if the image is very large:
|
||||
// http://simonmacdonald.blogspot.ca/2012/07/change-to-camera-code-in-phonegap-190.html
|
||||
// If this happens, simply do not rotate the image and return it unmodified.
|
||||
// If you do not catch the OutOfMemoryError, the Android app crashes.
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
@@ -547,16 +762,33 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
*/
|
||||
private void writeUncompressedImage(Uri uri) throws FileNotFoundException,
|
||||
IOException {
|
||||
FileInputStream fis = new FileInputStream(FileHelper.stripFileProtocol(imageUri.toString()));
|
||||
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
|
||||
byte[] buffer = new byte[4096];
|
||||
int len;
|
||||
while ((len = fis.read(buffer)) != -1) {
|
||||
os.write(buffer, 0, len);
|
||||
FileInputStream fis = null;
|
||||
OutputStream os = null;
|
||||
try {
|
||||
fis = new FileInputStream(FileHelper.stripFileProtocol(imageUri.toString()));
|
||||
os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
|
||||
byte[] buffer = new byte[4096];
|
||||
int len;
|
||||
while ((len = fis.read(buffer)) != -1) {
|
||||
os.write(buffer, 0, len);
|
||||
}
|
||||
os.flush();
|
||||
} finally {
|
||||
if (os != null) {
|
||||
try {
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
LOG.d(LOG_TAG,"Exception while closing output stream.");
|
||||
}
|
||||
}
|
||||
if (fis != null) {
|
||||
try {
|
||||
fis.close();
|
||||
} catch (IOException e) {
|
||||
LOG.d(LOG_TAG,"Exception while closing file input stream.");
|
||||
}
|
||||
}
|
||||
}
|
||||
os.flush();
|
||||
os.close();
|
||||
fis.close();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -570,11 +802,11 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
Uri uri;
|
||||
try {
|
||||
uri = this.cordova.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
|
||||
} catch (UnsupportedOperationException e) {
|
||||
} catch (RuntimeException e) {
|
||||
LOG.d(LOG_TAG, "Can't write to external media storage.");
|
||||
try {
|
||||
uri = this.cordova.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
} catch (RuntimeException ex) {
|
||||
LOG.d(LOG_TAG, "Can't write to internal media storage.");
|
||||
return null;
|
||||
}
|
||||
@@ -592,13 +824,39 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
private Bitmap getScaledBitmap(String imageUrl) throws IOException {
|
||||
// If no new width or height were specified return the original bitmap
|
||||
if (this.targetWidth <= 0 && this.targetHeight <= 0) {
|
||||
return BitmapFactory.decodeStream(FileHelper.getInputStreamFromUriString(imageUrl, cordova));
|
||||
InputStream fileStream = null;
|
||||
Bitmap image = null;
|
||||
try {
|
||||
fileStream = FileHelper.getInputStreamFromUriString(imageUrl, cordova);
|
||||
image = BitmapFactory.decodeStream(fileStream);
|
||||
} finally {
|
||||
if (fileStream != null) {
|
||||
try {
|
||||
fileStream.close();
|
||||
} catch (IOException e) {
|
||||
LOG.d(LOG_TAG,"Exception while closing file input stream.");
|
||||
}
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
// figure out the original width and height of the image
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeStream(FileHelper.getInputStreamFromUriString(imageUrl, cordova), null, options);
|
||||
InputStream fileStream = null;
|
||||
try {
|
||||
fileStream = FileHelper.getInputStreamFromUriString(imageUrl, cordova);
|
||||
BitmapFactory.decodeStream(fileStream, null, options);
|
||||
} finally {
|
||||
if (fileStream != null) {
|
||||
try {
|
||||
fileStream.close();
|
||||
} catch (IOException e) {
|
||||
LOG.d(LOG_TAG,"Exception while closing file input stream.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//CB-2292: WTF? Why is the width null?
|
||||
if(options.outWidth == 0 || options.outHeight == 0)
|
||||
@@ -612,7 +870,19 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
// Load in the smallest bitmap possible that is closest to the size we want
|
||||
options.inJustDecodeBounds = false;
|
||||
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, this.targetWidth, this.targetHeight);
|
||||
Bitmap unscaledBitmap = BitmapFactory.decodeStream(FileHelper.getInputStreamFromUriString(imageUrl, cordova), null, options);
|
||||
Bitmap unscaledBitmap = null;
|
||||
try {
|
||||
fileStream = FileHelper.getInputStreamFromUriString(imageUrl, cordova);
|
||||
unscaledBitmap = BitmapFactory.decodeStream(fileStream, null, options);
|
||||
} finally {
|
||||
if (fileStream != null) {
|
||||
try {
|
||||
fileStream.close();
|
||||
} catch (IOException e) {
|
||||
LOG.d(LOG_TAG,"Exception while closing file input stream.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unscaledBitmap == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -749,6 +1019,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
}
|
||||
Uri uri = Uri.parse(contentStore + "/" + id);
|
||||
this.cordova.getActivity().getContentResolver().delete(uri, null, null);
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
185
src/android/ExifHelper.java
Normal file
185
src/android/ExifHelper.java
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
package org.apache.cordova.camera;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import android.media.ExifInterface;
|
||||
|
||||
public class ExifHelper {
|
||||
private String aperture = null;
|
||||
private String datetime = null;
|
||||
private String exposureTime = null;
|
||||
private String flash = null;
|
||||
private String focalLength = null;
|
||||
private String gpsAltitude = null;
|
||||
private String gpsAltitudeRef = null;
|
||||
private String gpsDateStamp = null;
|
||||
private String gpsLatitude = null;
|
||||
private String gpsLatitudeRef = null;
|
||||
private String gpsLongitude = null;
|
||||
private String gpsLongitudeRef = null;
|
||||
private String gpsProcessingMethod = null;
|
||||
private String gpsTimestamp = null;
|
||||
private String iso = null;
|
||||
private String make = null;
|
||||
private String model = null;
|
||||
private String orientation = null;
|
||||
private String whiteBalance = null;
|
||||
|
||||
private ExifInterface inFile = null;
|
||||
private ExifInterface outFile = null;
|
||||
|
||||
/**
|
||||
* The file before it is compressed
|
||||
*
|
||||
* @param filePath
|
||||
* @throws IOException
|
||||
*/
|
||||
public void createInFile(String filePath) throws IOException {
|
||||
this.inFile = new ExifInterface(filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* The file after it has been compressed
|
||||
*
|
||||
* @param filePath
|
||||
* @throws IOException
|
||||
*/
|
||||
public void createOutFile(String filePath) throws IOException {
|
||||
this.outFile = new ExifInterface(filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all the EXIF data from the input file.
|
||||
*/
|
||||
public void readExifData() {
|
||||
this.aperture = inFile.getAttribute(ExifInterface.TAG_APERTURE);
|
||||
this.datetime = inFile.getAttribute(ExifInterface.TAG_DATETIME);
|
||||
this.exposureTime = inFile.getAttribute(ExifInterface.TAG_EXPOSURE_TIME);
|
||||
this.flash = inFile.getAttribute(ExifInterface.TAG_FLASH);
|
||||
this.focalLength = inFile.getAttribute(ExifInterface.TAG_FOCAL_LENGTH);
|
||||
this.gpsAltitude = inFile.getAttribute(ExifInterface.TAG_GPS_ALTITUDE);
|
||||
this.gpsAltitudeRef = inFile.getAttribute(ExifInterface.TAG_GPS_ALTITUDE_REF);
|
||||
this.gpsDateStamp = inFile.getAttribute(ExifInterface.TAG_GPS_DATESTAMP);
|
||||
this.gpsLatitude = inFile.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
|
||||
this.gpsLatitudeRef = inFile.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF);
|
||||
this.gpsLongitude = inFile.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
|
||||
this.gpsLongitudeRef = inFile.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF);
|
||||
this.gpsProcessingMethod = inFile.getAttribute(ExifInterface.TAG_GPS_PROCESSING_METHOD);
|
||||
this.gpsTimestamp = inFile.getAttribute(ExifInterface.TAG_GPS_TIMESTAMP);
|
||||
this.iso = inFile.getAttribute(ExifInterface.TAG_ISO);
|
||||
this.make = inFile.getAttribute(ExifInterface.TAG_MAKE);
|
||||
this.model = inFile.getAttribute(ExifInterface.TAG_MODEL);
|
||||
this.orientation = inFile.getAttribute(ExifInterface.TAG_ORIENTATION);
|
||||
this.whiteBalance = inFile.getAttribute(ExifInterface.TAG_WHITE_BALANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the previously stored EXIF data to the output file.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeExifData() throws IOException {
|
||||
// Don't try to write to a null file
|
||||
if (this.outFile == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.aperture != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_APERTURE, this.aperture);
|
||||
}
|
||||
if (this.datetime != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_DATETIME, this.datetime);
|
||||
}
|
||||
if (this.exposureTime != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_EXPOSURE_TIME, this.exposureTime);
|
||||
}
|
||||
if (this.flash != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_FLASH, this.flash);
|
||||
}
|
||||
if (this.focalLength != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_FOCAL_LENGTH, this.focalLength);
|
||||
}
|
||||
if (this.gpsAltitude != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_GPS_ALTITUDE, this.gpsAltitude);
|
||||
}
|
||||
if (this.gpsAltitudeRef != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_GPS_ALTITUDE_REF, this.gpsAltitudeRef);
|
||||
}
|
||||
if (this.gpsDateStamp != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_GPS_DATESTAMP, this.gpsDateStamp);
|
||||
}
|
||||
if (this.gpsLatitude != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_GPS_LATITUDE, this.gpsLatitude);
|
||||
}
|
||||
if (this.gpsLatitudeRef != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, this.gpsLatitudeRef);
|
||||
}
|
||||
if (this.gpsLongitude != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, this.gpsLongitude);
|
||||
}
|
||||
if (this.gpsLongitudeRef != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, this.gpsLongitudeRef);
|
||||
}
|
||||
if (this.gpsProcessingMethod != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_GPS_PROCESSING_METHOD, this.gpsProcessingMethod);
|
||||
}
|
||||
if (this.gpsTimestamp != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_GPS_TIMESTAMP, this.gpsTimestamp);
|
||||
}
|
||||
if (this.iso != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_ISO, this.iso);
|
||||
}
|
||||
if (this.make != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_MAKE, this.make);
|
||||
}
|
||||
if (this.model != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_MODEL, this.model);
|
||||
}
|
||||
if (this.orientation != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_ORIENTATION, this.orientation);
|
||||
}
|
||||
if (this.whiteBalance != null) {
|
||||
this.outFile.setAttribute(ExifInterface.TAG_WHITE_BALANCE, this.whiteBalance);
|
||||
}
|
||||
|
||||
this.outFile.saveAttributes();
|
||||
}
|
||||
|
||||
public int getOrientation() {
|
||||
int o = Integer.parseInt(this.orientation);
|
||||
|
||||
if (o == ExifInterface.ORIENTATION_NORMAL) {
|
||||
return 0;
|
||||
} else if (o == ExifInterface.ORIENTATION_ROTATE_90) {
|
||||
return 90;
|
||||
} else if (o == ExifInterface.ORIENTATION_ROTATE_180) {
|
||||
return 180;
|
||||
} else if (o == ExifInterface.ORIENTATION_ROTATE_270) {
|
||||
return 270;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void resetOrientation() {
|
||||
this.orientation = "" + ExifInterface.ORIENTATION_NORMAL;
|
||||
}
|
||||
}
|
||||
231
src/android/FileHelper.java
Normal file
231
src/android/FileHelper.java
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
package org.apache.cordova.camera;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.CursorLoader;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.MediaStore;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import org.apache.cordova.CordovaInterface;
|
||||
import org.apache.cordova.LOG;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Locale;
|
||||
|
||||
public class FileHelper {
|
||||
private static final String LOG_TAG = "FileUtils";
|
||||
private static final String _DATA = "_data";
|
||||
|
||||
/**
|
||||
* Returns the real path of the given URI string.
|
||||
* If the given URI string represents a content:// URI, the real path is retrieved from the media store.
|
||||
*
|
||||
* @param uriString the URI string of the audio/image/video
|
||||
* @param cordova the current application context
|
||||
* @return the full path to the file
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static String getRealPath(Uri uri, CordovaInterface cordova) {
|
||||
String realPath = null;
|
||||
|
||||
if (Build.VERSION.SDK_INT < 11)
|
||||
realPath = FileHelper.getRealPathFromURI_BelowAPI11(cordova.getActivity(), uri);
|
||||
|
||||
// SDK >= 11 && SDK < 19
|
||||
else if (Build.VERSION.SDK_INT < 19)
|
||||
realPath = FileHelper.getRealPathFromURI_API11to18(cordova.getActivity(), uri);
|
||||
|
||||
// SDK > 19 (Android 4.4)
|
||||
else
|
||||
realPath = FileHelper.getRealPathFromURI_API19(cordova.getActivity(), uri);
|
||||
|
||||
return realPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the real path of the given URI.
|
||||
* If the given URI is a content:// URI, the real path is retrieved from the media store.
|
||||
*
|
||||
* @param uri the URI of the audio/image/video
|
||||
* @param cordova the current application context
|
||||
* @return the full path to the file
|
||||
*/
|
||||
public static String getRealPath(String uriString, CordovaInterface cordova) {
|
||||
return FileHelper.getRealPath(Uri.parse(uriString), cordova);
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public static String getRealPathFromURI_API19(Context context, Uri uri) {
|
||||
String filePath = "";
|
||||
try {
|
||||
String wholeID = DocumentsContract.getDocumentId(uri);
|
||||
|
||||
// Split at colon, use second item in the array
|
||||
String id = wholeID.indexOf(":") > -1 ? wholeID.split(":")[1] : wholeID.indexOf(";") > -1 ? wholeID
|
||||
.split(";")[1] : wholeID;
|
||||
|
||||
String[] column = { MediaStore.Images.Media.DATA };
|
||||
|
||||
// where id is equal to
|
||||
String sel = MediaStore.Images.Media._ID + "=?";
|
||||
|
||||
Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column,
|
||||
sel, new String[] { id }, null);
|
||||
|
||||
int columnIndex = cursor.getColumnIndex(column[0]);
|
||||
|
||||
if (cursor.moveToFirst()) {
|
||||
filePath = cursor.getString(columnIndex);
|
||||
}
|
||||
cursor.close();
|
||||
} catch (Exception e) {
|
||||
filePath = "";
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
|
||||
String[] proj = { MediaStore.Images.Media.DATA };
|
||||
String result = null;
|
||||
|
||||
try {
|
||||
CursorLoader cursorLoader = new CursorLoader(context, contentUri, proj, null, null, null);
|
||||
Cursor cursor = cursorLoader.loadInBackground();
|
||||
|
||||
if (cursor != null) {
|
||||
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
|
||||
cursor.moveToFirst();
|
||||
result = cursor.getString(column_index);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri) {
|
||||
String[] proj = { MediaStore.Images.Media.DATA };
|
||||
String result = null;
|
||||
|
||||
try {
|
||||
Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
|
||||
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
|
||||
cursor.moveToFirst();
|
||||
result = cursor.getString(column_index);
|
||||
|
||||
} catch (Exception e) {
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an input stream based on given URI string.
|
||||
*
|
||||
* @param uriString the URI string from which to obtain the input stream
|
||||
* @param cordova the current application context
|
||||
* @return an input stream into the data at the given URI or null if given an invalid URI string
|
||||
* @throws IOException
|
||||
*/
|
||||
public static InputStream getInputStreamFromUriString(String uriString, CordovaInterface cordova)
|
||||
throws IOException {
|
||||
InputStream returnValue = null;
|
||||
if (uriString.startsWith("content")) {
|
||||
Uri uri = Uri.parse(uriString);
|
||||
returnValue = cordova.getActivity().getContentResolver().openInputStream(uri);
|
||||
} else if (uriString.startsWith("file://")) {
|
||||
int question = uriString.indexOf("?");
|
||||
if (question > -1) {
|
||||
uriString = uriString.substring(0, question);
|
||||
}
|
||||
if (uriString.startsWith("file:///android_asset/")) {
|
||||
Uri uri = Uri.parse(uriString);
|
||||
String relativePath = uri.getPath().substring(15);
|
||||
returnValue = cordova.getActivity().getAssets().open(relativePath);
|
||||
} else {
|
||||
// might still be content so try that first
|
||||
try {
|
||||
returnValue = cordova.getActivity().getContentResolver().openInputStream(Uri.parse(uriString));
|
||||
} catch (Exception e) {
|
||||
returnValue = null;
|
||||
}
|
||||
if (returnValue == null) {
|
||||
returnValue = new FileInputStream(getRealPath(uriString, cordova));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
returnValue = new FileInputStream(uriString);
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the "file://" prefix from the given URI string, if applicable.
|
||||
* If the given URI string doesn't have a "file://" prefix, it is returned unchanged.
|
||||
*
|
||||
* @param uriString the URI string to operate on
|
||||
* @return a path without the "file://" prefix
|
||||
*/
|
||||
public static String stripFileProtocol(String uriString) {
|
||||
if (uriString.startsWith("file://")) {
|
||||
uriString = uriString.substring(7);
|
||||
}
|
||||
return uriString;
|
||||
}
|
||||
|
||||
public static String getMimeTypeForExtension(String path) {
|
||||
String extension = path;
|
||||
int lastDot = extension.lastIndexOf('.');
|
||||
if (lastDot != -1) {
|
||||
extension = extension.substring(lastDot + 1);
|
||||
}
|
||||
// Convert the URI string to lower case to ensure compatibility with MimeTypeMap (see CB-2185).
|
||||
extension = extension.toLowerCase(Locale.getDefault());
|
||||
if (extension.equals("3ga")) {
|
||||
return "audio/3gpp";
|
||||
}
|
||||
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mime type of the data specified by the given URI string.
|
||||
*
|
||||
* @param uriString the URI string of the data
|
||||
* @return the mime type of the specified data
|
||||
*/
|
||||
public static String getMimeType(String uriString, CordovaInterface cordova) {
|
||||
String mimeType = null;
|
||||
|
||||
Uri uri = Uri.parse(uriString);
|
||||
if (uriString.startsWith("content://")) {
|
||||
mimeType = cordova.getActivity().getContentResolver().getType(uri);
|
||||
} else {
|
||||
mimeType = getMimeTypeForExtension(uri.getPath());
|
||||
}
|
||||
|
||||
return mimeType;
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,98 @@ var PictureSourceType = {
|
||||
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)
|
||||
};
|
||||
},
|
||||
savePath = window.qnx.webplatform.getApplication().getEnv("HOME").replace('/data', '') + '/shared/camera/',
|
||||
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);
|
||||
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);
|
||||
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(),
|
||||
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]),
|
||||
mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0],
|
||||
arrayBuffer = new ArrayBuffer(byteString.length),
|
||||
ia = new Uint8Array(arrayBuffer),
|
||||
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
|
||||
@@ -112,7 +203,11 @@ module.exports = {
|
||||
|
||||
switch(sourceType) {
|
||||
case PictureSourceType.CAMERA:
|
||||
window.qnx.webplatform.getApplication().cards.camera.open("photo", done, cancel, invoked);
|
||||
if (invokeAvailable) {
|
||||
window.qnx.webplatform.getApplication().cards.camera.open("photo", done, cancel, invoked);
|
||||
} else {
|
||||
showCameraDialog(done, cancel, fail);
|
||||
}
|
||||
break;
|
||||
|
||||
case PictureSourceType.PHOTOLIBRARY:
|
||||
|
||||
102
src/browser/CameraProxy.js
Normal file
102
src/browser/CameraProxy.js
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
function takePicture(success, error, opts) {
|
||||
if (opts && opts[2] === 1) {
|
||||
capture(success, error);
|
||||
} else {
|
||||
var input = document.createElement('input');
|
||||
input.type = 'file';
|
||||
input.name = 'files[]';
|
||||
|
||||
input.onchange = function(inputEvent) {
|
||||
var canvas = document.createElement('canvas');
|
||||
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(readerEvent) {
|
||||
input.parentNode.removeChild(input);
|
||||
|
||||
var imageData = readerEvent.target.result;
|
||||
|
||||
return success(imageData.substr(imageData.indexOf(',') + 1));
|
||||
}
|
||||
|
||||
reader.readAsDataURL(inputEvent.target.files[0]);
|
||||
};
|
||||
|
||||
document.body.appendChild(input);
|
||||
}
|
||||
}
|
||||
|
||||
function capture(success, errorCallback) {
|
||||
var localMediaStream;
|
||||
|
||||
var video = document.createElement('video');
|
||||
var button = document.createElement('button');
|
||||
|
||||
video.width = 320;
|
||||
video.height = 240;
|
||||
button.innerHTML = 'Capture!';
|
||||
|
||||
button.onclick = function() {
|
||||
// create a canvas and capture a frame from video stream
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.getContext('2d').drawImage(video, 0, 0, 320, 240);
|
||||
|
||||
// convert image stored in canvas to base64 encoded image
|
||||
var imageData = canvas.toDataURL('img/png');
|
||||
imageData = imageData.replace('data:image/png;base64,', '');
|
||||
|
||||
// stop video stream, remove video and button
|
||||
localMediaStream.stop();
|
||||
video.parentNode.removeChild(video);
|
||||
button.parentNode.removeChild(button);
|
||||
|
||||
return success(imageData);
|
||||
}
|
||||
|
||||
navigator.getUserMedia = navigator.getUserMedia ||
|
||||
navigator.webkitGetUserMedia ||
|
||||
navigator.mozGetUserMedia ||
|
||||
navigator.msGetUserMedia;
|
||||
|
||||
var successCallback = function(stream) {
|
||||
localMediaStream = stream;
|
||||
video.src = window.URL.createObjectURL(localMediaStream);
|
||||
video.play();
|
||||
|
||||
document.body.appendChild(video);
|
||||
document.body.appendChild(button);
|
||||
}
|
||||
|
||||
if (navigator.getUserMedia) {
|
||||
navigator.getUserMedia({video: true, audio: true}, successCallback, errorCallback);
|
||||
} else {
|
||||
alert('Browser does not support camera :(');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
takePicture: takePicture,
|
||||
cleanup: function(){}
|
||||
};
|
||||
|
||||
require("cordova/exec/proxy").add("Camera",module.exports);
|
||||
51
src/firefoxos/CameraProxy.js
Normal file
51
src/firefoxos/CameraProxy.js
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
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);
|
||||
@@ -42,21 +42,39 @@ enum CDVMediaType {
|
||||
};
|
||||
typedef NSUInteger CDVMediaType;
|
||||
|
||||
@interface CDVCameraPicker : UIImagePickerController
|
||||
{}
|
||||
@interface CDVPictureOptions : NSObject
|
||||
|
||||
@property (strong) NSNumber* quality;
|
||||
@property (assign) CDVDestinationType destinationType;
|
||||
@property (assign) UIImagePickerControllerSourceType sourceType;
|
||||
@property (assign) CGSize targetSize;
|
||||
@property (assign) CDVEncodingType encodingType;
|
||||
@property (assign) CDVMediaType mediaType;
|
||||
@property (assign) BOOL allowsEditing;
|
||||
@property (assign) BOOL correctOrientation;
|
||||
@property (assign) BOOL saveToPhotoAlbum;
|
||||
@property (strong) NSDictionary* popoverOptions;
|
||||
@property (assign) UIImagePickerControllerCameraDevice cameraDirection;
|
||||
|
||||
@property (assign) BOOL popoverSupported;
|
||||
@property (assign) BOOL usesGeolocation;
|
||||
@property (assign) BOOL cropToSize;
|
||||
|
||||
+ (instancetype) createFromTakePictureArguments:(CDVInvokedUrlCommand*)command;
|
||||
|
||||
@end
|
||||
|
||||
@interface CDVCameraPicker : UIImagePickerController
|
||||
|
||||
@property (strong) CDVPictureOptions* pictureOptions;
|
||||
|
||||
@property (assign) NSInteger quality;
|
||||
@property (copy) NSString* callbackId;
|
||||
@property (copy) NSString* postUrl;
|
||||
@property (nonatomic) enum CDVDestinationType returnType;
|
||||
@property (nonatomic) enum CDVEncodingType encodingType;
|
||||
@property (strong) UIPopoverController* popoverController;
|
||||
@property (assign) CGSize targetSize;
|
||||
@property (assign) bool correctOrientation;
|
||||
@property (assign) bool saveToPhotoAlbum;
|
||||
@property (assign) bool cropToSize;
|
||||
@property (strong) UIWebView* webView;
|
||||
@property (assign) BOOL popoverSupported;
|
||||
@property (strong) UIPopoverController* pickerPopoverController;
|
||||
@property (assign) BOOL cropToSize;
|
||||
@property (strong) UIView* webView;
|
||||
|
||||
+ (instancetype) createFromPictureOptions:(CDVPictureOptions*)options;
|
||||
|
||||
@end
|
||||
|
||||
@@ -84,7 +102,6 @@ typedef NSUInteger CDVMediaType;
|
||||
* quality: integer between 1 and 100
|
||||
*/
|
||||
- (void)takePicture:(CDVInvokedUrlCommand*)command;
|
||||
- (void)postImage:(UIImage*)anImage withFilename:(NSString*)filename toUrl:(NSURL*)url;
|
||||
- (void)cleanup:(CDVInvokedUrlCommand*)command;
|
||||
- (void)repositionPopover:(CDVInvokedUrlCommand*)command;
|
||||
|
||||
@@ -92,9 +109,6 @@ typedef NSUInteger CDVMediaType;
|
||||
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingImage:(UIImage*)image editingInfo:(NSDictionary*)editingInfo;
|
||||
- (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker;
|
||||
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
|
||||
- (UIImage*)imageByScalingAndCroppingForSize:(UIImage*)anImage toSize:(CGSize)targetSize;
|
||||
- (UIImage*)imageByScalingNotCroppingForSize:(UIImage*)anImage toSize:(CGSize)frameSize;
|
||||
- (UIImage*)imageCorrectedForCaptureOrientation:(UIImage*)anImage;
|
||||
|
||||
- (void)locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation*)oldLocation;
|
||||
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -190,7 +190,7 @@ const uint mTiffLength = 0x2a; // after byte align bits, next to bits are 0x002a
|
||||
// construct the complete app1 data block
|
||||
app1 = [[NSMutableString alloc] initWithFormat: @"%@%04x%@%@%@%@%@",
|
||||
app1marker,
|
||||
16 + ([exifIFD length]/2) + ([subExifIFD length]/2) /*16+[exifIFD length]/2*/,
|
||||
(unsigned int)(16 + ([exifIFD length]/2) + ([subExifIFD length]/2)) /*16+[exifIFD length]/2*/,
|
||||
exifmarker,
|
||||
tiffheader,
|
||||
ifd0offset,
|
||||
@@ -268,10 +268,10 @@ const uint mTiffLength = 0x2a; // after byte align bits, next to bits are 0x002a
|
||||
}
|
||||
|
||||
// calculate IFD0 terminal offset tags, currently ExifSubIFD
|
||||
int entrycount = [ifdblock count];
|
||||
unsigned int entrycount = (unsigned int)[ifdblock count];
|
||||
if (ifd0flag) {
|
||||
// 18 accounts for 8769's width + offset to next ifd, 8 accounts for start of header
|
||||
NSNumber * offset = [NSNumber numberWithInt:[exifstr length] / 2 + [dbstr length] / 2 + 18+8];
|
||||
NSNumber * offset = [NSNumber numberWithUnsignedInteger:[exifstr length] / 2 + [dbstr length] / 2 + 18+8];
|
||||
|
||||
[self appendExifOffsetTagTo: exifstr
|
||||
withOffset : offset];
|
||||
@@ -293,7 +293,7 @@ const uint mTiffLength = 0x2a; // after byte align bits, next to bits are 0x002a
|
||||
NSNumber * dataformat = [formtemplate objectAtIndex:1];
|
||||
NSNumber * components = [formtemplate objectAtIndex:2];
|
||||
if([components intValue] == 0) {
|
||||
components = [NSNumber numberWithInt: [data length] * DataTypeToWidth[[dataformat intValue]-1]];
|
||||
components = [NSNumber numberWithUnsignedInteger:[data length] * DataTypeToWidth[[dataformat intValue]-1]];
|
||||
}
|
||||
|
||||
return [[NSString alloc] initWithFormat: @"%@%@%08x",
|
||||
@@ -344,7 +344,7 @@ const uint mTiffLength = 0x2a; // after byte align bits, next to bits are 0x002a
|
||||
[datastr appendString:[dataformat objectAtIndex:3]];
|
||||
}
|
||||
if ([datastr length] < 8) {
|
||||
NSString * format = [NSString stringWithFormat:@"%%0%dd", 8 - [datastr length]];
|
||||
NSString * format = [NSString stringWithFormat:@"%%0%dd", (int)(8 - [datastr length])];
|
||||
[datastr appendFormat:format,0];
|
||||
}
|
||||
return datastr;
|
||||
@@ -464,7 +464,7 @@ const uint mTiffLength = 0x2a; // after byte align bits, next to bits are 0x002a
|
||||
-(void) expandContinuedFraction: (NSArray*) fractionlist
|
||||
withResultNumerator: (NSNumber**) numerator
|
||||
withResultDenominator: (NSNumber**) denominator {
|
||||
int i = 0;
|
||||
NSUInteger i = 0;
|
||||
int den = 0;
|
||||
int num = 0;
|
||||
if ([fractionlist count] == 1) {
|
||||
|
||||
29
src/ios/UIImage+CropScaleOrientation.h
Normal file
29
src/ios/UIImage+CropScaleOrientation.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
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 <UIKit/UIKit.h>
|
||||
|
||||
@interface UIImage (CropScaleOrientation)
|
||||
|
||||
- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize;
|
||||
- (UIImage*)imageCorrectedForCaptureOrientation;
|
||||
- (UIImage*)imageCorrectedForCaptureOrientation:(UIImageOrientation)imageOrientation;
|
||||
- (UIImage*)imageByScalingNotCroppingForSize:(CGSize)targetSize;
|
||||
|
||||
@end
|
||||
175
src/ios/UIImage+CropScaleOrientation.m
Normal file
175
src/ios/UIImage+CropScaleOrientation.m
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
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 "UIImage+CropScaleOrientation.h"
|
||||
|
||||
@implementation UIImage (CropScaleOrientation)
|
||||
|
||||
- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize
|
||||
{
|
||||
UIImage* sourceImage = self;
|
||||
UIImage* newImage = nil;
|
||||
CGSize imageSize = sourceImage.size;
|
||||
CGFloat width = imageSize.width;
|
||||
CGFloat height = imageSize.height;
|
||||
CGFloat targetWidth = targetSize.width;
|
||||
CGFloat targetHeight = targetSize.height;
|
||||
CGFloat scaleFactor = 0.0;
|
||||
CGFloat scaledWidth = targetWidth;
|
||||
CGFloat scaledHeight = targetHeight;
|
||||
CGPoint thumbnailPoint = CGPointMake(0.0, 0.0);
|
||||
|
||||
if (CGSizeEqualToSize(imageSize, targetSize) == NO) {
|
||||
CGFloat widthFactor = targetWidth / width;
|
||||
CGFloat heightFactor = targetHeight / height;
|
||||
|
||||
if (widthFactor > heightFactor) {
|
||||
scaleFactor = widthFactor; // scale to fit height
|
||||
} else {
|
||||
scaleFactor = heightFactor; // scale to fit width
|
||||
}
|
||||
scaledWidth = width * scaleFactor;
|
||||
scaledHeight = height * scaleFactor;
|
||||
|
||||
// center the image
|
||||
if (widthFactor > heightFactor) {
|
||||
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
|
||||
} else if (widthFactor < heightFactor) {
|
||||
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
UIGraphicsBeginImageContext(targetSize); // this will crop
|
||||
|
||||
CGRect thumbnailRect = CGRectZero;
|
||||
thumbnailRect.origin = thumbnailPoint;
|
||||
thumbnailRect.size.width = scaledWidth;
|
||||
thumbnailRect.size.height = scaledHeight;
|
||||
|
||||
[sourceImage drawInRect:thumbnailRect];
|
||||
|
||||
newImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
if (newImage == nil) {
|
||||
NSLog(@"could not scale image");
|
||||
}
|
||||
|
||||
// pop the context to get back to the default
|
||||
UIGraphicsEndImageContext();
|
||||
return newImage;
|
||||
}
|
||||
|
||||
- (UIImage*)imageCorrectedForCaptureOrientation:(UIImageOrientation)imageOrientation
|
||||
{
|
||||
float rotation_radians = 0;
|
||||
bool perpendicular = false;
|
||||
|
||||
switch (imageOrientation) {
|
||||
case UIImageOrientationUp :
|
||||
rotation_radians = 0.0;
|
||||
break;
|
||||
|
||||
case UIImageOrientationDown:
|
||||
rotation_radians = M_PI; // don't be scared of radians, if you're reading this, you're good at math
|
||||
break;
|
||||
|
||||
case UIImageOrientationRight:
|
||||
rotation_radians = M_PI_2;
|
||||
perpendicular = true;
|
||||
break;
|
||||
|
||||
case UIImageOrientationLeft:
|
||||
rotation_radians = -M_PI_2;
|
||||
perpendicular = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UIGraphicsBeginImageContext(CGSizeMake(self.size.width, self.size.height));
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
// Rotate around the center point
|
||||
CGContextTranslateCTM(context, self.size.width / 2, self.size.height / 2);
|
||||
CGContextRotateCTM(context, rotation_radians);
|
||||
|
||||
CGContextScaleCTM(context, 1.0, -1.0);
|
||||
float width = perpendicular ? self.size.height : self.size.width;
|
||||
float height = perpendicular ? self.size.width : self.size.height;
|
||||
CGContextDrawImage(context, CGRectMake(-width / 2, -height / 2, width, height), [self CGImage]);
|
||||
|
||||
// Move the origin back since the rotation might've change it (if its 90 degrees)
|
||||
if (perpendicular) {
|
||||
CGContextTranslateCTM(context, -self.size.height / 2, -self.size.width / 2);
|
||||
}
|
||||
|
||||
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
return newImage;
|
||||
}
|
||||
|
||||
- (UIImage*)imageCorrectedForCaptureOrientation
|
||||
{
|
||||
return [self imageCorrectedForCaptureOrientation:[self imageOrientation]];
|
||||
}
|
||||
|
||||
- (UIImage*)imageByScalingNotCroppingForSize:(CGSize)targetSize
|
||||
{
|
||||
UIImage* sourceImage = self;
|
||||
UIImage* newImage = nil;
|
||||
CGSize imageSize = sourceImage.size;
|
||||
CGFloat width = imageSize.width;
|
||||
CGFloat height = imageSize.height;
|
||||
CGFloat targetWidth = targetSize.width;
|
||||
CGFloat targetHeight = targetSize.height;
|
||||
CGFloat scaleFactor = 0.0;
|
||||
CGSize scaledSize = targetSize;
|
||||
|
||||
if (CGSizeEqualToSize(imageSize, targetSize) == NO) {
|
||||
CGFloat widthFactor = targetWidth / width;
|
||||
CGFloat heightFactor = targetHeight / height;
|
||||
|
||||
// opposite comparison to imageByScalingAndCroppingForSize in order to contain the image within the given bounds
|
||||
if (widthFactor > heightFactor) {
|
||||
scaleFactor = heightFactor; // scale to fit height
|
||||
} else {
|
||||
scaleFactor = widthFactor; // scale to fit width
|
||||
}
|
||||
scaledSize = CGSizeMake(MIN(width * scaleFactor, targetWidth), MIN(height * scaleFactor, targetHeight));
|
||||
}
|
||||
|
||||
// If the pixels are floats, it causes a white line in iOS8 and probably other versions too
|
||||
scaledSize.width = (int)scaledSize.width;
|
||||
scaledSize.height = (int)scaledSize.height;
|
||||
|
||||
UIGraphicsBeginImageContext(scaledSize); // this will resize
|
||||
|
||||
[sourceImage drawInRect:CGRectMake(0, 0, scaledSize.width, scaledSize.height)];
|
||||
|
||||
newImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
if (newImage == nil) {
|
||||
NSLog(@"could not scale image");
|
||||
}
|
||||
|
||||
// pop the context to get back to the default
|
||||
UIGraphicsEndImageContext();
|
||||
return newImage;
|
||||
}
|
||||
|
||||
@end
|
||||
118
src/ubuntu/CaptureWidget.qml
Normal file
118
src/ubuntu/CaptureWidget.qml
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
*
|
||||
* 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
src/ubuntu/back.png
Normal file
BIN
src/ubuntu/back.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
140
src/ubuntu/camera.cpp
Normal file
140
src/ubuntu/camera.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
86
src/ubuntu/camera.h
Normal file
86
src/ubuntu/camera.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
*
|
||||
* 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
|
||||
BIN
src/ubuntu/shoot.png
Normal file
BIN
src/ubuntu/shoot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
src/ubuntu/toolbar-left.png
Normal file
BIN
src/ubuntu/toolbar-left.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/ubuntu/toolbar-middle.png
Normal file
BIN
src/ubuntu/toolbar-middle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
BIN
src/ubuntu/toolbar-right.png
Normal file
BIN
src/ubuntu/toolbar-right.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
585
src/windows/CameraProxy.js
Normal file
585
src/windows/CameraProxy.js
Normal file
@@ -0,0 +1,585 @@
|
||||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*jshint unused:true, undef:true, browser:true */
|
||||
/*global Windows:true, URL:true, module:true, require:true */
|
||||
|
||||
|
||||
var Camera = require('./Camera');
|
||||
|
||||
module.exports = {
|
||||
|
||||
// args will contain :
|
||||
// ... it is an array, so be careful
|
||||
// 0 quality:50,
|
||||
// 1 destinationType:Camera.DestinationType.FILE_URI,
|
||||
// 2 sourceType:Camera.PictureSourceType.CAMERA,
|
||||
// 3 targetWidth:-1,
|
||||
// 4 targetHeight:-1,
|
||||
// 5 encodingType:Camera.EncodingType.JPEG,
|
||||
// 6 mediaType:Camera.MediaType.PICTURE,
|
||||
// 7 allowEdit:false,
|
||||
// 8 correctOrientation:false,
|
||||
// 9 saveToPhotoAlbum:false,
|
||||
// 10 popoverOptions:null
|
||||
// 11 cameraDirection:0
|
||||
|
||||
takePicture: function (successCallback, errorCallback, args) {
|
||||
var sourceType = args[2];
|
||||
|
||||
if (sourceType != Camera.PictureSourceType.CAMERA) {
|
||||
takePictureFromFile(successCallback, errorCallback, args);
|
||||
} else {
|
||||
takePictureFromCamera(successCallback, errorCallback, args);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/windows/apps/ff462087(v=vs.105).aspx
|
||||
var windowsVideoContainers = [".avi", ".flv", ".asx", ".asf", ".mov", ".mp4", ".mpg", ".rm", ".srt", ".swf", ".wmv", ".vob"];
|
||||
var windowsPhoneVideoContainers = [".avi", ".3gp", ".3g2", ".wmv", ".3gp", ".3g2", ".mp4", ".m4v"];
|
||||
|
||||
// Resize method
|
||||
function resizeImage(successCallback, errorCallback, file, targetWidth, targetHeight, encodingType) {
|
||||
var tempPhotoFileName = "";
|
||||
if (encodingType == Camera.EncodingType.PNG) {
|
||||
tempPhotoFileName = "camera_cordova_temp_return.png";
|
||||
} else {
|
||||
tempPhotoFileName = "camera_cordova_temp_return.jpg";
|
||||
}
|
||||
|
||||
var storageFolder = Windows.Storage.ApplicationData.current.localFolder;
|
||||
file.copyAsync(storageFolder, file.name, Windows.Storage.NameCollisionOption.replaceExisting)
|
||||
.then(function (storageFile) { return Windows.Storage.FileIO.readBufferAsync(storageFile); })
|
||||
.then(function(buffer) {
|
||||
var strBase64 = Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(buffer);
|
||||
var imageData = "data:" + file.contentType + ";base64," + strBase64;
|
||||
var image = new Image();
|
||||
image.src = imageData;
|
||||
image.onload = function() {
|
||||
var imageWidth = targetWidth,
|
||||
imageHeight = targetHeight;
|
||||
var canvas = document.createElement('canvas');
|
||||
var storageFileName;
|
||||
|
||||
canvas.width = imageWidth;
|
||||
canvas.height = imageHeight;
|
||||
|
||||
canvas.getContext("2d").drawImage(this, 0, 0, imageWidth, imageHeight);
|
||||
|
||||
var fileContent = canvas.toDataURL(file.contentType).split(',')[1];
|
||||
|
||||
var storageFolder = Windows.Storage.ApplicationData.current.localFolder;
|
||||
|
||||
storageFolder.createFileAsync(tempPhotoFileName, Windows.Storage.CreationCollisionOption.generateUniqueName)
|
||||
.then(function (storagefile) {
|
||||
var content = Windows.Security.Cryptography.CryptographicBuffer.decodeFromBase64String(fileContent);
|
||||
storageFileName = storagefile.name;
|
||||
return Windows.Storage.FileIO.writeBufferAsync(storagefile, content);
|
||||
})
|
||||
.done(function () {
|
||||
successCallback("ms-appdata:///local/" + storageFileName);
|
||||
}, errorCallback);
|
||||
};
|
||||
})
|
||||
.done(null, function(err) {
|
||||
errorCallback(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Because of asynchronous method, so let the successCallback be called in it.
|
||||
function resizeImageBase64(successCallback, errorCallback, file, targetWidth, targetHeight) {
|
||||
Windows.Storage.FileIO.readBufferAsync(file).done( function(buffer) {
|
||||
var strBase64 = Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(buffer);
|
||||
var imageData = "data:" + file.contentType + ";base64," + strBase64;
|
||||
|
||||
var image = new Image();
|
||||
image.src = imageData;
|
||||
|
||||
image.onload = function() {
|
||||
var imageWidth = targetWidth,
|
||||
imageHeight = targetHeight;
|
||||
var canvas = document.createElement('canvas');
|
||||
|
||||
canvas.width = imageWidth;
|
||||
canvas.height = imageHeight;
|
||||
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(this, 0, 0, imageWidth, imageHeight);
|
||||
|
||||
// The resized file ready for upload
|
||||
var finalFile = canvas.toDataURL(file.contentType);
|
||||
|
||||
// Remove the prefix such as "data:" + contentType + ";base64," , in order to meet the Cordova API.
|
||||
var arr = finalFile.split(",");
|
||||
var newStr = finalFile.substr(arr[0].length + 1);
|
||||
successCallback(newStr);
|
||||
};
|
||||
}, function(err) { errorCallback(err); });
|
||||
}
|
||||
|
||||
function takePictureFromFile(successCallback, errorCallback, args) {
|
||||
// Detect Windows Phone
|
||||
if (navigator.appVersion.indexOf('Windows Phone 8.1') >= 0) {
|
||||
takePictureFromFileWP(successCallback, errorCallback, args);
|
||||
} else {
|
||||
takePictureFromFileWindows(successCallback, errorCallback, args);
|
||||
}
|
||||
}
|
||||
|
||||
function takePictureFromFileWP(successCallback, errorCallback, args) {
|
||||
var mediaType = args[6],
|
||||
destinationType = args[1],
|
||||
targetWidth = args[3],
|
||||
targetHeight = args[4],
|
||||
encodingType = args[5];
|
||||
|
||||
/*
|
||||
Need to add and remove an event listener to catch activation state
|
||||
Using FileOpenPicker will suspend the app and it's required to catch the PickSingleFileAndContinue
|
||||
https://msdn.microsoft.com/en-us/library/windows/apps/xaml/dn631755.aspx
|
||||
*/
|
||||
var filePickerActivationHandler = function(eventArgs) {
|
||||
if (eventArgs.kind === Windows.ApplicationModel.Activation.ActivationKind.pickFileContinuation) {
|
||||
var file = eventArgs.files[0];
|
||||
if (!file) {
|
||||
errorCallback("User didn't choose a file.");
|
||||
Windows.UI.WebUI.WebUIApplication.removeEventListener("activated", filePickerActivationHandler);
|
||||
return;
|
||||
}
|
||||
if (destinationType == Camera.DestinationType.FILE_URI || destinationType == Camera.DestinationType.NATIVE_URI) {
|
||||
if (targetHeight > 0 && targetWidth > 0) {
|
||||
resizeImage(successCallback, errorCallback, file, targetWidth, targetHeight, encodingType);
|
||||
}
|
||||
else {
|
||||
var storageFolder = Windows.Storage.ApplicationData.current.localFolder;
|
||||
file.copyAsync(storageFolder, file.name, Windows.Storage.NameCollisionOption.replaceExisting).done(function (storageFile) {
|
||||
successCallback(URL.createObjectURL(storageFile));
|
||||
}, function () {
|
||||
errorCallback("Can't access localStorage folder.");
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (targetHeight > 0 && targetWidth > 0) {
|
||||
resizeImageBase64(successCallback, errorCallback, file, targetWidth, targetHeight);
|
||||
} else {
|
||||
Windows.Storage.FileIO.readBufferAsync(file).done(function (buffer) {
|
||||
var strBase64 = Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(buffer);
|
||||
successCallback(strBase64);
|
||||
}, errorCallback);
|
||||
}
|
||||
}
|
||||
Windows.UI.WebUI.WebUIApplication.removeEventListener("activated", filePickerActivationHandler);
|
||||
}
|
||||
};
|
||||
|
||||
var fileOpenPicker = new Windows.Storage.Pickers.FileOpenPicker();
|
||||
if (mediaType == Camera.MediaType.PICTURE) {
|
||||
fileOpenPicker.fileTypeFilter.replaceAll([".png", ".jpg", ".jpeg"]);
|
||||
fileOpenPicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.picturesLibrary;
|
||||
}
|
||||
else if (mediaType == Camera.MediaType.VIDEO) {
|
||||
fileOpenPicker.fileTypeFilter.replaceAll(windowsPhoneVideoContainers);
|
||||
fileOpenPicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.videosLibrary;
|
||||
}
|
||||
else {
|
||||
fileOpenPicker.fileTypeFilter.replaceAll(["*"]);
|
||||
fileOpenPicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.documentsLibrary;
|
||||
}
|
||||
|
||||
Windows.UI.WebUI.WebUIApplication.addEventListener("activated", filePickerActivationHandler);
|
||||
fileOpenPicker.pickSingleFileAndContinue();
|
||||
}
|
||||
|
||||
function takePictureFromFileWindows(successCallback, errorCallback, args) {
|
||||
var mediaType = args[6],
|
||||
destinationType = args[1],
|
||||
targetWidth = args[3],
|
||||
targetHeight = args[4],
|
||||
encodingType = args[5];
|
||||
|
||||
var fileOpenPicker = new Windows.Storage.Pickers.FileOpenPicker();
|
||||
if (mediaType == Camera.MediaType.PICTURE) {
|
||||
fileOpenPicker.fileTypeFilter.replaceAll([".png", ".jpg", ".jpeg"]);
|
||||
fileOpenPicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.picturesLibrary;
|
||||
}
|
||||
else if (mediaType == Camera.MediaType.VIDEO) {
|
||||
fileOpenPicker.fileTypeFilter.replaceAll(windowsVideoContainers);
|
||||
fileOpenPicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.videosLibrary;
|
||||
}
|
||||
else {
|
||||
fileOpenPicker.fileTypeFilter.replaceAll(["*"]);
|
||||
fileOpenPicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.documentsLibrary;
|
||||
}
|
||||
|
||||
fileOpenPicker.pickSingleFileAsync().done(function (file) {
|
||||
if (!file) {
|
||||
errorCallback("User didn't choose a file.");
|
||||
return;
|
||||
}
|
||||
if (destinationType == Camera.DestinationType.FILE_URI || destinationType == Camera.DestinationType.NATIVE_URI) {
|
||||
if (targetHeight > 0 && targetWidth > 0) {
|
||||
resizeImage(successCallback, errorCallback, file, targetWidth, targetHeight, encodingType);
|
||||
}
|
||||
else {
|
||||
var storageFolder = Windows.Storage.ApplicationData.current.localFolder;
|
||||
file.copyAsync(storageFolder, file.name, Windows.Storage.NameCollisionOption.replaceExisting).done(function (storageFile) {
|
||||
successCallback(URL.createObjectURL(storageFile));
|
||||
}, function () {
|
||||
errorCallback("Can't access localStorage folder.");
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (targetHeight > 0 && targetWidth > 0) {
|
||||
resizeImageBase64(successCallback, errorCallback, file, targetWidth, targetHeight);
|
||||
} else {
|
||||
Windows.Storage.FileIO.readBufferAsync(file).done(function (buffer) {
|
||||
var strBase64 = Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(buffer);
|
||||
successCallback(strBase64);
|
||||
}, errorCallback);
|
||||
}
|
||||
}
|
||||
}, function () {
|
||||
errorCallback("User didn't choose a file.");
|
||||
});
|
||||
}
|
||||
|
||||
function takePictureFromCamera(successCallback, errorCallback, args) {
|
||||
// Check if necessary API available
|
||||
if (!Windows.Media.Capture.CameraCaptureUI) {
|
||||
takePictureFromCameraWP(successCallback, errorCallback, args);
|
||||
} else {
|
||||
takePictureFromCameraWindows(successCallback, errorCallback, args);
|
||||
}
|
||||
}
|
||||
|
||||
function takePictureFromCameraWP(successCallback, errorCallback, args) {
|
||||
// We are running on WP8.1 which lacks CameraCaptureUI class
|
||||
// so we need to use MediaCapture class instead and implement custom UI for camera
|
||||
var destinationType = args[1],
|
||||
targetWidth = args[3],
|
||||
targetHeight = args[4],
|
||||
encodingType = args[5],
|
||||
saveToPhotoAlbum = args[9],
|
||||
cameraDirection = args[11],
|
||||
capturePreview = null,
|
||||
captureCancelButton = null,
|
||||
capture = null,
|
||||
captureSettings = null,
|
||||
CaptureNS = Windows.Media.Capture;
|
||||
|
||||
function cameraPreviewOrientation() {
|
||||
// Rotate the cam since WP8.1 MediaCapture outputs video stream rotated 90° CCW
|
||||
if (screen.msOrientation === "portrait-primary" || screen.msOrientation === "portrait-secondary") {
|
||||
capture.setPreviewRotation(Windows.Media.Capture.VideoRotation.clockwise90Degrees);
|
||||
} else if (screen.msOrientation === "landscape-secondary") {
|
||||
capture.setPreviewRotation(Windows.Media.Capture.VideoRotation.clockwise180Degrees);
|
||||
} else {
|
||||
capture.setPreviewRotation(Windows.Media.Capture.VideoRotation.none);
|
||||
}
|
||||
}
|
||||
|
||||
var createCameraUI = function () {
|
||||
// Create fullscreen preview
|
||||
capturePreview = document.createElement("video");
|
||||
|
||||
// z-order style element for capturePreview and captureCancelButton elts
|
||||
// is necessary to avoid overriding by another page elements, -1 sometimes is not enough
|
||||
capturePreview.style.cssText = "position: fixed; left: 0; top: 0; width: 100%; height: 100%; z-index: 999";
|
||||
|
||||
// Create cancel button
|
||||
captureCancelButton = document.createElement("button");
|
||||
captureCancelButton.innerText = "Cancel";
|
||||
captureCancelButton.style.cssText = "position: fixed; right: 0; bottom: 0; display: block; margin: 20px; z-index: 1000";
|
||||
|
||||
capture = new CaptureNS.MediaCapture();
|
||||
|
||||
captureSettings = new CaptureNS.MediaCaptureInitializationSettings();
|
||||
captureSettings.streamingCaptureMode = CaptureNS.StreamingCaptureMode.video;
|
||||
};
|
||||
|
||||
var startCameraPreview = function () {
|
||||
// Search for available camera devices
|
||||
// This is necessary to detect which camera (front or back) we should use
|
||||
var expectedPanel = cameraDirection === 1 ? Windows.Devices.Enumeration.Panel.front : Windows.Devices.Enumeration.Panel.back;
|
||||
Windows.Devices.Enumeration.DeviceInformation.findAllAsync(Windows.Devices.Enumeration.DeviceClass.videoCapture)
|
||||
.done(function (devices) {
|
||||
if (devices.length <= 0) {
|
||||
destroyCameraPreview();
|
||||
errorCallback('Camera not found');
|
||||
return;
|
||||
}
|
||||
|
||||
devices.forEach(function(currDev) {
|
||||
if (currDev.enclosureLocation.panel && currDev.enclosureLocation.panel == expectedPanel) {
|
||||
captureSettings.videoDeviceId = currDev.id;
|
||||
}
|
||||
});
|
||||
|
||||
capture.initializeAsync(captureSettings).done(function () {
|
||||
// msdn.microsoft.com/en-us/library/windows/apps/hh452807.aspx
|
||||
capturePreview.msZoom = true;
|
||||
capturePreview.src = URL.createObjectURL(capture);
|
||||
capturePreview.play();
|
||||
|
||||
// Insert preview frame and controls into page
|
||||
document.body.appendChild(capturePreview);
|
||||
document.body.appendChild(captureCancelButton);
|
||||
|
||||
// Bind events to controls
|
||||
window.addEventListener('deviceorientation', cameraPreviewOrientation, false);
|
||||
capturePreview.addEventListener('click', captureAction);
|
||||
captureCancelButton.addEventListener('click', function () {
|
||||
destroyCameraPreview();
|
||||
errorCallback('Cancelled');
|
||||
}, false);
|
||||
}, function (err) {
|
||||
destroyCameraPreview();
|
||||
errorCallback('Camera intitialization error ' + err);
|
||||
});
|
||||
}, errorCallback);
|
||||
};
|
||||
|
||||
var destroyCameraPreview = function () {
|
||||
window.removeEventListener('deviceorientation', cameraPreviewOrientation, false);
|
||||
capturePreview.pause();
|
||||
capturePreview.src = null;
|
||||
[capturePreview, captureCancelButton].forEach(function(elem) {
|
||||
if (elem /* && elem in document.body.childNodes */) {
|
||||
document.body.removeChild(elem);
|
||||
}
|
||||
});
|
||||
if (capture) {
|
||||
capture.stopRecordAsync();
|
||||
capture = null;
|
||||
}
|
||||
};
|
||||
|
||||
var captureAction = function () {
|
||||
|
||||
var encodingProperties,
|
||||
fileName,
|
||||
generateUniqueCollisionOption = Windows.Storage.CreationCollisionOption.generateUniqueName,
|
||||
tempFolder = Windows.Storage.ApplicationData.current.temporaryFolder;
|
||||
|
||||
if (encodingType == Camera.EncodingType.PNG) {
|
||||
fileName = 'photo.png';
|
||||
encodingProperties = Windows.Media.MediaProperties.ImageEncodingProperties.createPng();
|
||||
} else {
|
||||
fileName = 'photo.jpg';
|
||||
encodingProperties = Windows.Media.MediaProperties.ImageEncodingProperties.createJpeg();
|
||||
}
|
||||
|
||||
tempFolder.createFileAsync(fileName, generateUniqueCollisionOption)
|
||||
.then(function(tempCapturedFile) {
|
||||
return new WinJS.Promise(function (complete) {
|
||||
var imgStream = new Windows.Storage.Streams.InMemoryRandomAccessStream();
|
||||
capture.capturePhotoToStreamAsync(encodingProperties, imgStream)
|
||||
.then(function() {
|
||||
return Windows.Graphics.Imaging.BitmapDecoder.createAsync(imgStream);
|
||||
})
|
||||
.then(function(dec) {
|
||||
return Windows.Graphics.Imaging.BitmapEncoder.createForTranscodingAsync(imgStream, dec);
|
||||
})
|
||||
.then(function(enc) {
|
||||
// We need to rotate the photo 90° CW because by default wp8.1 takes 90° CCW rotated photos.
|
||||
enc.bitmapTransform.rotation = Windows.Graphics.Imaging.BitmapRotation.clockwise90Degrees;
|
||||
return enc.flushAsync();
|
||||
})
|
||||
.then(function() {
|
||||
return tempCapturedFile.openAsync(Windows.Storage.FileAccessMode.readWrite);
|
||||
})
|
||||
.then(function(fileStream) {
|
||||
imgStream.seek(0); // required for win8.1 emulator
|
||||
return Windows.Storage.Streams.RandomAccessStream.copyAsync(imgStream, fileStream);
|
||||
})
|
||||
.done(function() {
|
||||
imgStream.close();
|
||||
complete(tempCapturedFile);
|
||||
}, function() {
|
||||
imgStream.close();
|
||||
throw new Error("An error has occured while capturing the photo.");
|
||||
});
|
||||
});
|
||||
})
|
||||
.done(function(capturedFile) {
|
||||
destroyCameraPreview();
|
||||
savePhoto(capturedFile, {
|
||||
destinationType: destinationType,
|
||||
targetHeight: targetHeight,
|
||||
targetWidth: targetWidth,
|
||||
encodingType: encodingType,
|
||||
saveToPhotoAlbum: saveToPhotoAlbum
|
||||
}, successCallback, errorCallback);
|
||||
}, function(err) {
|
||||
destroyCameraPreview();
|
||||
errorCallback(err);
|
||||
});
|
||||
};
|
||||
|
||||
try {
|
||||
createCameraUI();
|
||||
startCameraPreview();
|
||||
} catch (ex) {
|
||||
errorCallback(ex);
|
||||
}
|
||||
}
|
||||
|
||||
function takePictureFromCameraWindows(successCallback, errorCallback, args) {
|
||||
var destinationType = args[1],
|
||||
targetWidth = args[3],
|
||||
targetHeight = args[4],
|
||||
encodingType = args[5],
|
||||
allowCrop = !!args[7],
|
||||
saveToPhotoAlbum = args[9],
|
||||
cameraCaptureUI = new Windows.Media.Capture.CameraCaptureUI();
|
||||
cameraCaptureUI.photoSettings.allowCropping = allowCrop;
|
||||
|
||||
if (encodingType == Camera.EncodingType.PNG) {
|
||||
cameraCaptureUI.photoSettings.format = Windows.Media.Capture.CameraCaptureUIPhotoFormat.png;
|
||||
} else {
|
||||
cameraCaptureUI.photoSettings.format = Windows.Media.Capture.CameraCaptureUIPhotoFormat.jpeg;
|
||||
}
|
||||
|
||||
// decide which max pixels should be supported by targetWidth or targetHeight.
|
||||
if (targetWidth >= 1280 || targetHeight >= 960) {
|
||||
cameraCaptureUI.photoSettings.maxResolution = Windows.Media.Capture.CameraCaptureUIMaxPhotoResolution.large3M;
|
||||
} else if (targetWidth >= 1024 || targetHeight >= 768) {
|
||||
cameraCaptureUI.photoSettings.maxResolution = Windows.Media.Capture.CameraCaptureUIMaxPhotoResolution.mediumXga;
|
||||
} else if (targetWidth >= 800 || targetHeight >= 600) {
|
||||
cameraCaptureUI.photoSettings.maxResolution = Windows.Media.Capture.CameraCaptureUIMaxPhotoResolution.mediumXga;
|
||||
} else if (targetWidth >= 640 || targetHeight >= 480) {
|
||||
cameraCaptureUI.photoSettings.maxResolution = Windows.Media.Capture.CameraCaptureUIMaxPhotoResolution.smallVga;
|
||||
} else if (targetWidth >= 320 || targetHeight >= 240) {
|
||||
cameraCaptureUI.photoSettings.maxResolution = Windows.Media.Capture.CameraCaptureUIMaxPhotoResolution.verySmallQvga;
|
||||
} else {
|
||||
cameraCaptureUI.photoSettings.maxResolution = Windows.Media.Capture.CameraCaptureUIMaxPhotoResolution.highestAvailable;
|
||||
}
|
||||
|
||||
cameraCaptureUI.captureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.photo).done(function(picture) {
|
||||
if (!picture) {
|
||||
errorCallback("User didn't capture a photo.");
|
||||
return;
|
||||
}
|
||||
|
||||
savePhoto(picture, {
|
||||
destinationType: destinationType,
|
||||
targetHeight: targetHeight,
|
||||
targetWidth: targetWidth,
|
||||
encodingType: encodingType,
|
||||
saveToPhotoAlbum: saveToPhotoAlbum
|
||||
}, successCallback, errorCallback);
|
||||
}, function() {
|
||||
errorCallback("Fail to capture a photo.");
|
||||
});
|
||||
}
|
||||
|
||||
function savePhoto(picture, options, successCallback, errorCallback) {
|
||||
// success callback for capture operation
|
||||
var success = function(picture) {
|
||||
var generateUniqueCollisionOption = Windows.Storage.CreationCollisionOption.generateUniqueName;
|
||||
if (options.destinationType == Camera.DestinationType.FILE_URI || options.destinationType == Camera.DestinationType.NATIVE_URI) {
|
||||
if (options.targetHeight > 0 && options.targetWidth > 0) {
|
||||
resizeImage(successCallback, errorCallback, picture, options.targetWidth, options.targetHeight, options.encodingType);
|
||||
} else {
|
||||
picture.copyAsync(Windows.Storage.ApplicationData.current.localFolder, picture.name, generateUniqueCollisionOption).done(function(copiedFile) {
|
||||
successCallback("ms-appdata:///local/" + copiedFile.name);
|
||||
},errorCallback);
|
||||
}
|
||||
} else {
|
||||
if (options.targetHeight > 0 && options.targetWidth > 0) {
|
||||
resizeImageBase64(successCallback, errorCallback, picture, options.targetWidth, options.targetHeight);
|
||||
} else {
|
||||
Windows.Storage.FileIO.readBufferAsync(picture).done(function(buffer) {
|
||||
var strBase64 = Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(buffer);
|
||||
picture.deleteAsync().done(function() {
|
||||
successCallback(strBase64);
|
||||
}, function(err) {
|
||||
errorCallback(err);
|
||||
});
|
||||
}, errorCallback);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!options.saveToPhotoAlbum) {
|
||||
success(picture);
|
||||
return;
|
||||
} else {
|
||||
var savePicker = new Windows.Storage.Pickers.FileSavePicker();
|
||||
var saveFile = function(file) {
|
||||
if (file) {
|
||||
// Prevent updates to the remote version of the file until we're done
|
||||
Windows.Storage.CachedFileManager.deferUpdates(file);
|
||||
picture.moveAndReplaceAsync(file)
|
||||
.then(function() {
|
||||
// Let Windows know that we're finished changing the file so
|
||||
// the other app can update the remote version of the file.
|
||||
return Windows.Storage.CachedFileManager.completeUpdatesAsync(file);
|
||||
})
|
||||
.done(function(updateStatus) {
|
||||
if (updateStatus === Windows.Storage.Provider.FileUpdateStatus.complete) {
|
||||
success(picture);
|
||||
} else {
|
||||
errorCallback("File update status is not complete.");
|
||||
}
|
||||
}, errorCallback);
|
||||
} else {
|
||||
errorCallback("Failed to select a file.");
|
||||
}
|
||||
};
|
||||
savePicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.picturesLibrary;
|
||||
|
||||
if (options.encodingType === Camera.EncodingType.PNG) {
|
||||
savePicker.fileTypeChoices.insert("PNG", [".png"]);
|
||||
savePicker.suggestedFileName = "photo.png";
|
||||
} else {
|
||||
savePicker.fileTypeChoices.insert("JPEG", [".jpg"]);
|
||||
savePicker.suggestedFileName = "photo.jpg";
|
||||
}
|
||||
|
||||
// If Windows Phone 8.1 use pickSaveFileAndContinue()
|
||||
if (navigator.appVersion.indexOf('Windows Phone 8.1') >= 0) {
|
||||
/*
|
||||
Need to add and remove an event listener to catch activation state
|
||||
Using FileSavePicker will suspend the app and it's required to catch the pickSaveFileContinuation
|
||||
https://msdn.microsoft.com/en-us/library/windows/apps/xaml/dn631755.aspx
|
||||
*/
|
||||
var fileSaveHandler = function(eventArgs) {
|
||||
if (eventArgs.kind === Windows.ApplicationModel.Activation.ActivationKind.pickSaveFileContinuation) {
|
||||
var file = eventArgs.file;
|
||||
saveFile(file);
|
||||
Windows.UI.WebUI.WebUIApplication.removeEventListener("activated", fileSaveHandler);
|
||||
}
|
||||
};
|
||||
Windows.UI.WebUI.WebUIApplication.addEventListener("activated", fileSaveHandler);
|
||||
savePicker.pickSaveFileAndContinue();
|
||||
} else {
|
||||
savePicker.pickSaveFileAsync()
|
||||
.done(saveFile, errorCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
require("cordova/exec/proxy").add("Camera",module.exports);
|
||||
@@ -1,341 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*global Windows:true, URL:true */
|
||||
|
||||
|
||||
var cordova = require('cordova'),
|
||||
Camera = require('./Camera'),
|
||||
FileEntry = require('org.apache.cordova.core.file.FileEntry'),
|
||||
FileError = require('org.apache.cordova.core.file.FileError'),
|
||||
FileReader = require('org.apache.cordova.core.file.FileReader');
|
||||
|
||||
module.exports = {
|
||||
|
||||
// args will contain :
|
||||
// ... it is an array, so be careful
|
||||
// 0 quality:50,
|
||||
// 1 destinationType:Camera.DestinationType.FILE_URI,
|
||||
// 2 sourceType:Camera.PictureSourceType.CAMERA,
|
||||
// 3 targetWidth:-1,
|
||||
// 4 targetHeight:-1,
|
||||
// 5 encodingType:Camera.EncodingType.JPEG,
|
||||
// 6 mediaType:Camera.MediaType.PICTURE,
|
||||
// 7 allowEdit:false,
|
||||
// 8 correctOrientation:false,
|
||||
// 9 saveToPhotoAlbum:false,
|
||||
// 10 popoverOptions:null
|
||||
|
||||
takePicture: function (successCallback, errorCallback, args) {
|
||||
var encodingType = args[5];
|
||||
var targetWidth = args[3];
|
||||
var targetHeight = args[4];
|
||||
var sourceType = args[2];
|
||||
var destinationType = args[1];
|
||||
var mediaType = args[6];
|
||||
var saveToPhotoAlbum = args[9];
|
||||
|
||||
var pkg = Windows.ApplicationModel.Package.current;
|
||||
var packageId = pkg.installedLocation;
|
||||
|
||||
var fail = function (fileError) {
|
||||
errorCallback("FileError, code:" + fileError.code);
|
||||
};
|
||||
|
||||
// resize method :)
|
||||
var resizeImage = function (file) {
|
||||
var tempPhotoFileName = "";
|
||||
if (encodingType == Camera.EncodingType.PNG) {
|
||||
tempPhotoFileName = "camera_cordova_temp_return.png";
|
||||
} else {
|
||||
tempPhotoFileName = "camera_cordova_temp_return.jpg";
|
||||
}
|
||||
var imgObj = new Image();
|
||||
var success = function (fileEntry) {
|
||||
var successCB = function (filePhoto) {
|
||||
var fileType = file.contentType,
|
||||
reader = new FileReader();
|
||||
reader.onloadend = function () {
|
||||
var image = new Image();
|
||||
image.src = reader.result;
|
||||
image.onload = function () {
|
||||
var imageWidth = targetWidth,
|
||||
imageHeight = targetHeight;
|
||||
var canvas = document.createElement('canvas');
|
||||
|
||||
canvas.width = imageWidth;
|
||||
canvas.height = imageHeight;
|
||||
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(this, 0, 0, imageWidth, imageHeight);
|
||||
|
||||
// The resized file ready for upload
|
||||
var _blob = canvas.msToBlob();
|
||||
var _stream = _blob.msDetachStream();
|
||||
Windows.Storage.StorageFolder.getFolderFromPathAsync(packageId.path).done(function (storageFolder) {
|
||||
storageFolder.createFileAsync(tempPhotoFileName, Windows.Storage.CreationCollisionOption.generateUniqueName).done(function (file) {
|
||||
file.openAsync(Windows.Storage.FileAccessMode.readWrite).done(function (fileStream) {
|
||||
Windows.Storage.Streams.RandomAccessStream.copyAndCloseAsync(_stream, fileStream).done(function () {
|
||||
var _imageUrl = URL.createObjectURL(file);
|
||||
successCallback(_imageUrl);
|
||||
}, function () { errorCallback("Resize picture error."); });
|
||||
}, function () { errorCallback("Resize picture error."); });
|
||||
}, function () { errorCallback("Resize picture error."); });
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
reader.readAsDataURL(filePhoto);
|
||||
};
|
||||
|
||||
var failCB = function () {
|
||||
errorCallback("File not found.");
|
||||
};
|
||||
fileEntry.file(successCB, failCB);
|
||||
};
|
||||
|
||||
Windows.Storage.StorageFolder.getFolderFromPathAsync(packageId.path).done(function (storageFolder) {
|
||||
file.copyAsync(storageFolder, file.name, Windows.Storage.NameCollisionOption.replaceExisting).then(function (storageFile) {
|
||||
success(new FileEntry(storageFile.name, storageFile.path));
|
||||
}, function () {
|
||||
fail(FileError.INVALID_MODIFICATION_ERR);
|
||||
}, function () {
|
||||
errorCallback("Folder not access.");
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// because of asynchronous method, so let the successCallback be called in it.
|
||||
var resizeImageBase64 = function (file) {
|
||||
var imgObj = new Image();
|
||||
var success = function (fileEntry) {
|
||||
var successCB = function (filePhoto) {
|
||||
var fileType = file.contentType,
|
||||
reader = new FileReader();
|
||||
reader.onloadend = function () {
|
||||
var image = new Image();
|
||||
image.src = reader.result;
|
||||
|
||||
image.onload = function () {
|
||||
var imageWidth = targetWidth,
|
||||
imageHeight = targetHeight;
|
||||
var canvas = document.createElement('canvas');
|
||||
|
||||
canvas.width = imageWidth;
|
||||
canvas.height = imageHeight;
|
||||
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(this, 0, 0, imageWidth, imageHeight);
|
||||
|
||||
// The resized file ready for upload
|
||||
var finalFile = canvas.toDataURL(fileType);
|
||||
|
||||
// Remove the prefix such as "data:" + contentType + ";base64," , in order to meet the Cordova API.
|
||||
var arr = finalFile.split(",");
|
||||
var newStr = finalFile.substr(arr[0].length + 1);
|
||||
successCallback(newStr);
|
||||
};
|
||||
};
|
||||
|
||||
reader.readAsDataURL(filePhoto);
|
||||
|
||||
};
|
||||
var failCB = function () {
|
||||
errorCallback("File not found.");
|
||||
};
|
||||
fileEntry.file(successCB, failCB);
|
||||
};
|
||||
|
||||
Windows.Storage.StorageFolder.getFolderFromPathAsync(packageId.path).done(function (storageFolder) {
|
||||
file.copyAsync(storageFolder, file.name, Windows.Storage.NameCollisionOption.replaceExisting).then(function (storageFile) {
|
||||
success(new FileEntry(storageFile.name, storageFile.path));
|
||||
}, function () {
|
||||
fail(FileError.INVALID_MODIFICATION_ERR);
|
||||
}, function () {
|
||||
errorCallback("Folder not access.");
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
if (sourceType != Camera.PictureSourceType.CAMERA) {
|
||||
var fileOpenPicker = new Windows.Storage.Pickers.FileOpenPicker();
|
||||
fileOpenPicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.picturesLibrary;
|
||||
if (mediaType == Camera.MediaType.PICTURE) {
|
||||
fileOpenPicker.fileTypeFilter.replaceAll([".png", ".jpg", ".jpeg"]);
|
||||
} else if (mediaType == Camera.MediaType.VIDEO) {
|
||||
fileOpenPicker.fileTypeFilter.replaceAll([".avi", ".flv", ".asx", ".asf", ".mov", ".mp4", ".mpg", ".rm", ".srt", ".swf", ".wmv", ".vob"]);
|
||||
} else {
|
||||
fileOpenPicker.fileTypeFilter.replaceAll(["*"]);
|
||||
}
|
||||
|
||||
fileOpenPicker.pickSingleFileAsync().then(function (file) {
|
||||
if (file) {
|
||||
if (destinationType == Camera.DestinationType.FILE_URI) {
|
||||
if (targetHeight > 0 && targetWidth > 0) {
|
||||
resizeImage(file);
|
||||
} else {
|
||||
Windows.Storage.StorageFolder.getFolderFromPathAsync(packageId.path).done(function (storageFolder) {
|
||||
file.copyAsync(storageFolder, file.name, Windows.Storage.NameCollisionOption.replaceExisting).then(function (storageFile) {
|
||||
var _imageUrl = URL.createObjectURL(storageFile);
|
||||
successCallback(_imageUrl);
|
||||
}, function () {
|
||||
fail(FileError.INVALID_MODIFICATION_ERR);
|
||||
}, function () {
|
||||
errorCallback("Folder not access.");
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (targetHeight > 0 && targetWidth > 0) {
|
||||
resizeImageBase64(file);
|
||||
} else {
|
||||
Windows.Storage.FileIO.readBufferAsync(file).done(function (buffer) {
|
||||
var strBase64 = Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(buffer);
|
||||
successCallback(strBase64);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
errorCallback("User didn't choose a file.");
|
||||
}
|
||||
}, function () {
|
||||
errorCallback("User didn't choose a file.");
|
||||
});
|
||||
}
|
||||
else {
|
||||
|
||||
var cameraCaptureUI = new Windows.Media.Capture.CameraCaptureUI();
|
||||
cameraCaptureUI.photoSettings.allowCropping = true;
|
||||
var allowCrop = !!args[7];
|
||||
if (!allowCrop) {
|
||||
cameraCaptureUI.photoSettings.allowCropping = false;
|
||||
}
|
||||
|
||||
if (encodingType == Camera.EncodingType.PNG) {
|
||||
cameraCaptureUI.photoSettings.format = Windows.Media.Capture.CameraCaptureUIPhotoFormat.png;
|
||||
} else {
|
||||
cameraCaptureUI.photoSettings.format = Windows.Media.Capture.CameraCaptureUIPhotoFormat.jpeg;
|
||||
}
|
||||
// decide which max pixels should be supported by targetWidth or targetHeight.
|
||||
if (targetWidth >= 1280 || targetHeight >= 960) {
|
||||
cameraCaptureUI.photoSettings.maxResolution = Windows.Media.Capture.CameraCaptureUIMaxPhotoResolution.large3M;
|
||||
} else if (targetWidth >= 1024 || targetHeight >= 768) {
|
||||
cameraCaptureUI.photoSettings.maxResolution = Windows.Media.Capture.CameraCaptureUIMaxPhotoResolution.mediumXga;
|
||||
} else if (targetWidth >= 800 || targetHeight >= 600) {
|
||||
cameraCaptureUI.photoSettings.maxResolution = Windows.Media.Capture.CameraCaptureUIMaxPhotoResolution.mediumXga;
|
||||
} else if (targetWidth >= 640 || targetHeight >= 480) {
|
||||
cameraCaptureUI.photoSettings.maxResolution = Windows.Media.Capture.CameraCaptureUIMaxPhotoResolution.smallVga;
|
||||
} else if (targetWidth >= 320 || targetHeight >= 240) {
|
||||
cameraCaptureUI.photoSettings.maxResolution = Windows.Media.Capture.CameraCaptureUIMaxPhotoResolution.verySmallQvga;
|
||||
} else {
|
||||
cameraCaptureUI.photoSettings.maxResolution = Windows.Media.Capture.CameraCaptureUIMaxPhotoResolution.highestAvailable;
|
||||
}
|
||||
|
||||
cameraCaptureUI.captureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.photo).then(function (picture) {
|
||||
if (picture) {
|
||||
// save to photo album successCallback
|
||||
var success = function (fileEntry) {
|
||||
if (destinationType == Camera.DestinationType.FILE_URI) {
|
||||
if (targetHeight > 0 && targetWidth > 0) {
|
||||
resizeImage(picture);
|
||||
} else {
|
||||
Windows.Storage.StorageFolder.getFolderFromPathAsync(packageId.path).done(function (storageFolder) {
|
||||
picture.copyAsync(storageFolder, picture.name, Windows.Storage.NameCollisionOption.replaceExisting).then(function (storageFile) {
|
||||
var _imageUrl = URL.createObjectURL(storageFile);
|
||||
successCallback(_imageUrl);
|
||||
}, function () {
|
||||
fail(FileError.INVALID_MODIFICATION_ERR);
|
||||
}, function () {
|
||||
errorCallback("Folder not access.");
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (targetHeight > 0 && targetWidth > 0) {
|
||||
resizeImageBase64(picture);
|
||||
} else {
|
||||
Windows.Storage.FileIO.readBufferAsync(picture).done(function (buffer) {
|
||||
var strBase64 = Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(buffer);
|
||||
successCallback(strBase64);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
// save to photo album errorCallback
|
||||
var fail = function () {
|
||||
//errorCallback("FileError, code:" + fileError.code);
|
||||
errorCallback("Save fail.");
|
||||
};
|
||||
|
||||
if (saveToPhotoAlbum) {
|
||||
Windows.Storage.StorageFile.getFileFromPathAsync(picture.path).then(function (storageFile) {
|
||||
storageFile.copyAsync(Windows.Storage.KnownFolders.picturesLibrary, picture.name, Windows.Storage.NameCollisionOption.generateUniqueName).then(function (storageFile) {
|
||||
success(storageFile);
|
||||
}, function () {
|
||||
fail();
|
||||
});
|
||||
});
|
||||
//var directory = new DirectoryEntry("Pictures", parentPath);
|
||||
//new FileEntry(picture.name, picture.path).copyTo(directory, null, success, fail);
|
||||
} else {
|
||||
if (destinationType == Camera.DestinationType.FILE_URI) {
|
||||
if (targetHeight > 0 && targetWidth > 0) {
|
||||
resizeImage(picture);
|
||||
} else {
|
||||
Windows.Storage.StorageFolder.getFolderFromPathAsync(packageId.path).done(function (storageFolder) {
|
||||
picture.copyAsync(storageFolder, picture.name, Windows.Storage.NameCollisionOption.replaceExisting).then(function (storageFile) {
|
||||
var _imageUrl = URL.createObjectURL(storageFile);
|
||||
successCallback(_imageUrl);
|
||||
}, function () {
|
||||
fail(FileError.INVALID_MODIFICATION_ERR);
|
||||
}, function () {
|
||||
errorCallback("Folder not access.");
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (targetHeight > 0 && targetWidth > 0) {
|
||||
resizeImageBase64(picture);
|
||||
} else {
|
||||
Windows.Storage.FileIO.readBufferAsync(picture).done(function (buffer) {
|
||||
var strBase64 = Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(buffer);
|
||||
successCallback(strBase64);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
errorCallback("User didn't capture a photo.");
|
||||
}
|
||||
}, function () {
|
||||
errorCallback("Fail to capture a photo.");
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
require("cordova/commandProxy").add("Camera",module.exports);
|
||||
368
src/wp/Camera.cs
368
src/wp/Camera.cs
@@ -113,8 +113,6 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
[DataMember(IsRequired = false, Name = "correctOrientation")]
|
||||
public bool CorrectOrientation { get; set; }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Ignored
|
||||
/// </summary>
|
||||
@@ -176,16 +174,6 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to open photo library
|
||||
/// </summary>
|
||||
PhotoChooserTask photoChooserTask;
|
||||
|
||||
/// <summary>
|
||||
/// Used to open camera application
|
||||
/// </summary>
|
||||
CameraCaptureTask cameraTask;
|
||||
|
||||
/// <summary>
|
||||
/// Camera options
|
||||
/// </summary>
|
||||
@@ -198,54 +186,70 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
|
||||
// ["quality", "destinationType", "sourceType", "targetWidth", "targetHeight", "encodingType",
|
||||
// "mediaType", "allowEdit", "correctOrientation", "saveToPhotoAlbum" ]
|
||||
this.cameraOptions = new CameraOptions();
|
||||
this.cameraOptions.Quality = int.Parse(args[0]);
|
||||
this.cameraOptions.DestinationType = int.Parse(args[1]);
|
||||
this.cameraOptions.PictureSourceType = int.Parse(args[2]);
|
||||
this.cameraOptions.TargetWidth = int.Parse(args[3]);
|
||||
this.cameraOptions.TargetHeight = int.Parse(args[4]);
|
||||
this.cameraOptions.EncodingType = int.Parse(args[5]);
|
||||
this.cameraOptions.MediaType = int.Parse(args[6]);
|
||||
this.cameraOptions.AllowEdit = bool.Parse(args[7]);
|
||||
this.cameraOptions.CorrectOrientation = bool.Parse(args[8]);
|
||||
this.cameraOptions.SaveToPhotoAlbum = bool.Parse(args[9]);
|
||||
|
||||
//this.cameraOptions = String.IsNullOrEmpty(options) ?
|
||||
// new CameraOptions() : JSON.JsonHelper.Deserialize<CameraOptions>(options);
|
||||
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)
|
||||
{
|
||||
this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO Check if all the options are acceptable
|
||||
|
||||
if(cameraOptions.DestinationType != Camera.FILE_URI && cameraOptions.DestinationType != Camera.DATA_URL )
|
||||
{
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
|
||||
return;
|
||||
}
|
||||
|
||||
ChooserBase<PhotoResult> chooserTask = null;
|
||||
if (cameraOptions.PictureSourceType == CAMERA)
|
||||
{
|
||||
cameraTask = new CameraCaptureTask();
|
||||
cameraTask.Completed += onCameraTaskCompleted;
|
||||
cameraTask.Show();
|
||||
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
|
||||
{
|
||||
if ((cameraOptions.PictureSourceType == PHOTOLIBRARY) || (cameraOptions.PictureSourceType == SAVEDPHOTOALBUM))
|
||||
{
|
||||
photoChooserTask = new PhotoChooserTask();
|
||||
photoChooserTask.Completed += onPickerTaskCompleted;
|
||||
photoChooserTask.Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
|
||||
}
|
||||
Debug.WriteLine("Unrecognized PictureSourceType :: " + cameraOptions.PictureSourceType.ToString());
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void onCameraTaskCompleted(object sender, PhotoResult e)
|
||||
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));
|
||||
@@ -259,19 +263,21 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
{
|
||||
string imagePathOrContent = string.Empty;
|
||||
|
||||
if (cameraOptions.DestinationType == FILE_URI)
|
||||
// Save image back to media library
|
||||
// only save to photoalbum if it didn't come from there ...
|
||||
if (cameraOptions.PictureSourceType == CAMERA && cameraOptions.SaveToPhotoAlbum)
|
||||
{
|
||||
// Save image in media library
|
||||
if (cameraOptions.SaveToPhotoAlbum)
|
||||
{
|
||||
MediaLibrary library = new MediaLibrary();
|
||||
Picture pict = library.SavePicture(e.OriginalFileName, e.ChosenPhoto); // to save to photo-roll ...
|
||||
}
|
||||
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);
|
||||
int newAngle = 0;
|
||||
switch (orient)
|
||||
{
|
||||
switch (orient) {
|
||||
case ImageExifOrientation.LandscapeLeft:
|
||||
newAngle = 90;
|
||||
break;
|
||||
@@ -284,100 +290,54 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
case ImageExifOrientation.Portrait:
|
||||
default: break; // 0 default already set
|
||||
}
|
||||
|
||||
Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle);
|
||||
|
||||
// we should return stream position back after saving stream to media library
|
||||
rotImageStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
WriteableBitmap image = PictureDecoder.DecodeJpeg(rotImageStream);
|
||||
|
||||
imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
|
||||
|
||||
|
||||
} catch {
|
||||
Debug.WriteLine("Error fetching orientation from Exif");
|
||||
}
|
||||
else if (cameraOptions.DestinationType == DATA_URL)
|
||||
|
||||
if (newAngle != 0)
|
||||
{
|
||||
imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
|
||||
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
|
||||
{
|
||||
imagePathOrContent = SaveImageToLocalStorage(rotImageStream, Path.GetFileName(e.OriginalFileName));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else // no need to reorient
|
||||
{
|
||||
// TODO: shouldn't this happen before we launch the camera-picker?
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
|
||||
return;
|
||||
if (cameraOptions.DestinationType == DATA_URL)
|
||||
{
|
||||
imagePathOrContent = GetImageContent(e.ChosenPhoto);
|
||||
}
|
||||
else // FILE_URL
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void onPickerTaskCompleted(object sender, PhotoResult e)
|
||||
{
|
||||
if (e.Error != null)
|
||||
{
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e.TaskResult)
|
||||
{
|
||||
case TaskResult.OK:
|
||||
try
|
||||
{
|
||||
string imagePathOrContent = string.Empty;
|
||||
|
||||
if (cameraOptions.DestinationType == FILE_URI)
|
||||
{
|
||||
WriteableBitmap image = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
|
||||
imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
|
||||
}
|
||||
else if (cameraOptions.DestinationType == DATA_URL)
|
||||
{
|
||||
imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: shouldn't this happen before we launch the camera-picker?
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
|
||||
return;
|
||||
}
|
||||
|
||||
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>
|
||||
@@ -385,76 +345,119 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
/// <returns>Base64 representation of the image</returns>
|
||||
private string GetImageContent(Stream stream)
|
||||
{
|
||||
int streamLength = (int)stream.Length;
|
||||
byte[] fileData = new byte[streamLength + 1];
|
||||
stream.Read(fileData, 0, streamLength);
|
||||
byte[] imageContent = null;
|
||||
|
||||
//use photo's actual width & height if user doesn't provide width & height
|
||||
if (cameraOptions.TargetWidth < 0 && cameraOptions.TargetHeight < 0)
|
||||
try
|
||||
{
|
||||
stream.Close();
|
||||
return Convert.ToBase64String(fileData);
|
||||
// Resize photo and convert to JPEG
|
||||
imageContent = ResizePhoto(stream);
|
||||
}
|
||||
else
|
||||
finally
|
||||
{
|
||||
// resize photo
|
||||
byte[] resizedFile = ResizePhoto(stream, fileData);
|
||||
stream.Close();
|
||||
return Convert.ToBase64String(resizedFile);
|
||||
stream.Dispose();
|
||||
}
|
||||
|
||||
return Convert.ToBase64String(imageContent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resize image
|
||||
/// </summary>
|
||||
/// <param name="stream">Image stream</param>
|
||||
/// <param name="fileData">File data</param>
|
||||
/// <returns>resized image</returns>
|
||||
private byte[] ResizePhoto(Stream stream, byte[] fileData)
|
||||
private byte[] ResizePhoto(Stream stream)
|
||||
{
|
||||
int streamLength = (int)stream.Length;
|
||||
int intResult = 0;
|
||||
|
||||
//output
|
||||
byte[] resizedFile;
|
||||
|
||||
stream.Read(fileData, 0, streamLength);
|
||||
|
||||
BitmapImage objBitmap = new BitmapImage();
|
||||
MemoryStream objBitmapStream = new MemoryStream(fileData);
|
||||
MemoryStream objBitmapStreamResized = new MemoryStream();
|
||||
WriteableBitmap objWB;
|
||||
objBitmap.SetSource(stream);
|
||||
objWB = new WriteableBitmap(objBitmap);
|
||||
objBitmap.CreateOptions = BitmapCreateOptions.None;
|
||||
|
||||
// resize the photo with user defined TargetWidth & TargetHeight
|
||||
Extensions.SaveJpeg(objWB, objBitmapStreamResized, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
|
||||
WriteableBitmap objWB = new WriteableBitmap(objBitmap);
|
||||
objBitmap.UriSource = null;
|
||||
|
||||
//Convert the resized stream to a byte array.
|
||||
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...
|
||||
intResult = objBitmapStreamResized.Read(resizedFile, 0, streamLength);
|
||||
// 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(WriteableBitmap image, string imageFileName)
|
||||
private string SaveImageToLocalStorage(Stream stream, string imageFileName)
|
||||
{
|
||||
|
||||
if (image == null)
|
||||
if (stream == null)
|
||||
{
|
||||
throw new ArgumentNullException("imageBytes");
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
|
||||
var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
|
||||
|
||||
if (!isoFile.DirectoryExists(isoFolder))
|
||||
@@ -464,16 +467,41 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
|
||||
string filePath = System.IO.Path.Combine("///" + isoFolder + "/", imageFileName);
|
||||
|
||||
using (var stream = isoFile.CreateFile(filePath))
|
||||
using (IsolatedStorageFileStream outputStream = isoFile.CreateFile(filePath))
|
||||
{
|
||||
// resize image if Height and Width defined via options
|
||||
if (cameraOptions.TargetHeight > 0 && cameraOptions.TargetWidth > 0)
|
||||
BitmapImage objBitmap = new BitmapImage();
|
||||
objBitmap.SetSource(stream);
|
||||
objBitmap.CreateOptions = BitmapCreateOptions.None;
|
||||
|
||||
WriteableBitmap objWB = new WriteableBitmap(objBitmap);
|
||||
objBitmap.UriSource = null;
|
||||
|
||||
try
|
||||
{
|
||||
image.SaveJpeg(stream, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
|
||||
|
||||
//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);
|
||||
}
|
||||
}
|
||||
else
|
||||
finally
|
||||
{
|
||||
image.SaveJpeg(stream, image.PixelWidth, image.PixelHeight, 0, cameraOptions.Quality);
|
||||
//Dispose bitmaps immediately, they are memory expensive
|
||||
DisposeImage(objBitmap);
|
||||
DisposeImage(objWB);
|
||||
GC.Collect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -484,6 +512,10 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
//TODO: log or do something else
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
stream.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
jasmine.HtmlReporter = function(_doc) {
|
||||
var self = this;
|
||||
var doc = _doc || window.document;
|
||||
|
||||
var reporterView;
|
||||
|
||||
var dom = {};
|
||||
|
||||
// Jasmine Reporter Public Interface
|
||||
self.logRunningSpecs = false;
|
||||
|
||||
self.reportRunnerStarting = function(runner) {
|
||||
var specs = runner.specs() || [];
|
||||
|
||||
if (specs.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
createReporterDom(runner.env.versionString());
|
||||
doc.body.appendChild(dom.reporter);
|
||||
|
||||
reporterView = new jasmine.HtmlReporter.ReporterView(dom);
|
||||
reporterView.addSpecs(specs, self.specFilter);
|
||||
};
|
||||
|
||||
self.reportRunnerResults = function(runner) {
|
||||
reporterView && reporterView.complete();
|
||||
};
|
||||
|
||||
self.reportSuiteResults = function(suite) {
|
||||
reporterView.suiteComplete(suite);
|
||||
};
|
||||
|
||||
self.reportSpecStarting = function(spec) {
|
||||
if (self.logRunningSpecs) {
|
||||
self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
|
||||
}
|
||||
};
|
||||
|
||||
self.reportSpecResults = function(spec) {
|
||||
reporterView.specComplete(spec);
|
||||
};
|
||||
|
||||
self.log = function() {
|
||||
var console = jasmine.getGlobal().console;
|
||||
if (console && console.log) {
|
||||
if (console.log.apply) {
|
||||
console.log.apply(console, arguments);
|
||||
} else {
|
||||
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
self.specFilter = function(spec) {
|
||||
if (!focusedSpecName()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return spec.getFullName().indexOf(focusedSpecName()) === 0;
|
||||
};
|
||||
|
||||
return self;
|
||||
|
||||
function focusedSpecName() {
|
||||
var specName;
|
||||
|
||||
(function memoizeFocusedSpec() {
|
||||
if (specName) {
|
||||
return;
|
||||
}
|
||||
|
||||
var paramMap = [];
|
||||
var params = doc.location.search.substring(1).split('&');
|
||||
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var p = params[i].split('=');
|
||||
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
|
||||
}
|
||||
|
||||
specName = paramMap.spec;
|
||||
})();
|
||||
|
||||
return specName;
|
||||
}
|
||||
|
||||
function createReporterDom(version) {
|
||||
dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
|
||||
dom.banner = self.createDom('div', { className: 'banner' },
|
||||
self.createDom('span', { className: 'title' }, "Jasmine "),
|
||||
self.createDom('span', { className: 'version' }, version)),
|
||||
|
||||
dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
|
||||
dom.alert = self.createDom('div', {className: 'alert'}),
|
||||
dom.results = self.createDom('div', {className: 'results'},
|
||||
dom.summary = self.createDom('div', { className: 'summary' }),
|
||||
dom.details = self.createDom('div', { id: 'details' }))
|
||||
);
|
||||
}
|
||||
};
|
||||
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);
|
||||
@@ -1,60 +0,0 @@
|
||||
jasmine.HtmlReporterHelpers = {};
|
||||
|
||||
jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {
|
||||
var el = document.createElement(type);
|
||||
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var child = arguments[i];
|
||||
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(document.createTextNode(child));
|
||||
} else {
|
||||
if (child) {
|
||||
el.appendChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var attr in attrs) {
|
||||
if (attr == "className") {
|
||||
el[attr] = attrs[attr];
|
||||
} else {
|
||||
el.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.getSpecStatus = function(child) {
|
||||
var results = child.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.skipped) {
|
||||
status = 'skipped';
|
||||
}
|
||||
|
||||
return status;
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
|
||||
var parentDiv = this.dom.summary;
|
||||
var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
|
||||
var parent = child[parentSuite];
|
||||
|
||||
if (parent) {
|
||||
if (typeof this.views.suites[parent.id] == 'undefined') {
|
||||
this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
|
||||
}
|
||||
parentDiv = this.views.suites[parent.id].element;
|
||||
}
|
||||
|
||||
parentDiv.appendChild(childElement);
|
||||
};
|
||||
|
||||
|
||||
jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
|
||||
for(var fn in jasmine.HtmlReporterHelpers) {
|
||||
ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
jasmine.HtmlReporter.ReporterView = function(dom) {
|
||||
this.startedAt = new Date();
|
||||
this.runningSpecCount = 0;
|
||||
this.completeSpecCount = 0;
|
||||
this.passedCount = 0;
|
||||
this.failedCount = 0;
|
||||
this.skippedCount = 0;
|
||||
|
||||
this.createResultsMenu = function() {
|
||||
this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
|
||||
this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
|
||||
' | ',
|
||||
this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
|
||||
|
||||
this.summaryMenuItem.onclick = function() {
|
||||
dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
|
||||
};
|
||||
|
||||
this.detailsMenuItem.onclick = function() {
|
||||
showDetails();
|
||||
};
|
||||
};
|
||||
|
||||
this.addSpecs = function(specs, specFilter) {
|
||||
this.totalSpecCount = specs.length;
|
||||
|
||||
this.views = {
|
||||
specs: {},
|
||||
suites: {}
|
||||
};
|
||||
|
||||
for (var i = 0; i < specs.length; i++) {
|
||||
var spec = specs[i];
|
||||
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);
|
||||
if (specFilter(spec)) {
|
||||
this.runningSpecCount++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.specComplete = function(spec) {
|
||||
this.completeSpecCount++;
|
||||
|
||||
if (isUndefined(this.views.specs[spec.id])) {
|
||||
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
|
||||
}
|
||||
|
||||
var specView = this.views.specs[spec.id];
|
||||
|
||||
switch (specView.status()) {
|
||||
case 'passed':
|
||||
this.passedCount++;
|
||||
break;
|
||||
|
||||
case 'failed':
|
||||
this.failedCount++;
|
||||
break;
|
||||
|
||||
case 'skipped':
|
||||
this.skippedCount++;
|
||||
break;
|
||||
}
|
||||
|
||||
specView.refresh();
|
||||
this.refresh();
|
||||
};
|
||||
|
||||
this.suiteComplete = function(suite) {
|
||||
var suiteView = this.views.suites[suite.id];
|
||||
if (isUndefined(suiteView)) {
|
||||
return;
|
||||
}
|
||||
suiteView.refresh();
|
||||
};
|
||||
|
||||
this.refresh = function() {
|
||||
|
||||
if (isUndefined(this.resultsMenu)) {
|
||||
this.createResultsMenu();
|
||||
}
|
||||
|
||||
// currently running UI
|
||||
if (isUndefined(this.runningAlert)) {
|
||||
this.runningAlert = this.createDom('a', {href: "?", className: "runningAlert bar"});
|
||||
dom.alert.appendChild(this.runningAlert);
|
||||
}
|
||||
this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
|
||||
|
||||
// skipped specs UI
|
||||
if (isUndefined(this.skippedAlert)) {
|
||||
this.skippedAlert = this.createDom('a', {href: "?", className: "skippedAlert bar"});
|
||||
}
|
||||
|
||||
this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
|
||||
|
||||
if (this.skippedCount === 1 && isDefined(dom.alert)) {
|
||||
dom.alert.appendChild(this.skippedAlert);
|
||||
}
|
||||
|
||||
// passing specs UI
|
||||
if (isUndefined(this.passedAlert)) {
|
||||
this.passedAlert = this.createDom('span', {href: "?", className: "passingAlert bar"});
|
||||
}
|
||||
this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
|
||||
|
||||
// failing specs UI
|
||||
if (isUndefined(this.failedAlert)) {
|
||||
this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
|
||||
}
|
||||
this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
|
||||
|
||||
if (this.failedCount === 1 && isDefined(dom.alert)) {
|
||||
dom.alert.appendChild(this.failedAlert);
|
||||
dom.alert.appendChild(this.resultsMenu);
|
||||
}
|
||||
|
||||
// summary info
|
||||
this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
|
||||
this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
|
||||
};
|
||||
|
||||
this.complete = function() {
|
||||
dom.alert.removeChild(this.runningAlert);
|
||||
|
||||
this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
|
||||
|
||||
if (this.failedCount === 0) {
|
||||
dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
|
||||
} else {
|
||||
showDetails();
|
||||
}
|
||||
|
||||
dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function showDetails() {
|
||||
if (dom.reporter.className.search(/showDetails/) === -1) {
|
||||
dom.reporter.className += " showDetails";
|
||||
}
|
||||
}
|
||||
|
||||
function isUndefined(obj) {
|
||||
return typeof obj === 'undefined';
|
||||
}
|
||||
|
||||
function isDefined(obj) {
|
||||
return !isUndefined(obj);
|
||||
}
|
||||
|
||||
function specPluralizedFor(count) {
|
||||
var str = count + " spec";
|
||||
if (count > 1) {
|
||||
str += "s"
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);
|
||||
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
|
||||
this.spec = spec;
|
||||
this.dom = dom;
|
||||
this.views = views;
|
||||
|
||||
this.symbol = this.createDom('li', { className: 'pending' });
|
||||
this.dom.symbolSummary.appendChild(this.symbol);
|
||||
|
||||
this.summary = this.createDom('div', { className: 'specSummary' },
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
|
||||
title: this.spec.getFullName()
|
||||
}, this.spec.description)
|
||||
);
|
||||
|
||||
this.detail = this.createDom('div', { className: 'specDetail' },
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
|
||||
title: this.spec.getFullName()
|
||||
}, this.spec.getFullName())
|
||||
);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SpecView.prototype.status = function() {
|
||||
return this.getSpecStatus(this.spec);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
|
||||
this.symbol.className = this.status();
|
||||
|
||||
switch (this.status()) {
|
||||
case 'skipped':
|
||||
break;
|
||||
|
||||
case 'passed':
|
||||
this.appendSummaryToSuiteDiv();
|
||||
break;
|
||||
|
||||
case 'failed':
|
||||
this.appendSummaryToSuiteDiv();
|
||||
this.appendFailureDetail();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
|
||||
this.summary.className += ' ' + this.status();
|
||||
this.appendToSummary(this.spec, this.summary);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
|
||||
this.detail.className += ' ' + this.status();
|
||||
|
||||
var resultItems = this.spec.results().getItems();
|
||||
var messagesDiv = this.createDom('div', { className: 'messages' });
|
||||
|
||||
for (var i = 0; i < resultItems.length; i++) {
|
||||
var result = resultItems[i];
|
||||
|
||||
if (result.type == 'log') {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
|
||||
} else if (result.type == 'expect' && result.passed && !result.passed()) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
|
||||
|
||||
if (result.trace.stack) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (messagesDiv.childNodes.length > 0) {
|
||||
this.detail.appendChild(messagesDiv);
|
||||
this.dom.details.appendChild(this.detail);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);
|
||||
@@ -1,22 +0,0 @@
|
||||
jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
|
||||
this.suite = suite;
|
||||
this.dom = dom;
|
||||
this.views = views;
|
||||
|
||||
this.element = this.createDom('div', { className: 'suite' },
|
||||
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(this.suite.getFullName()) }, this.suite.description)
|
||||
);
|
||||
|
||||
this.appendToSummary(this.suite, this.element);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SuiteView.prototype.status = function() {
|
||||
return this.getSpecStatus(this.suite);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
|
||||
this.element.className += " " + this.status();
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);
|
||||
|
||||
@@ -1,192 +0,0 @@
|
||||
/* @deprecated Use jasmine.HtmlReporter instead
|
||||
*/
|
||||
jasmine.TrivialReporter = function(doc) {
|
||||
this.document = doc || document;
|
||||
this.suiteDivs = {};
|
||||
this.logRunningSpecs = false;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
|
||||
var el = document.createElement(type);
|
||||
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var child = arguments[i];
|
||||
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(document.createTextNode(child));
|
||||
} else {
|
||||
if (child) { el.appendChild(child); }
|
||||
}
|
||||
}
|
||||
|
||||
for (var attr in attrs) {
|
||||
if (attr == "className") {
|
||||
el[attr] = attrs[attr];
|
||||
} else {
|
||||
el.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
|
||||
var showPassed, showSkipped;
|
||||
|
||||
this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' },
|
||||
this.createDom('div', { className: 'banner' },
|
||||
this.createDom('div', { className: 'logo' },
|
||||
this.createDom('span', { className: 'title' }, "Jasmine"),
|
||||
this.createDom('span', { className: 'version' }, runner.env.versionString())),
|
||||
this.createDom('div', { className: 'options' },
|
||||
"Show ",
|
||||
showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
|
||||
this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
|
||||
showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
|
||||
this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
|
||||
)
|
||||
),
|
||||
|
||||
this.runnerDiv = this.createDom('div', { className: 'runner running' },
|
||||
this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
|
||||
this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
|
||||
this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
|
||||
);
|
||||
|
||||
this.document.body.appendChild(this.outerDiv);
|
||||
|
||||
var suites = runner.suites();
|
||||
for (var i = 0; i < suites.length; i++) {
|
||||
var suite = suites[i];
|
||||
var suiteDiv = this.createDom('div', { className: 'suite' },
|
||||
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
|
||||
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
|
||||
this.suiteDivs[suite.id] = suiteDiv;
|
||||
var parentDiv = this.outerDiv;
|
||||
if (suite.parentSuite) {
|
||||
parentDiv = this.suiteDivs[suite.parentSuite.id];
|
||||
}
|
||||
parentDiv.appendChild(suiteDiv);
|
||||
}
|
||||
|
||||
this.startedAt = new Date();
|
||||
|
||||
var self = this;
|
||||
showPassed.onclick = function(evt) {
|
||||
if (showPassed.checked) {
|
||||
self.outerDiv.className += ' show-passed';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
|
||||
}
|
||||
};
|
||||
|
||||
showSkipped.onclick = function(evt) {
|
||||
if (showSkipped.checked) {
|
||||
self.outerDiv.className += ' show-skipped';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
|
||||
var results = runner.results();
|
||||
var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
|
||||
this.runnerDiv.setAttribute("class", className);
|
||||
//do it twice for IE
|
||||
this.runnerDiv.setAttribute("className", className);
|
||||
var specs = runner.specs();
|
||||
var specCount = 0;
|
||||
for (var i = 0; i < specs.length; i++) {
|
||||
if (this.specFilter(specs[i])) {
|
||||
specCount++;
|
||||
}
|
||||
}
|
||||
var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
|
||||
message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
|
||||
this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
|
||||
|
||||
this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
|
||||
var results = suite.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.totalCount === 0) { // todo: change this to check results.skipped
|
||||
status = 'skipped';
|
||||
}
|
||||
this.suiteDivs[suite.id].className += " " + status;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
|
||||
if (this.logRunningSpecs) {
|
||||
this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
|
||||
var results = spec.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.skipped) {
|
||||
status = 'skipped';
|
||||
}
|
||||
var specDiv = this.createDom('div', { className: 'spec ' + status },
|
||||
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: '?spec=' + encodeURIComponent(spec.getFullName()),
|
||||
title: spec.getFullName()
|
||||
}, spec.description));
|
||||
|
||||
|
||||
var resultItems = results.getItems();
|
||||
var messagesDiv = this.createDom('div', { className: 'messages' });
|
||||
for (var i = 0; i < resultItems.length; i++) {
|
||||
var result = resultItems[i];
|
||||
|
||||
if (result.type == 'log') {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
|
||||
} else if (result.type == 'expect' && result.passed && !result.passed()) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
|
||||
|
||||
if (result.trace.stack) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (messagesDiv.childNodes.length > 0) {
|
||||
specDiv.appendChild(messagesDiv);
|
||||
}
|
||||
|
||||
this.suiteDivs[spec.suite.id].appendChild(specDiv);
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.log = function() {
|
||||
var console = jasmine.getGlobal().console;
|
||||
if (console && console.log) {
|
||||
if (console.log.apply) {
|
||||
console.log.apply(console, arguments);
|
||||
} else {
|
||||
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.getLocation = function() {
|
||||
return this.document.location;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.specFilter = function(spec) {
|
||||
var paramMap = {};
|
||||
var params = this.getLocation().search.substring(1).split('&');
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var p = params[i].split('=');
|
||||
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
|
||||
}
|
||||
|
||||
if (!paramMap.spec) {
|
||||
return true;
|
||||
}
|
||||
return spec.getFullName().indexOf(paramMap.spec) === 0;
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
<!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 http-equiv="Content-Type" content="text/html;charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
|
||||
|
||||
<title>Cordova API Specs</title>
|
||||
|
||||
<link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
|
||||
<script type="text/javascript" src="../cordova-incl.js"></script>
|
||||
</head>
|
||||
<body id="stage" class="theme">
|
||||
<h1>Cordova API Specs</h1>
|
||||
|
||||
<a href="pages/all.html" class="btn large" style="width:100%;">Run All Tests</a>
|
||||
<a href="pages/accelerometer.html" class="btn large" style="width:100%;">Run Accelerometer Tests</a>
|
||||
<a href="pages/battery.html" class="btn large" style="width:100%;">Run Battery Tests</a>
|
||||
<a href="pages/camera.html" class="btn large" style="width:100%;">Run Camera Tests</a>
|
||||
<a href="pages/capture.html" class="btn large" style="width:100%;">Run Capture Tests</a>
|
||||
<a href="pages/compass.html" class="btn large" style="width:100%;">Run Compass Tests</a>
|
||||
<a href="pages/contacts.html" class="btn large" style="width:100%;">Run Contacts Tests</a>
|
||||
<a href="pages/datauri.html" class="btn large" style="width:100%;">Run Data URI Tests</a>
|
||||
<a href="pages/device.html" class="btn large" style="width:100%;">Run Device Tests</a>
|
||||
<a href="pages/file.html" class="btn large" style="width:100%;">Run File Tests</a>
|
||||
<a href="pages/filetransfer.html" class="btn large" style="width:100%;">Run FileTransfer Tests</a>
|
||||
<a href="pages/geolocation.html" class="btn large" style="width:100%;">Run Geolocation Tests</a>
|
||||
<a href="pages/globalization.html" class="btn large" style="width:100%;">Run Globalization Tests</a>
|
||||
<a href="pages/media.html" class="btn large" style="width:100%;">Run Media Tests</a>
|
||||
<a href="pages/network.html" class="btn large" style="width:100%;">Run Network Tests</a>
|
||||
<a href="pages/notification.html" class="btn large" style="width:100%;">Run Notification Tests</a>
|
||||
<a href="pages/platform.html" class="btn large" style="width:100%;">Run Platform Tests</a>
|
||||
<a href="pages/storage.html" class="btn large" style="width:100%;">Run Storage Tests</a>
|
||||
<a href="pages/bridge.html" class="btn large" style="width:100%;">Run Bridge Tests</a>
|
||||
|
||||
<h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,81 +0,0 @@
|
||||
body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
|
||||
|
||||
#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
|
||||
#HTMLReporter a { text-decoration: none; }
|
||||
#HTMLReporter a:hover { text-decoration: underline; }
|
||||
#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
|
||||
#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
|
||||
#HTMLReporter #jasmine_content { position: fixed; right: 100%; }
|
||||
#HTMLReporter .version { color: #aaaaaa; }
|
||||
#HTMLReporter .banner { margin-top: 14px; }
|
||||
#HTMLReporter .duration { color: #aaaaaa; float: right; }
|
||||
#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
|
||||
#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
|
||||
#HTMLReporter .symbolSummary li.passed { font-size: 14px; }
|
||||
#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
|
||||
#HTMLReporter .symbolSummary li.failed { line-height: 9px; }
|
||||
#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
|
||||
#HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
|
||||
#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
|
||||
#HTMLReporter .symbolSummary li.pending { line-height: 11px; }
|
||||
#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
|
||||
#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
|
||||
#HTMLReporter .runningAlert { background-color: #666666; }
|
||||
#HTMLReporter .skippedAlert { background-color: #aaaaaa; }
|
||||
#HTMLReporter .skippedAlert:first-child { background-color: #333333; }
|
||||
#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
|
||||
#HTMLReporter .passingAlert { background-color: #a6b779; }
|
||||
#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
|
||||
#HTMLReporter .failingAlert { background-color: #cf867e; }
|
||||
#HTMLReporter .failingAlert:first-child { background-color: #b03911; }
|
||||
#HTMLReporter .results { margin-top: 14px; }
|
||||
#HTMLReporter #details { display: none; }
|
||||
#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
|
||||
#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
|
||||
#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
|
||||
#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
|
||||
#HTMLReporter.showDetails .summary { display: none; }
|
||||
#HTMLReporter.showDetails #details { display: block; }
|
||||
#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
|
||||
#HTMLReporter .summary { margin-top: 14px; }
|
||||
#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
|
||||
#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
|
||||
#HTMLReporter .summary .specSummary.failed a { color: #b03911; }
|
||||
#HTMLReporter .description + .suite { margin-top: 0; }
|
||||
#HTMLReporter .suite { margin-top: 14px; }
|
||||
#HTMLReporter .suite a { color: #333333; }
|
||||
#HTMLReporter #details .specDetail { margin-bottom: 28px; }
|
||||
#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
|
||||
#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
|
||||
#HTMLReporter .resultMessage span.result { display: block; }
|
||||
#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
|
||||
|
||||
#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
|
||||
#TrivialReporter a:visited, #TrivialReporter a { color: #303; }
|
||||
#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
|
||||
#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
|
||||
#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
|
||||
#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
|
||||
#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
|
||||
#TrivialReporter .runner.running { background-color: yellow; }
|
||||
#TrivialReporter .options { text-align: right; font-size: .8em; }
|
||||
#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
|
||||
#TrivialReporter .suite .suite { margin: 5px; }
|
||||
#TrivialReporter .suite.passed { background-color: #dfd; }
|
||||
#TrivialReporter .suite.failed { background-color: #fdd; }
|
||||
#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
|
||||
#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
|
||||
#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
|
||||
#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
|
||||
#TrivialReporter .spec.skipped { background-color: #bbb; }
|
||||
#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
|
||||
#TrivialReporter .passed { background-color: #cfc; display: none; }
|
||||
#TrivialReporter .failed { background-color: #fbb; }
|
||||
#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
|
||||
#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
|
||||
#TrivialReporter .resultMessage .mismatch { color: black; }
|
||||
#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
|
||||
#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
|
||||
#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
|
||||
#TrivialReporter #jasmine_content { position: fixed; right: 100%; }
|
||||
#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }
|
||||
File diff suppressed because it is too large
Load Diff
BIN
test/autotest/pages/.DS_Store
vendored
BIN
test/autotest/pages/.DS_Store
vendored
Binary file not shown.
@@ -1,71 +0,0 @@
|
||||
<!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>
|
||||
<title>Cordova: Camera API Specs</title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
|
||||
|
||||
<!-- Load jasmine -->
|
||||
<link href="../jasmine.css" rel="stylesheet"/>
|
||||
<script type="text/javascript" src="../jasmine.js"></script>
|
||||
<script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
|
||||
<script type="text/javascript" src="../html/HtmlReporter.js"></script>
|
||||
<script type="text/javascript" src="../html/ReporterView.js"></script>
|
||||
<script type="text/javascript" src="../html/SpecView.js"></script>
|
||||
<script type="text/javascript" src="../html/SuiteView.js"></script>
|
||||
<script type="text/javascript" src="../html/TrivialReporter.js"></script>
|
||||
|
||||
<!-- Source -->
|
||||
<script type="text/javascript" src="../../cordova-incl.js"></script>
|
||||
|
||||
<!-- Load Test Runner -->
|
||||
<script type="text/javascript" src="../test-runner.js"></script>
|
||||
|
||||
<!-- Tests -->
|
||||
<script type="text/javascript" src="../tests/camera.tests.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('deviceready', function () {
|
||||
var jasmineEnv = jasmine.getEnv();
|
||||
jasmineEnv.updateInterval = 1000;
|
||||
|
||||
var htmlReporter = new jasmine.HtmlReporter();
|
||||
|
||||
jasmineEnv.addReporter(htmlReporter);
|
||||
|
||||
jasmineEnv.specFilter = function(spec) {
|
||||
return htmlReporter.specFilter(spec);
|
||||
};
|
||||
|
||||
jasmineEnv.execute();
|
||||
}, false);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a href="javascript:" class="backBtn" onclick="backHome();">Back</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,62 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
if (window.sessionStorage != null) {
|
||||
window.sessionStorage.clear();
|
||||
}
|
||||
|
||||
// Timeout is 2 seconds to allow physical devices enough
|
||||
// time to query the response. This is important for some
|
||||
// Android devices.
|
||||
var Tests = function() {};
|
||||
Tests.TEST_TIMEOUT = 7500;
|
||||
|
||||
// Creates a spy that will fail if called.
|
||||
function createDoNotCallSpy(name, opt_extraMessage) {
|
||||
return jasmine.createSpy().andCallFake(function() {
|
||||
var errorMessage = name + ' should not have been called.';
|
||||
if (arguments.length) {
|
||||
errorMessage += ' Got args: ' + JSON.stringify(arguments);
|
||||
}
|
||||
if (opt_extraMessage) {
|
||||
errorMessage += '\n' + opt_extraMessage;
|
||||
}
|
||||
expect(false).toBe(true, errorMessage);
|
||||
});
|
||||
}
|
||||
|
||||
// Waits for any of the given spys to be called.
|
||||
// Last param may be a custom timeout duration.
|
||||
function waitsForAny() {
|
||||
var spys = [].slice.call(arguments);
|
||||
var timeout = Tests.TEST_TIMEOUT;
|
||||
if (typeof spys[spys.length - 1] == 'number') {
|
||||
timeout = spys.pop();
|
||||
}
|
||||
waitsFor(function() {
|
||||
for (var i = 0; i < spys.length; ++i) {
|
||||
if (spys[i].wasCalled) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}, "Expecting callbacks to be called.", timeout);
|
||||
}
|
||||
BIN
test/autotest/tests/.DS_Store
vendored
BIN
test/autotest/tests/.DS_Store
vendored
Binary file not shown.
@@ -1,70 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('Camera (navigator.camera)', function () {
|
||||
it("should exist", function() {
|
||||
expect(navigator.camera).toBeDefined();
|
||||
});
|
||||
|
||||
it("should contain a getPicture function", function() {
|
||||
expect(navigator.camera.getPicture).toBeDefined();
|
||||
expect(typeof navigator.camera.getPicture == 'function').toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Camera Constants (window.Camera + navigator.camera)', function () {
|
||||
it("camera.spec.1 window.Camera should exist", function() {
|
||||
expect(window.Camera).toBeDefined();
|
||||
});
|
||||
|
||||
it("camera.spec.2 should contain three DestinationType constants", function() {
|
||||
expect(Camera.DestinationType.DATA_URL).toBe(0);
|
||||
expect(Camera.DestinationType.FILE_URI).toBe(1);
|
||||
expect(Camera.DestinationType.NATIVE_URI).toBe(2);
|
||||
expect(navigator.camera.DestinationType.DATA_URL).toBe(0);
|
||||
expect(navigator.camera.DestinationType.FILE_URI).toBe(1);
|
||||
expect(navigator.camera.DestinationType.NATIVE_URI).toBe(2);
|
||||
});
|
||||
|
||||
it("camera.spec.3 should contain two EncodingType constants", function() {
|
||||
expect(Camera.EncodingType.JPEG).toBe(0);
|
||||
expect(Camera.EncodingType.PNG).toBe(1);
|
||||
expect(navigator.camera.EncodingType.JPEG).toBe(0);
|
||||
expect(navigator.camera.EncodingType.PNG).toBe(1);
|
||||
});
|
||||
|
||||
it("camera.spec.4 should contain three MediaType constants", function() {
|
||||
expect(Camera.MediaType.PICTURE).toBe(0);
|
||||
expect(Camera.MediaType.VIDEO).toBe(1);
|
||||
expect(Camera.MediaType.ALLMEDIA).toBe(2);
|
||||
expect(navigator.camera.MediaType.PICTURE).toBe(0);
|
||||
expect(navigator.camera.MediaType.VIDEO).toBe(1);
|
||||
expect(navigator.camera.MediaType.ALLMEDIA).toBe(2);
|
||||
});
|
||||
it("camera.spec.5 should contain three PictureSourceType constants", function() {
|
||||
expect(Camera.PictureSourceType.PHOTOLIBRARY).toBe(0);
|
||||
expect(Camera.PictureSourceType.CAMERA).toBe(1);
|
||||
expect(Camera.PictureSourceType.SAVEDPHOTOALBUM).toBe(2);
|
||||
expect(navigator.camera.PictureSourceType.PHOTOLIBRARY).toBe(0);
|
||||
expect(navigator.camera.PictureSourceType.CAMERA).toBe(1);
|
||||
expect(navigator.camera.PictureSourceType.SAVEDPHOTOALBUM).toBe(2);
|
||||
});
|
||||
});
|
||||
@@ -1,394 +0,0 @@
|
||||
<!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 = null;
|
||||
var CameraPopoverOptions = null;
|
||||
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;
|
||||
platformId = cordova.require('cordova/platform').id;
|
||||
CameraPopoverOptions = cordova.require('org.apache.cordova.core.camera.CameraPopoverOptions');
|
||||
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>
|
||||
70
test/cordova-incl.js
vendored
70
test/cordova-incl.js
vendored
@@ -1,70 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
var PLAT;
|
||||
if (/Android/.exec(navigator.userAgent)) {
|
||||
PLAT = 'android';
|
||||
} else if (/(iPad)|(iPhone)|(iPod)/.exec(navigator.userAgent)) {
|
||||
PLAT = 'ios';
|
||||
} else if (/(BB10)|(PlayBook)|(BlackBerry)/.exec(navigator.userAgent)) {
|
||||
PLAT = 'blackberry';
|
||||
}
|
||||
|
||||
var scripts = document.getElementsByTagName('script');
|
||||
var currentPath = scripts[scripts.length - 1].src;
|
||||
var platformCordovaPath = currentPath.replace("cordova-incl.js", "cordova." + PLAT + ".js");
|
||||
var normalCordovaPath = currentPath.replace("cordova-incl.js", "cordova.js");
|
||||
var cordovaPath = normalCordovaPath;
|
||||
|
||||
if (PLAT) {
|
||||
// XHR to local file is an error on some platforms, windowsphone for one
|
||||
try {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", platformCordovaPath, false);
|
||||
xhr.onreadystatechange = function() {
|
||||
|
||||
if (this.readyState == this.DONE && this.responseText.length > 0) {
|
||||
if(parseInt(this.status) >= 400){
|
||||
cordovaPath = normalCordovaPath;
|
||||
}else{
|
||||
cordovaPath = platformCordovaPath;
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send(null);
|
||||
}
|
||||
catch(e){
|
||||
cordovaPath = normalCordovaPath;
|
||||
} // access denied!
|
||||
}
|
||||
|
||||
if (!window._doNotWriteCordovaScript) {
|
||||
document.write('<script type="text/javascript" charset="utf-8" src="' + cordovaPath + '"></script>');
|
||||
}
|
||||
|
||||
function backHome() {
|
||||
if (window.device && device.platform && device.platform.toLowerCase() == 'android') {
|
||||
navigator.app.backHistory();
|
||||
}
|
||||
else {
|
||||
window.history.go(-1);
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
<!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,initial-scale=1.0" />
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
<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" src="main.js"></script>
|
||||
|
||||
</head>
|
||||
<body onload="init();" id="stage" class="theme">
|
||||
<h1>Apache Cordova Tests</h1>
|
||||
<div id="info">
|
||||
<h4>Platform: <span id="platform"> </span></h4>
|
||||
<h4>Version: <span id="version"> </span></h4>
|
||||
<h4>UUID: <span id="uuid"> </span></h4>
|
||||
<h4>Name: <span id="name"> </span></h4>
|
||||
<h4>Model: <span id="model"> </span></h4>
|
||||
<h4>Width: <span id="width"> </span>, Height: <span id="height">
|
||||
</span>, Color Depth: <span id="colorDepth"></span></h4>
|
||||
<h4>User-Agent: <span id="user-agent"> </span></h4>
|
||||
</div>
|
||||
<a href="autotest/index.html" class="btn large">Automatic Test</a>
|
||||
<a href="accelerometer/index.html" class="btn large">Accelerometer</a>
|
||||
<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="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>
|
||||
<a href="location/index.html" class="btn large">Location</a>
|
||||
<a href="lazyloadjs/index.html" class="btn large">Lazy Loading of cordova-incl.js</a>
|
||||
<a href="misc/index.html" class="btn large">Misc Content</a>
|
||||
<a href="network/index.html" class="btn large">Network</a>
|
||||
<a href="notification/index.html" class="btn large">Notification</a>
|
||||
<a href="splashscreen/index.html" class="btn large">Splashscreen</a>
|
||||
<a href="sql/index.html" class="btn large">Web SQL</a>
|
||||
<a href="storage/index.html" class="btn large">Local Storage</a>
|
||||
<a href="benchmarks/index.html" class="btn large">Benchmarks</a>
|
||||
<a href="inappbrowser/index.html" class="btn large">In App Browser</a>
|
||||
</body>
|
||||
</html>
|
||||
163
test/main.js
163
test/main.js
@@ -1,163 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
var deviceInfo = function() {
|
||||
document.getElementById("platform").innerHTML = device.platform;
|
||||
document.getElementById("version").innerHTML = device.version;
|
||||
document.getElementById("uuid").innerHTML = device.uuid;
|
||||
document.getElementById("name").innerHTML = device.name;
|
||||
document.getElementById("model").innerHTML = device.model;
|
||||
document.getElementById("width").innerHTML = screen.width;
|
||||
document.getElementById("height").innerHTML = screen.height;
|
||||
document.getElementById("colorDepth").innerHTML = screen.colorDepth;
|
||||
};
|
||||
|
||||
var getLocation = function() {
|
||||
var suc = function(p) {
|
||||
alert(p.coords.latitude + " " + p.coords.longitude);
|
||||
};
|
||||
var locFail = function() {
|
||||
};
|
||||
navigator.geolocation.getCurrentPosition(suc, locFail);
|
||||
};
|
||||
|
||||
var beep = function() {
|
||||
navigator.notification.beep(2);
|
||||
};
|
||||
|
||||
var vibrate = function() {
|
||||
navigator.notification.vibrate(0);
|
||||
};
|
||||
|
||||
function roundNumber(num) {
|
||||
var dec = 3;
|
||||
var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
|
||||
return result;
|
||||
}
|
||||
|
||||
var accelerationWatch = null;
|
||||
|
||||
function updateAcceleration(a) {
|
||||
document.getElementById('x').innerHTML = roundNumber(a.x);
|
||||
document.getElementById('y').innerHTML = roundNumber(a.y);
|
||||
document.getElementById('z').innerHTML = roundNumber(a.z);
|
||||
}
|
||||
|
||||
var toggleAccel = function() {
|
||||
if (accelerationWatch !== null) {
|
||||
navigator.accelerometer.clearWatch(accelerationWatch);
|
||||
updateAcceleration({
|
||||
x : "",
|
||||
y : "",
|
||||
z : ""
|
||||
});
|
||||
accelerationWatch = null;
|
||||
} else {
|
||||
var options = {};
|
||||
options.frequency = 1000;
|
||||
accelerationWatch = navigator.accelerometer.watchAcceleration(
|
||||
updateAcceleration, function(ex) {
|
||||
alert("accel fail (" + ex.name + ": " + ex.message + ")");
|
||||
}, options);
|
||||
}
|
||||
};
|
||||
|
||||
var preventBehavior = function(e) {
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
function dump_pic(data) {
|
||||
var viewport = document.getElementById('viewport');
|
||||
console.log(data);
|
||||
viewport.style.display = "";
|
||||
viewport.style.position = "absolute";
|
||||
viewport.style.top = "10px";
|
||||
viewport.style.left = "10px";
|
||||
document.getElementById("test_img").src = "data:image/jpeg;base64," + data;
|
||||
}
|
||||
|
||||
function fail(msg) {
|
||||
alert(msg);
|
||||
}
|
||||
|
||||
function show_pic() {
|
||||
navigator.camera.getPicture(dump_pic, fail, {
|
||||
quality : 50
|
||||
});
|
||||
}
|
||||
|
||||
function close() {
|
||||
var viewport = document.getElementById('viewport');
|
||||
viewport.style.position = "relative";
|
||||
viewport.style.display = "none";
|
||||
}
|
||||
|
||||
// This is just to do this.
|
||||
function readFile() {
|
||||
navigator.file.read('/sdcard/cordova.txt', fail, fail);
|
||||
}
|
||||
|
||||
function writeFile() {
|
||||
navigator.file.write('foo.txt', "This is a test of writing to a file",
|
||||
fail, fail);
|
||||
}
|
||||
|
||||
function contacts_success(contacts) {
|
||||
alert(contacts.length
|
||||
+ ' contacts returned.'
|
||||
+ (contacts[2] && contacts[2].name ? (' Third contact is ' + contacts[2].name.formatted)
|
||||
: ''));
|
||||
}
|
||||
|
||||
function get_contacts() {
|
||||
var obj = new ContactFindOptions();
|
||||
obj.filter = "";
|
||||
obj.multiple = true;
|
||||
obj.limit = 5;
|
||||
navigator.service.contacts.find(
|
||||
[ "displayName", "name" ], contacts_success,
|
||||
fail, obj);
|
||||
}
|
||||
|
||||
var networkReachableCallback = function(reachability) {
|
||||
// There is no consistency on the format of reachability
|
||||
var networkState = reachability.code || reachability;
|
||||
|
||||
var currentState = {};
|
||||
currentState[NetworkStatus.NOT_REACHABLE] = 'No network connection';
|
||||
currentState[NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK] = 'Carrier data connection';
|
||||
currentState[NetworkStatus.REACHABLE_VIA_WIFI_NETWORK] = 'WiFi connection';
|
||||
|
||||
confirm("Connection type:\n" + currentState[networkState]);
|
||||
};
|
||||
|
||||
function check_network() {
|
||||
navigator.network.isReachable("www.mobiledevelopersolutions.com",
|
||||
networkReachableCallback, {});
|
||||
}
|
||||
|
||||
function init() {
|
||||
// the next line makes it impossible to see Contacts on the HTC Evo since it
|
||||
// doesn't have a scroll button
|
||||
// document.addEventListener("touchmove", preventBehavior, false);
|
||||
document.addEventListener("deviceready", deviceInfo, true);
|
||||
document.getElementById("user-agent").textContent = navigator.userAgent;
|
||||
}
|
||||
164
test/master.css
164
test/master.css
@@ -1,164 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
body {
|
||||
background:#222 none repeat scroll 0 0;
|
||||
color:#666;
|
||||
font-family:Helvetica;
|
||||
font-size:72%;
|
||||
line-height:1.5em;
|
||||
margin:0;
|
||||
border-top:1px solid #393939;
|
||||
}
|
||||
|
||||
#info{
|
||||
background:#ffa;
|
||||
border: 1px solid #ffd324;
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
clear:both;
|
||||
margin:15px 6px 0;
|
||||
min-width:295px;
|
||||
max-width:97%;
|
||||
padding:4px 0px 2px 10px;
|
||||
word-wrap:break-word;
|
||||
margin-bottom:10px;
|
||||
display:inline-block;
|
||||
min-height: 160px;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
#info > h4{
|
||||
font-size:.95em;
|
||||
margin:5px 0;
|
||||
}
|
||||
|
||||
#stage.theme{
|
||||
padding-top:3px;
|
||||
}
|
||||
|
||||
/* Definition List */
|
||||
#stage.theme > dl{
|
||||
padding-top:10px;
|
||||
clear:both;
|
||||
margin:0;
|
||||
list-style-type:none;
|
||||
padding-left:10px;
|
||||
overflow:auto;
|
||||
}
|
||||
|
||||
#stage.theme > dl > dt{
|
||||
font-weight:bold;
|
||||
float:left;
|
||||
margin-left:5px;
|
||||
}
|
||||
|
||||
#stage.theme > dl > dd{
|
||||
width:45px;
|
||||
float:left;
|
||||
color:#a87;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
/* Content Styling */
|
||||
#stage.theme > h1, #stage.theme > h2, #stage.theme > p{
|
||||
margin:1em 0 .5em 13px;
|
||||
}
|
||||
|
||||
#stage.theme > h1{
|
||||
color:#eee;
|
||||
font-size:1.6em;
|
||||
text-align:center;
|
||||
margin:0;
|
||||
margin-top:15px;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
#stage.theme > h2{
|
||||
clear:both;
|
||||
margin:0;
|
||||
padding:3px;
|
||||
font-size:1em;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
/* Stage Buttons */
|
||||
#stage.theme .btn{
|
||||
border: 1px solid #555;
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
text-align:center;
|
||||
display:inline-block;
|
||||
background:#444;
|
||||
width:150px;
|
||||
color:#9ab;
|
||||
font-size:1.1em;
|
||||
text-decoration:none;
|
||||
padding:1.2em 0;
|
||||
margin:3px 0px 3px 5px;
|
||||
}
|
||||
|
||||
#stage.theme .large{
|
||||
width:308px;
|
||||
padding:1.2em 0;
|
||||
}
|
||||
|
||||
#stage.theme .wide{
|
||||
width:100%;
|
||||
padding:1.2em 0;
|
||||
}
|
||||
|
||||
#stage.theme .backBtn{
|
||||
border: 1px solid #555;
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
text-align:center;
|
||||
display:block;
|
||||
float:right;
|
||||
background:#666;
|
||||
width:75px;
|
||||
color:#9ab;
|
||||
font-size:1.1em;
|
||||
text-decoration:none;
|
||||
padding:1.2em 0;
|
||||
margin:3px 5px 3px 5px;
|
||||
}
|
||||
|
||||
#stage.theme .input{
|
||||
border: 1px solid #555;
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
text-align:center;
|
||||
display:block;
|
||||
float:light;
|
||||
background:#888;
|
||||
color:#9cd;
|
||||
font-size:1.1em;
|
||||
text-decoration:none;
|
||||
padding:1.2em 0;
|
||||
margin:3px 0px 3px 5px;
|
||||
}
|
||||
|
||||
#stage.theme .numeric{
|
||||
width:100%;
|
||||
}
|
||||
1
tests/ios/.gitignore
vendored
Normal file
1
tests/ios/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
node_modules
|
||||
7
tests/ios/CDVCameraTest.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
tests/ios/CDVCameraTest.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "container:CDVCameraTest/CDVCameraTest.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
|
||||
<false/>
|
||||
<key>IDESourceControlProjectIdentifier</key>
|
||||
<string>6BE9AD73-1B9F-4362-98D7-DC631BEC6185</string>
|
||||
<key>IDESourceControlProjectName</key>
|
||||
<string>CDVCameraTest</string>
|
||||
<key>IDESourceControlProjectOriginsDictionary</key>
|
||||
<dict>
|
||||
<key>729B5706E7BAF4E9EE7AEE3C003A08107411AB7C</key>
|
||||
<string>github.com:shazron/cordova-plugin-camera.git</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectPath</key>
|
||||
<string>tests/ios/CDVCameraTest.xcworkspace</string>
|
||||
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
|
||||
<dict>
|
||||
<key>729B5706E7BAF4E9EE7AEE3C003A08107411AB7C</key>
|
||||
<string>../../..</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectURL</key>
|
||||
<string>github.com:shazron/cordova-plugin-camera.git</string>
|
||||
<key>IDESourceControlProjectVersion</key>
|
||||
<integer>111</integer>
|
||||
<key>IDESourceControlProjectWCCIdentifier</key>
|
||||
<string>729B5706E7BAF4E9EE7AEE3C003A08107411AB7C</string>
|
||||
<key>IDESourceControlProjectWCConfigurations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||
<string>public.vcs.git</string>
|
||||
<key>IDESourceControlWCCIdentifierKey</key>
|
||||
<string>729B5706E7BAF4E9EE7AEE3C003A08107411AB7C</string>
|
||||
<key>IDESourceControlWCCName</key>
|
||||
<string>cordova-plugin-camera</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0610"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D2AAC07D0554694100DB518D"
|
||||
BuildableName = "libCordova.a"
|
||||
BlueprintName = "CordovaLib"
|
||||
ReferencedContainer = "container:node_modules/cordova-ios/CordovaLib/CordovaLib.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D2AAC07D0554694100DB518D"
|
||||
BuildableName = "libCordova.a"
|
||||
BlueprintName = "CordovaLib"
|
||||
ReferencedContainer = "container:node_modules/cordova-ios/CordovaLib/CordovaLib.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D2AAC07D0554694100DB518D"
|
||||
BuildableName = "libCordova.a"
|
||||
BlueprintName = "CordovaLib"
|
||||
ReferencedContainer = "container:node_modules/cordova-ios/CordovaLib/CordovaLib.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
498
tests/ios/CDVCameraTest/CDVCameraLibTests/CameraTest.m
Normal file
498
tests/ios/CDVCameraTest/CDVCameraLibTests/CameraTest.m
Normal file
@@ -0,0 +1,498 @@
|
||||
/*
|
||||
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 <UIKit/UIKit.h>
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "CDVCamera.h"
|
||||
#import "UIImage+CropScaleOrientation.h"
|
||||
#import <Cordova/NSArray+Comparisons.h>
|
||||
#import <Cordova/NSData+Base64.h>
|
||||
#import <Cordova/NSDictionary+Extensions.h>
|
||||
#import <MobileCoreServices/UTCoreTypes.h>
|
||||
|
||||
|
||||
@interface CameraTest : XCTestCase
|
||||
|
||||
@property (nonatomic, strong) CDVCamera* plugin;
|
||||
|
||||
@end
|
||||
|
||||
@interface CDVCamera ()
|
||||
|
||||
// expose private interface
|
||||
- (NSData*)processImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPictureOptions*)options;
|
||||
- (UIImage*)retrieveImage:(NSDictionary*)info options:(CDVPictureOptions*)options;
|
||||
- (CDVPluginResult*)resultForImage:(CDVPictureOptions*)options info:(NSDictionary*)info;
|
||||
- (CDVPluginResult*)resultForVideo:(NSDictionary*)info;
|
||||
|
||||
@end
|
||||
|
||||
@implementation CameraTest
|
||||
|
||||
- (void)setUp {
|
||||
[super setUp];
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
|
||||
self.plugin = [[CDVCamera alloc] init];
|
||||
}
|
||||
|
||||
- (void)tearDown {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void) testPictureOptionsCreate
|
||||
{
|
||||
NSArray* args;
|
||||
CDVPictureOptions* options;
|
||||
NSDictionary* popoverOptions;
|
||||
|
||||
// No arguments, check whether the defaults are set
|
||||
args = @[];
|
||||
options = [CDVPictureOptions createFromTakePictureArguments:args];
|
||||
|
||||
XCTAssertEqual([options.quality intValue], 50);
|
||||
XCTAssertEqual(options.destinationType, (int)DestinationTypeFileUri);
|
||||
XCTAssertEqual(options.sourceType, (int)UIImagePickerControllerSourceTypeCamera);
|
||||
XCTAssertEqual(options.targetSize.width, 0);
|
||||
XCTAssertEqual(options.targetSize.height, 0);
|
||||
XCTAssertEqual(options.encodingType, (int)EncodingTypeJPEG);
|
||||
XCTAssertEqual(options.mediaType, (int)MediaTypePicture);
|
||||
XCTAssertEqual(options.allowsEditing, NO);
|
||||
XCTAssertEqual(options.correctOrientation, NO);
|
||||
XCTAssertEqual(options.saveToPhotoAlbum, NO);
|
||||
XCTAssertEqualObjects(options.popoverOptions, nil);
|
||||
XCTAssertEqual(options.cameraDirection, (int)UIImagePickerControllerCameraDeviceRear);
|
||||
XCTAssertEqual(options.popoverSupported, NO);
|
||||
XCTAssertEqual(options.usesGeolocation, NO);
|
||||
|
||||
// Set each argument, check whether they are set. different from defaults
|
||||
popoverOptions = @{ @"x" : @1, @"y" : @2, @"width" : @3, @"height" : @4 };
|
||||
|
||||
args = @[
|
||||
@(49),
|
||||
@(DestinationTypeDataUrl),
|
||||
@(UIImagePickerControllerSourceTypePhotoLibrary),
|
||||
@(120),
|
||||
@(240),
|
||||
@(EncodingTypePNG),
|
||||
@(MediaTypeVideo),
|
||||
@YES,
|
||||
@YES,
|
||||
@YES,
|
||||
popoverOptions,
|
||||
@(UIImagePickerControllerCameraDeviceFront),
|
||||
];
|
||||
options = [CDVPictureOptions createFromTakePictureArguments:args];
|
||||
|
||||
XCTAssertEqual([options.quality intValue], 49);
|
||||
XCTAssertEqual(options.destinationType, (int)DestinationTypeDataUrl);
|
||||
XCTAssertEqual(options.sourceType, (int)UIImagePickerControllerSourceTypePhotoLibrary);
|
||||
XCTAssertEqual(options.targetSize.width, 120);
|
||||
XCTAssertEqual(options.targetSize.height, 240);
|
||||
XCTAssertEqual(options.encodingType, (int)EncodingTypePNG);
|
||||
XCTAssertEqual(options.mediaType, (int)MediaTypeVideo);
|
||||
XCTAssertEqual(options.allowsEditing, YES);
|
||||
XCTAssertEqual(options.correctOrientation, YES);
|
||||
XCTAssertEqual(options.saveToPhotoAlbum, YES);
|
||||
XCTAssertEqualObjects(options.popoverOptions, popoverOptions);
|
||||
XCTAssertEqual(options.cameraDirection, (int)UIImagePickerControllerCameraDeviceFront);
|
||||
XCTAssertEqual(options.popoverSupported, NO);
|
||||
XCTAssertEqual(options.usesGeolocation, NO);
|
||||
}
|
||||
|
||||
- (void) testCameraPickerCreate
|
||||
{
|
||||
NSDictionary* popoverOptions;
|
||||
NSArray* args;
|
||||
CDVPictureOptions* pictureOptions;
|
||||
CDVCameraPicker* picker;
|
||||
|
||||
// Souce is Camera, and image type
|
||||
|
||||
popoverOptions = @{ @"x" : @1, @"y" : @2, @"width" : @3, @"height" : @4 };
|
||||
args = @[
|
||||
@(49),
|
||||
@(DestinationTypeDataUrl),
|
||||
@(UIImagePickerControllerSourceTypeCamera),
|
||||
@(120),
|
||||
@(240),
|
||||
@(EncodingTypePNG),
|
||||
@(MediaTypeAll),
|
||||
@YES,
|
||||
@YES,
|
||||
@YES,
|
||||
popoverOptions,
|
||||
@(UIImagePickerControllerCameraDeviceFront),
|
||||
];
|
||||
pictureOptions = [CDVPictureOptions createFromTakePictureArguments:args];
|
||||
|
||||
if ([UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType]) {
|
||||
picker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
||||
|
||||
XCTAssertEqualObjects(picker.pictureOptions, pictureOptions);
|
||||
|
||||
XCTAssertEqual(picker.sourceType, pictureOptions.sourceType);
|
||||
XCTAssertEqual(picker.allowsEditing, pictureOptions.allowsEditing);
|
||||
XCTAssertEqualObjects(picker.mediaTypes, @[(NSString*)kUTTypeImage]);
|
||||
XCTAssertEqual(picker.cameraDevice, pictureOptions.cameraDirection);
|
||||
}
|
||||
|
||||
// Souce is not Camera, and all media types
|
||||
|
||||
args = @[
|
||||
@(49),
|
||||
@(DestinationTypeDataUrl),
|
||||
@(UIImagePickerControllerSourceTypePhotoLibrary),
|
||||
@(120),
|
||||
@(240),
|
||||
@(EncodingTypePNG),
|
||||
@(MediaTypeAll),
|
||||
@YES,
|
||||
@YES,
|
||||
@YES,
|
||||
popoverOptions,
|
||||
@(UIImagePickerControllerCameraDeviceFront),
|
||||
];
|
||||
pictureOptions = [CDVPictureOptions createFromTakePictureArguments:args];
|
||||
|
||||
if ([UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType]) {
|
||||
picker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
||||
|
||||
XCTAssertEqualObjects(picker.pictureOptions, pictureOptions);
|
||||
|
||||
XCTAssertEqual(picker.sourceType, pictureOptions.sourceType);
|
||||
XCTAssertEqual(picker.allowsEditing, pictureOptions.allowsEditing);
|
||||
XCTAssertEqualObjects(picker.mediaTypes, [UIImagePickerController availableMediaTypesForSourceType:picker.sourceType]);
|
||||
}
|
||||
|
||||
// Souce is not Camera, and either Image or Movie media type
|
||||
|
||||
args = @[
|
||||
@(49),
|
||||
@(DestinationTypeDataUrl),
|
||||
@(UIImagePickerControllerSourceTypePhotoLibrary),
|
||||
@(120),
|
||||
@(240),
|
||||
@(EncodingTypePNG),
|
||||
@(MediaTypeVideo),
|
||||
@YES,
|
||||
@YES,
|
||||
@YES,
|
||||
popoverOptions,
|
||||
@(UIImagePickerControllerCameraDeviceFront),
|
||||
];
|
||||
pictureOptions = [CDVPictureOptions createFromTakePictureArguments:args];
|
||||
|
||||
if ([UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType]) {
|
||||
picker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
||||
|
||||
XCTAssertEqualObjects(picker.pictureOptions, pictureOptions);
|
||||
|
||||
XCTAssertEqual(picker.sourceType, pictureOptions.sourceType);
|
||||
XCTAssertEqual(picker.allowsEditing, pictureOptions.allowsEditing);
|
||||
XCTAssertEqualObjects(picker.mediaTypes, @[(NSString*)kUTTypeMovie]);
|
||||
}
|
||||
}
|
||||
|
||||
- (UIImage*) createImage:(CGRect)rect orientation:(UIImageOrientation)imageOrientation {
|
||||
UIGraphicsBeginImageContext(rect.size);
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
CGContextSetFillColorWithColor(context, [[UIColor greenColor] CGColor]);
|
||||
CGContextFillRect(context, rect);
|
||||
|
||||
CGImageRef result = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext());
|
||||
UIImage* image = [UIImage imageWithCGImage:result scale:1.0f orientation:imageOrientation];
|
||||
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
- (void) testImageScaleCropForSize {
|
||||
|
||||
UIImage *sourceImagePortrait, *sourceImageLandscape, *targetImage;
|
||||
CGSize targetSize = CGSizeZero;
|
||||
|
||||
sourceImagePortrait = [self createImage:CGRectMake(0, 0, 2448, 3264) orientation:UIImageOrientationUp];
|
||||
sourceImageLandscape = [self createImage:CGRectMake(0, 0, 3264, 2448) orientation:UIImageOrientationUp];
|
||||
|
||||
// test 640x480
|
||||
|
||||
targetSize = CGSizeMake(640, 480);
|
||||
|
||||
targetImage = [sourceImagePortrait imageByScalingAndCroppingForSize:targetSize];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
|
||||
targetImage = [sourceImageLandscape imageByScalingAndCroppingForSize:targetSize];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
|
||||
|
||||
// test 800x600
|
||||
|
||||
targetSize = CGSizeMake(800, 600);
|
||||
|
||||
targetImage = [sourceImagePortrait imageByScalingAndCroppingForSize:targetSize];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
|
||||
targetImage = [sourceImageLandscape imageByScalingAndCroppingForSize:targetSize];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
|
||||
// test 1024x768
|
||||
|
||||
targetSize = CGSizeMake(1024, 768);
|
||||
|
||||
targetImage = [sourceImagePortrait imageByScalingAndCroppingForSize:targetSize];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
|
||||
targetImage = [sourceImageLandscape imageByScalingAndCroppingForSize:targetSize];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
}
|
||||
|
||||
- (void) testImageScaleNoCropForSize {
|
||||
UIImage *sourceImagePortrait, *sourceImageLandscape, *targetImage;
|
||||
CGSize targetSize = CGSizeZero;
|
||||
|
||||
sourceImagePortrait = [self createImage:CGRectMake(0, 0, 2448, 3264) orientation:UIImageOrientationUp];
|
||||
sourceImageLandscape = [self createImage:CGRectMake(0, 0, 3264, 2448) orientation:UIImageOrientationUp];
|
||||
|
||||
// test 640x480
|
||||
|
||||
targetSize = CGSizeMake(640, 480);
|
||||
|
||||
targetImage = [sourceImagePortrait imageByScalingNotCroppingForSize:targetSize];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
|
||||
targetImage = [sourceImageLandscape imageByScalingNotCroppingForSize:targetSize];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
|
||||
|
||||
// test 800x600
|
||||
|
||||
targetSize = CGSizeMake(800, 600);
|
||||
|
||||
targetImage = [sourceImagePortrait imageByScalingNotCroppingForSize:targetSize];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
|
||||
targetImage = [sourceImageLandscape imageByScalingNotCroppingForSize:targetSize];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
|
||||
// test 1024x768
|
||||
|
||||
targetSize = CGSizeMake(1024, 768);
|
||||
|
||||
targetImage = [sourceImagePortrait imageByScalingNotCroppingForSize:targetSize];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
|
||||
targetImage = [sourceImageLandscape imageByScalingNotCroppingForSize:targetSize];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
}
|
||||
|
||||
- (void) testImageCorrectedForOrientation {
|
||||
UIImage *sourceImagePortrait, *sourceImageLandscape, *targetImage;
|
||||
CGSize targetSize = CGSizeZero;
|
||||
|
||||
sourceImagePortrait = [self createImage:CGRectMake(0, 0, 2448, 3264) orientation:UIImageOrientationDown];
|
||||
sourceImageLandscape = [self createImage:CGRectMake(0, 0, 3264, 2448) orientation:UIImageOrientationDown];
|
||||
|
||||
// PORTRAIT - image size should be unchanged
|
||||
|
||||
targetSize = CGSizeMake(2448, 3264);
|
||||
|
||||
targetImage = [sourceImagePortrait imageCorrectedForCaptureOrientation:UIImageOrientationUp];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
XCTAssertEqual(targetImage.imageOrientation, UIImageOrientationUp);
|
||||
|
||||
targetImage = [sourceImagePortrait imageCorrectedForCaptureOrientation:UIImageOrientationDown];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
XCTAssertEqual(targetImage.imageOrientation, UIImageOrientationUp);
|
||||
|
||||
targetImage = [sourceImagePortrait imageCorrectedForCaptureOrientation:UIImageOrientationRight];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
XCTAssertEqual(targetImage.imageOrientation, UIImageOrientationUp);
|
||||
|
||||
targetImage = [sourceImagePortrait imageCorrectedForCaptureOrientation:UIImageOrientationLeft];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
XCTAssertEqual(targetImage.imageOrientation, UIImageOrientationUp);
|
||||
|
||||
// LANDSCAPE - image size should be unchanged
|
||||
|
||||
targetSize = CGSizeMake(3264, 2448);
|
||||
|
||||
targetImage = [sourceImageLandscape imageCorrectedForCaptureOrientation:UIImageOrientationUp];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
|
||||
targetImage = [sourceImageLandscape imageCorrectedForCaptureOrientation:UIImageOrientationDown];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
|
||||
targetImage = [sourceImageLandscape imageCorrectedForCaptureOrientation:UIImageOrientationRight];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
|
||||
targetImage = [sourceImageLandscape imageCorrectedForCaptureOrientation:UIImageOrientationLeft];
|
||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
}
|
||||
|
||||
|
||||
- (void) testRetrieveImage
|
||||
{
|
||||
CDVPictureOptions* pictureOptions = [[CDVPictureOptions alloc] init];
|
||||
NSDictionary *infoDict1, *infoDict2;
|
||||
UIImage* resultImage;
|
||||
|
||||
UIImage* originalImage = [self createImage:CGRectMake(0, 0, 1024, 768) orientation:UIImageOrientationDown];
|
||||
UIImage* originalCorrectedForOrientation = [originalImage imageCorrectedForCaptureOrientation];
|
||||
|
||||
UIImage* editedImage = [self createImage:CGRectMake(0, 0, 800, 600) orientation:UIImageOrientationDown];
|
||||
UIImage* scaledImageWithCrop = [originalImage imageByScalingAndCroppingForSize:CGSizeMake(640, 480)];
|
||||
UIImage* scaledImageNoCrop = [originalImage imageByScalingNotCroppingForSize:CGSizeMake(640, 480)];
|
||||
|
||||
infoDict1 = @{
|
||||
UIImagePickerControllerOriginalImage : originalImage
|
||||
};
|
||||
|
||||
infoDict2 = @{
|
||||
UIImagePickerControllerOriginalImage : originalImage,
|
||||
UIImagePickerControllerEditedImage : editedImage
|
||||
};
|
||||
|
||||
// Original with no options
|
||||
|
||||
pictureOptions.allowsEditing = YES;
|
||||
pictureOptions.targetSize = CGSizeZero;
|
||||
pictureOptions.cropToSize = NO;
|
||||
pictureOptions.correctOrientation = NO;
|
||||
|
||||
resultImage = [self.plugin retrieveImage:infoDict1 options:pictureOptions];
|
||||
XCTAssertEqualObjects(resultImage, originalImage);
|
||||
|
||||
// Original with no options
|
||||
|
||||
pictureOptions.allowsEditing = YES;
|
||||
pictureOptions.targetSize = CGSizeZero;
|
||||
pictureOptions.cropToSize = NO;
|
||||
pictureOptions.correctOrientation = NO;
|
||||
|
||||
resultImage = [self.plugin retrieveImage:infoDict2 options:pictureOptions];
|
||||
XCTAssertEqualObjects(resultImage, editedImage);
|
||||
|
||||
// Original with corrected orientation
|
||||
|
||||
pictureOptions.allowsEditing = YES;
|
||||
pictureOptions.targetSize = CGSizeZero;
|
||||
pictureOptions.cropToSize = NO;
|
||||
pictureOptions.correctOrientation = YES;
|
||||
|
||||
resultImage = [self.plugin retrieveImage:infoDict1 options:pictureOptions];
|
||||
XCTAssertNotEqual(resultImage.imageOrientation, originalImage.imageOrientation);
|
||||
XCTAssertEqual(resultImage.imageOrientation, originalCorrectedForOrientation.imageOrientation);
|
||||
XCTAssertEqual(resultImage.size.width, originalCorrectedForOrientation.size.width);
|
||||
XCTAssertEqual(resultImage.size.height, originalCorrectedForOrientation.size.height);
|
||||
|
||||
// Original with targetSize, no crop
|
||||
|
||||
pictureOptions.allowsEditing = YES;
|
||||
pictureOptions.targetSize = CGSizeMake(640, 480);
|
||||
pictureOptions.cropToSize = NO;
|
||||
pictureOptions.correctOrientation = NO;
|
||||
|
||||
resultImage = [self.plugin retrieveImage:infoDict1 options:pictureOptions];
|
||||
XCTAssertEqual(resultImage.size.width, scaledImageNoCrop.size.width);
|
||||
XCTAssertEqual(resultImage.size.height, scaledImageNoCrop.size.height);
|
||||
|
||||
// Original with targetSize, plus crop
|
||||
|
||||
pictureOptions.allowsEditing = YES;
|
||||
pictureOptions.targetSize = CGSizeMake(640, 480);
|
||||
pictureOptions.cropToSize = YES;
|
||||
pictureOptions.correctOrientation = NO;
|
||||
|
||||
resultImage = [self.plugin retrieveImage:infoDict1 options:pictureOptions];
|
||||
XCTAssertEqual(resultImage.size.width, scaledImageWithCrop.size.width);
|
||||
XCTAssertEqual(resultImage.size.height, scaledImageWithCrop.size.height);
|
||||
}
|
||||
|
||||
- (void) testProcessImage
|
||||
{
|
||||
CDVPictureOptions* pictureOptions = [[CDVPictureOptions alloc] init];
|
||||
NSData* resultData;
|
||||
|
||||
UIImage* originalImage = [self createImage:CGRectMake(0, 0, 1024, 768) orientation:UIImageOrientationDown];
|
||||
NSData* originalImageDataPNG = UIImagePNGRepresentation(originalImage);
|
||||
NSData* originalImageDataJPEG = UIImageJPEGRepresentation(originalImage, 1.0);
|
||||
|
||||
// Original, PNG
|
||||
|
||||
pictureOptions.allowsEditing = YES;
|
||||
pictureOptions.targetSize = CGSizeZero;
|
||||
pictureOptions.cropToSize = NO;
|
||||
pictureOptions.correctOrientation = NO;
|
||||
pictureOptions.encodingType = EncodingTypePNG;
|
||||
|
||||
resultData = [self.plugin processImage:originalImage info:@{} options:pictureOptions];
|
||||
XCTAssertEqualObjects([resultData base64EncodedString], [originalImageDataPNG base64EncodedString]);
|
||||
|
||||
// Original, JPEG, full quality
|
||||
|
||||
pictureOptions.allowsEditing = NO;
|
||||
pictureOptions.targetSize = CGSizeZero;
|
||||
pictureOptions.cropToSize = NO;
|
||||
pictureOptions.correctOrientation = NO;
|
||||
pictureOptions.encodingType = EncodingTypeJPEG;
|
||||
|
||||
resultData = [self.plugin processImage:originalImage info:@{} options:pictureOptions];
|
||||
XCTAssertEqualObjects([resultData base64EncodedString], [originalImageDataJPEG base64EncodedString]);
|
||||
|
||||
// Original, JPEG, with quality value
|
||||
|
||||
pictureOptions.allowsEditing = YES;
|
||||
pictureOptions.targetSize = CGSizeZero;
|
||||
pictureOptions.cropToSize = NO;
|
||||
pictureOptions.correctOrientation = NO;
|
||||
pictureOptions.encodingType = EncodingTypeJPEG;
|
||||
pictureOptions.quality = @(57);
|
||||
|
||||
NSData* originalImageDataJPEGWithQuality = UIImageJPEGRepresentation(originalImage, [pictureOptions.quality floatValue]/ 100.f);
|
||||
resultData = [self.plugin processImage:originalImage info:@{} options:pictureOptions];
|
||||
XCTAssertEqualObjects([resultData base64EncodedString], [originalImageDataJPEGWithQuality base64EncodedString]);
|
||||
|
||||
// TODO: usesGeolocation is not tested
|
||||
}
|
||||
|
||||
@end
|
||||
24
tests/ios/CDVCameraTest/CDVCameraLibTests/Info.plist
Normal file
24
tests/ios/CDVCameraTest/CDVCameraLibTests/Info.plist
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.apache.cordova.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
561
tests/ios/CDVCameraTest/CDVCameraTest.xcodeproj/project.pbxproj
Normal file
561
tests/ios/CDVCameraTest/CDVCameraTest.xcodeproj/project.pbxproj
Normal file
@@ -0,0 +1,561 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
30486FEB1A40DC350065C233 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30486FEA1A40DC350065C233 /* UIKit.framework */; };
|
||||
30486FED1A40DC3B0065C233 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30486FEC1A40DC3A0065C233 /* Foundation.framework */; };
|
||||
30486FF91A40DCC70065C233 /* CDVCamera.m in Sources */ = {isa = PBXBuildFile; fileRef = 30486FF31A40DCC70065C233 /* CDVCamera.m */; };
|
||||
30486FFA1A40DCC70065C233 /* CDVJpegHeaderWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 30486FF61A40DCC70065C233 /* CDVJpegHeaderWriter.m */; };
|
||||
30486FFB1A40DCC70065C233 /* UIImage+CropScaleOrientation.m in Sources */ = {isa = PBXBuildFile; fileRef = 30486FF81A40DCC70065C233 /* UIImage+CropScaleOrientation.m */; };
|
||||
304870011A40DD620065C233 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30486FFE1A40DD180065C233 /* CoreGraphics.framework */; };
|
||||
304870021A40DD860065C233 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30486FFE1A40DD180065C233 /* CoreGraphics.framework */; };
|
||||
304870031A40DD8C0065C233 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30486FEA1A40DC350065C233 /* UIKit.framework */; };
|
||||
304870051A40DD9A0065C233 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 304870041A40DD9A0065C233 /* MobileCoreServices.framework */; };
|
||||
304870071A40DDAC0065C233 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 304870061A40DDAC0065C233 /* AssetsLibrary.framework */; };
|
||||
304870091A40DDB90065C233 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 304870081A40DDB90065C233 /* CoreLocation.framework */; };
|
||||
3048700B1A40DDF30065C233 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3048700A1A40DDF30065C233 /* ImageIO.framework */; };
|
||||
308F59B11A4228730031A4D4 /* libCordova.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E9F519019DA0F8300DA31AC /* libCordova.a */; };
|
||||
7E9F51B119DA114400DA31AC /* CameraTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E9F51B019DA114400DA31AC /* CameraTest.m */; };
|
||||
7E9F51B919DA1B1600DA31AC /* libCDVCameraLib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E9F519519DA102000DA31AC /* libCDVCameraLib.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
30486FFC1A40DCE80065C233 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 7E9F518B19DA0F8300DA31AC /* CordovaLib.xcodeproj */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = D2AAC07D0554694100DB518D;
|
||||
remoteInfo = CordovaLib;
|
||||
};
|
||||
7E9F518F19DA0F8300DA31AC /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 7E9F518B19DA0F8300DA31AC /* CordovaLib.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 68A32D7114102E1C006B237C;
|
||||
remoteInfo = CordovaLib;
|
||||
};
|
||||
7E9F51AC19DA10DE00DA31AC /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 7E9F517219DA09CE00DA31AC /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 7E9F519419DA102000DA31AC;
|
||||
remoteInfo = CDVCameraLib;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
7E9F519319DA102000DA31AC /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "include/$(PRODUCT_NAME)";
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
30486FEA1A40DC350065C233 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
|
||||
30486FEC1A40DC3A0065C233 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||
30486FF21A40DCC70065C233 /* CDVCamera.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDVCamera.h; sourceTree = "<group>"; };
|
||||
30486FF31A40DCC70065C233 /* CDVCamera.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDVCamera.m; sourceTree = "<group>"; };
|
||||
30486FF41A40DCC70065C233 /* CDVExif.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDVExif.h; sourceTree = "<group>"; };
|
||||
30486FF51A40DCC70065C233 /* CDVJpegHeaderWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDVJpegHeaderWriter.h; sourceTree = "<group>"; };
|
||||
30486FF61A40DCC70065C233 /* CDVJpegHeaderWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDVJpegHeaderWriter.m; sourceTree = "<group>"; };
|
||||
30486FF71A40DCC70065C233 /* UIImage+CropScaleOrientation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+CropScaleOrientation.h"; sourceTree = "<group>"; };
|
||||
30486FF81A40DCC70065C233 /* UIImage+CropScaleOrientation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+CropScaleOrientation.m"; sourceTree = "<group>"; };
|
||||
30486FFE1A40DD180065C233 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; };
|
||||
304870041A40DD9A0065C233 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk/System/Library/Frameworks/MobileCoreServices.framework; sourceTree = DEVELOPER_DIR; };
|
||||
304870061A40DDAC0065C233 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk/System/Library/Frameworks/AssetsLibrary.framework; sourceTree = DEVELOPER_DIR; };
|
||||
304870081A40DDB90065C233 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk/System/Library/Frameworks/CoreLocation.framework; sourceTree = DEVELOPER_DIR; };
|
||||
3048700A1A40DDF30065C233 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk/System/Library/Frameworks/ImageIO.framework; sourceTree = DEVELOPER_DIR; };
|
||||
7E9F518B19DA0F8300DA31AC /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CordovaLib.xcodeproj; path = "../node_modules/cordova-ios/CordovaLib/CordovaLib.xcodeproj"; sourceTree = "<group>"; };
|
||||
7E9F519519DA102000DA31AC /* libCDVCameraLib.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCDVCameraLib.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7E9F519F19DA102000DA31AC /* CDVCameraLibTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CDVCameraLibTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7E9F51A219DA102000DA31AC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
7E9F51B019DA114400DA31AC /* CameraTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CameraTest.m; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
7E9F519219DA102000DA31AC /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
308F59B11A4228730031A4D4 /* libCordova.a in Frameworks */,
|
||||
304870011A40DD620065C233 /* CoreGraphics.framework in Frameworks */,
|
||||
30486FED1A40DC3B0065C233 /* Foundation.framework in Frameworks */,
|
||||
30486FEB1A40DC350065C233 /* UIKit.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
7E9F519C19DA102000DA31AC /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3048700B1A40DDF30065C233 /* ImageIO.framework in Frameworks */,
|
||||
304870091A40DDB90065C233 /* CoreLocation.framework in Frameworks */,
|
||||
304870071A40DDAC0065C233 /* AssetsLibrary.framework in Frameworks */,
|
||||
304870051A40DD9A0065C233 /* MobileCoreServices.framework in Frameworks */,
|
||||
304870031A40DD8C0065C233 /* UIKit.framework in Frameworks */,
|
||||
304870021A40DD860065C233 /* CoreGraphics.framework in Frameworks */,
|
||||
7E9F51B919DA1B1600DA31AC /* libCDVCameraLib.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
30486FF11A40DCC70065C233 /* CDVCameraLib */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
30486FF21A40DCC70065C233 /* CDVCamera.h */,
|
||||
30486FF31A40DCC70065C233 /* CDVCamera.m */,
|
||||
30486FF41A40DCC70065C233 /* CDVExif.h */,
|
||||
30486FF51A40DCC70065C233 /* CDVJpegHeaderWriter.h */,
|
||||
30486FF61A40DCC70065C233 /* CDVJpegHeaderWriter.m */,
|
||||
30486FF71A40DCC70065C233 /* UIImage+CropScaleOrientation.h */,
|
||||
30486FF81A40DCC70065C233 /* UIImage+CropScaleOrientation.m */,
|
||||
);
|
||||
name = CDVCameraLib;
|
||||
path = ../../../src/ios;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
308F59B01A4227A60031A4D4 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3048700A1A40DDF30065C233 /* ImageIO.framework */,
|
||||
304870081A40DDB90065C233 /* CoreLocation.framework */,
|
||||
304870061A40DDAC0065C233 /* AssetsLibrary.framework */,
|
||||
304870041A40DD9A0065C233 /* MobileCoreServices.framework */,
|
||||
30486FFE1A40DD180065C233 /* CoreGraphics.framework */,
|
||||
30486FEC1A40DC3A0065C233 /* Foundation.framework */,
|
||||
30486FEA1A40DC350065C233 /* UIKit.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7E9F517119DA09CE00DA31AC = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7E9F518B19DA0F8300DA31AC /* CordovaLib.xcodeproj */,
|
||||
308F59B01A4227A60031A4D4 /* Frameworks */,
|
||||
30486FF11A40DCC70065C233 /* CDVCameraLib */,
|
||||
7E9F51A019DA102000DA31AC /* CDVCameraLibTests */,
|
||||
7E9F517D19DA0A0A00DA31AC /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7E9F517D19DA0A0A00DA31AC /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7E9F519519DA102000DA31AC /* libCDVCameraLib.a */,
|
||||
7E9F519F19DA102000DA31AC /* CDVCameraLibTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7E9F518C19DA0F8300DA31AC /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7E9F519019DA0F8300DA31AC /* libCordova.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7E9F51A019DA102000DA31AC /* CDVCameraLibTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7E9F51A119DA102000DA31AC /* Supporting Files */,
|
||||
7E9F51B019DA114400DA31AC /* CameraTest.m */,
|
||||
);
|
||||
path = CDVCameraLibTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7E9F51A119DA102000DA31AC /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7E9F51A219DA102000DA31AC /* Info.plist */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
7E9F519419DA102000DA31AC /* CDVCameraLib */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 7E9F51A319DA102000DA31AC /* Build configuration list for PBXNativeTarget "CDVCameraLib" */;
|
||||
buildPhases = (
|
||||
7E9F519119DA102000DA31AC /* Sources */,
|
||||
7E9F519219DA102000DA31AC /* Frameworks */,
|
||||
7E9F519319DA102000DA31AC /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
30486FFD1A40DCE80065C233 /* PBXTargetDependency */,
|
||||
);
|
||||
name = CDVCameraLib;
|
||||
productName = CDVCameraLib;
|
||||
productReference = 7E9F519519DA102000DA31AC /* libCDVCameraLib.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
7E9F519E19DA102000DA31AC /* CDVCameraLibTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 7E9F51A619DA102000DA31AC /* Build configuration list for PBXNativeTarget "CDVCameraLibTests" */;
|
||||
buildPhases = (
|
||||
7E9F519B19DA102000DA31AC /* Sources */,
|
||||
7E9F519C19DA102000DA31AC /* Frameworks */,
|
||||
7E9F519D19DA102000DA31AC /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
7E9F51AD19DA10DE00DA31AC /* PBXTargetDependency */,
|
||||
);
|
||||
name = CDVCameraLibTests;
|
||||
productName = CDVCameraLibTests;
|
||||
productReference = 7E9F519F19DA102000DA31AC /* CDVCameraLibTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
7E9F517219DA09CE00DA31AC /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0610;
|
||||
TargetAttributes = {
|
||||
7E9F519419DA102000DA31AC = {
|
||||
CreatedOnToolsVersion = 6.0;
|
||||
};
|
||||
7E9F519E19DA102000DA31AC = {
|
||||
CreatedOnToolsVersion = 6.0;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 7E9F517519DA09CE00DA31AC /* Build configuration list for PBXProject "CDVCameraTest" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 7E9F517119DA09CE00DA31AC;
|
||||
productRefGroup = 7E9F517D19DA0A0A00DA31AC /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 7E9F518C19DA0F8300DA31AC /* Products */;
|
||||
ProjectRef = 7E9F518B19DA0F8300DA31AC /* CordovaLib.xcodeproj */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
7E9F519419DA102000DA31AC /* CDVCameraLib */,
|
||||
7E9F519E19DA102000DA31AC /* CDVCameraLibTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
7E9F519019DA0F8300DA31AC /* libCordova.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libCordova.a;
|
||||
remoteRef = 7E9F518F19DA0F8300DA31AC /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
7E9F519D19DA102000DA31AC /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
7E9F519119DA102000DA31AC /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
30486FF91A40DCC70065C233 /* CDVCamera.m in Sources */,
|
||||
30486FFB1A40DCC70065C233 /* UIImage+CropScaleOrientation.m in Sources */,
|
||||
30486FFA1A40DCC70065C233 /* CDVJpegHeaderWriter.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
7E9F519B19DA102000DA31AC /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7E9F51B119DA114400DA31AC /* CameraTest.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
30486FFD1A40DCE80065C233 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = CordovaLib;
|
||||
targetProxy = 30486FFC1A40DCE80065C233 /* PBXContainerItemProxy */;
|
||||
};
|
||||
7E9F51AD19DA10DE00DA31AC /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 7E9F519419DA102000DA31AC /* CDVCameraLib */;
|
||||
targetProxy = 7E9F51AC19DA10DE00DA31AC /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
7E9F517619DA09CE00DA31AC /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
7E9F517719DA09CE00DA31AC /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
7E9F51A419DA102000DA31AC /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"",
|
||||
"\"$(OBJROOT)/UninstalledProducts/include\"",
|
||||
"\"$(BUILT_PRODUCTS_DIR)\"",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
7E9F51A519DA102000DA31AC /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"",
|
||||
"\n\"$(OBJROOT)/UninstalledProducts/include\"\n\"$(BUILT_PRODUCTS_DIR)\"",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
7E9F51A719DA102000DA31AC /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INFOPLIST_FILE = CDVCameraLibTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-framework",
|
||||
XCTest,
|
||||
"-all_load",
|
||||
"-ObjC",
|
||||
);
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
7E9F51A819DA102000DA31AC /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INFOPLIST_FILE = CDVCameraLibTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-framework",
|
||||
XCTest,
|
||||
"-all_load",
|
||||
"-ObjC",
|
||||
);
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
7E9F517519DA09CE00DA31AC /* Build configuration list for PBXProject "CDVCameraTest" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
7E9F517619DA09CE00DA31AC /* Debug */,
|
||||
7E9F517719DA09CE00DA31AC /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
7E9F51A319DA102000DA31AC /* Build configuration list for PBXNativeTarget "CDVCameraLib" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
7E9F51A419DA102000DA31AC /* Debug */,
|
||||
7E9F51A519DA102000DA31AC /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
7E9F51A619DA102000DA31AC /* Build configuration list for PBXNativeTarget "CDVCameraLibTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
7E9F51A719DA102000DA31AC /* Debug */,
|
||||
7E9F51A819DA102000DA31AC /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 7E9F517219DA09CE00DA31AC /* Project object */;
|
||||
}
|
||||
7
tests/ios/CDVCameraTest/CDVCameraTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
tests/ios/CDVCameraTest/CDVCameraTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:CDVCameraTest.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
|
||||
<false/>
|
||||
<key>IDESourceControlProjectIdentifier</key>
|
||||
<string>6BE9AD73-1B9F-4362-98D7-DC631BEC6185</string>
|
||||
<key>IDESourceControlProjectName</key>
|
||||
<string>CDVCameraTest</string>
|
||||
<key>IDESourceControlProjectOriginsDictionary</key>
|
||||
<dict>
|
||||
<key>BEF5A5D0FF64801E558286389440357A9233D7DB</key>
|
||||
<string>https://git-wip-us.apache.org/repos/asf/cordova-plugin-camera.git</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectPath</key>
|
||||
<string>tests/ios/CDVCameraTest/CDVCameraTest.xcodeproj</string>
|
||||
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
|
||||
<dict>
|
||||
<key>BEF5A5D0FF64801E558286389440357A9233D7DB</key>
|
||||
<string>../../../../..</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectURL</key>
|
||||
<string>https://git-wip-us.apache.org/repos/asf/cordova-plugin-camera.git</string>
|
||||
<key>IDESourceControlProjectVersion</key>
|
||||
<integer>111</integer>
|
||||
<key>IDESourceControlProjectWCCIdentifier</key>
|
||||
<string>BEF5A5D0FF64801E558286389440357A9233D7DB</string>
|
||||
<key>IDESourceControlProjectWCConfigurations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||
<string>public.vcs.git</string>
|
||||
<key>IDESourceControlWCCIdentifierKey</key>
|
||||
<string>BEF5A5D0FF64801E558286389440357A9233D7DB</string>
|
||||
<key>IDESourceControlWCCName</key>
|
||||
<string>cordova-plugin-camera</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0610"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7E9F519419DA102000DA31AC"
|
||||
BuildableName = "libCDVCameraLib.a"
|
||||
BlueprintName = "CDVCameraLib"
|
||||
ReferencedContainer = "container:CDVCameraTest.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7E9F519419DA102000DA31AC"
|
||||
BuildableName = "libCDVCameraLib.a"
|
||||
BlueprintName = "CDVCameraLib"
|
||||
ReferencedContainer = "container:CDVCameraTest.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7E9F519419DA102000DA31AC"
|
||||
BuildableName = "libCDVCameraLib.a"
|
||||
BlueprintName = "CDVCameraLib"
|
||||
ReferencedContainer = "container:CDVCameraTest.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0610"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "NO"
|
||||
buildForArchiving = "NO"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7E9F519E19DA102000DA31AC"
|
||||
BuildableName = "CDVCameraLibTests.xctest"
|
||||
BlueprintName = "CDVCameraLibTests"
|
||||
ReferencedContainer = "container:CDVCameraTest.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7E9F519E19DA102000DA31AC"
|
||||
BuildableName = "CDVCameraLibTests.xctest"
|
||||
BlueprintName = "CDVCameraLibTests"
|
||||
ReferencedContainer = "container:CDVCameraTest.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7E9F519E19DA102000DA31AC"
|
||||
BuildableName = "CDVCameraLibTests.xctest"
|
||||
BlueprintName = "CDVCameraLibTests"
|
||||
ReferencedContainer = "container:CDVCameraTest.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7E9F519E19DA102000DA31AC"
|
||||
BuildableName = "CDVCameraLibTests.xctest"
|
||||
BlueprintName = "CDVCameraLibTests"
|
||||
ReferencedContainer = "container:CDVCameraTest.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7E9F519E19DA102000DA31AC"
|
||||
BuildableName = "CDVCameraLibTests.xctest"
|
||||
BlueprintName = "CDVCameraLibTests"
|
||||
ReferencedContainer = "container:CDVCameraTest.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
license: Licensed to the Apache Software Foundation (ASF) under one
|
||||
<!---
|
||||
license: 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
|
||||
@@ -15,18 +15,26 @@ license: Licensed to the Apache Software Foundation (ASF) under one
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
---
|
||||
-->
|
||||
|
||||
cameraError
|
||||
===========
|
||||
# iOS Tests for CDVCamera
|
||||
|
||||
onError callback function that provides an error message.
|
||||
You need to install `node.js` to pull in `cordova-ios`.
|
||||
|
||||
function(message) {
|
||||
// Show a helpful message
|
||||
}
|
||||
First install cordova-ios:
|
||||
|
||||
Parameters
|
||||
----------
|
||||
npm install
|
||||
|
||||
- __message:__ The message is provided by the device's native code. (`String`)
|
||||
... in the current folder.
|
||||
|
||||
|
||||
# Testing from Xcode
|
||||
|
||||
1. Launch the `CDVCameraTest.xcworkspace` file.
|
||||
2. Choose "CDVCameraLibTests" from the scheme drop-down menu
|
||||
3. Click and hold on the `Play` button, and choose the `Wrench` icon to run the tests
|
||||
|
||||
|
||||
# Testing from the command line
|
||||
|
||||
npm test
|
||||
13
tests/ios/package.json
Normal file
13
tests/ios/package.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "cordova-plugin-camera-test-ios",
|
||||
"version": "1.0.0",
|
||||
"description": "iOS Unit Tests for Camera Plugin",
|
||||
"author": "Apache Software Foundation",
|
||||
"license": "Apache Version 2.0",
|
||||
"dependencies": {
|
||||
"cordova-ios": "^3.7.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "xcodebuild -scheme CordovaLib && xcodebuild test -scheme CDVCameraLibTests -destination 'platform=iOS Simulator,name=iPhone 5'"
|
||||
}
|
||||
}
|
||||
33
tests/plugin.xml
Normal file
33
tests/plugin.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:rim="http://www.blackberry.com/ns/widgets"
|
||||
id="cordova-plugin-camera-tests"
|
||||
version="1.1.0">
|
||||
<name>Cordova Camera Plugin Tests</name>
|
||||
<license>Apache 2.0</license>
|
||||
|
||||
<dependency id="cordova-plugin-file" version=">=2.0.0" />
|
||||
|
||||
<js-module src="tests.js" name="tests">
|
||||
</js-module>
|
||||
</plugin>
|
||||
504
tests/tests.js
Normal file
504
tests/tests.js
Normal file
@@ -0,0 +1,504 @@
|
||||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
exports.defineAutoTests = function () {
|
||||
describe('Camera (navigator.camera)', function () {
|
||||
it("should exist", function () {
|
||||
expect(navigator.camera).toBeDefined();
|
||||
});
|
||||
|
||||
it("should contain a getPicture function", function () {
|
||||
expect(navigator.camera.getPicture).toBeDefined();
|
||||
expect(typeof navigator.camera.getPicture == 'function').toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Camera Constants (window.Camera + navigator.camera)', function () {
|
||||
it("camera.spec.1 window.Camera should exist", function () {
|
||||
expect(window.Camera).toBeDefined();
|
||||
});
|
||||
|
||||
it("camera.spec.2 should contain three DestinationType constants", function () {
|
||||
expect(Camera.DestinationType.DATA_URL).toBe(0);
|
||||
expect(Camera.DestinationType.FILE_URI).toBe(1);
|
||||
expect(Camera.DestinationType.NATIVE_URI).toBe(2);
|
||||
expect(navigator.camera.DestinationType.DATA_URL).toBe(0);
|
||||
expect(navigator.camera.DestinationType.FILE_URI).toBe(1);
|
||||
expect(navigator.camera.DestinationType.NATIVE_URI).toBe(2);
|
||||
});
|
||||
|
||||
it("camera.spec.3 should contain two EncodingType constants", function () {
|
||||
expect(Camera.EncodingType.JPEG).toBe(0);
|
||||
expect(Camera.EncodingType.PNG).toBe(1);
|
||||
expect(navigator.camera.EncodingType.JPEG).toBe(0);
|
||||
expect(navigator.camera.EncodingType.PNG).toBe(1);
|
||||
});
|
||||
|
||||
it("camera.spec.4 should contain three MediaType constants", function () {
|
||||
expect(Camera.MediaType.PICTURE).toBe(0);
|
||||
expect(Camera.MediaType.VIDEO).toBe(1);
|
||||
expect(Camera.MediaType.ALLMEDIA).toBe(2);
|
||||
expect(navigator.camera.MediaType.PICTURE).toBe(0);
|
||||
expect(navigator.camera.MediaType.VIDEO).toBe(1);
|
||||
expect(navigator.camera.MediaType.ALLMEDIA).toBe(2);
|
||||
});
|
||||
|
||||
it("camera.spec.5 should contain three PictureSourceType constants", function () {
|
||||
expect(Camera.PictureSourceType.PHOTOLIBRARY).toBe(0);
|
||||
expect(Camera.PictureSourceType.CAMERA).toBe(1);
|
||||
expect(Camera.PictureSourceType.SAVEDPHOTOALBUM).toBe(2);
|
||||
expect(navigator.camera.PictureSourceType.PHOTOLIBRARY).toBe(0);
|
||||
expect(navigator.camera.PictureSourceType.CAMERA).toBe(1);
|
||||
expect(navigator.camera.PictureSourceType.SAVEDPHOTOALBUM).toBe(2);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
exports.defineManualTests = function (contentEl, createActionButton) {
|
||||
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 = ['50', 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];
|
||||
|
||||
var clearLog = function () {
|
||||
var log = document.getElementById('info');
|
||||
log.innerHTML = "";
|
||||
}
|
||||
|
||||
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 || e));
|
||||
}
|
||||
|
||||
function getPictureWin(data) {
|
||||
setPicture(data);
|
||||
// TODO: Fix resolveLocalFileSystemURI to work with native-uri.
|
||||
if (pictureUrl.indexOf('file:') == 0 || pictureUrl.indexOf('content:') == 0 || pictureUrl.indexOf('ms-appdata:') === 0) {
|
||||
resolveLocalFileSystemURI(data, function (e) {
|
||||
fileEntry = e;
|
||||
logCallback('resolveLocalFileSystemURI()', true)(e.toURL());
|
||||
}, 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) {
|
||||
console.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;
|
||||
var origName = fileEntry.name;
|
||||
|
||||
// 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));
|
||||
|
||||
//cleanup
|
||||
//rename moved file back to original name so other tests can reference image
|
||||
resolveLocalFileSystemURI(destDirEntry.nativeURL+'moved_file.png', function(fileEntry) {
|
||||
fileEntry.moveTo(destDirEntry, origName, logCallback('FileEntry.moveTo', true), logCallback('FileEntry.moveTo', false));
|
||||
console.log('Cleanup: successfully renamed file back to original name');
|
||||
}, function () {
|
||||
console.log('Cleanup: failed to rename file back to original name');
|
||||
});
|
||||
|
||||
//remove copied file
|
||||
resolveLocalFileSystemURI(destDirEntry.nativeURL+'copied_file.png', function(fileEntry) {
|
||||
fileEntry.remove(logCallback('FileEntry.remove', true), logCallback('FileEntry.remove', false));
|
||||
console.log('Cleanup: successfully removed copied file');
|
||||
}, function () {
|
||||
console.log('Cleanup: failed to remove copied file');
|
||||
});
|
||||
};
|
||||
|
||||
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.getAttribute("name")] = !!+value;
|
||||
} else {
|
||||
ret[el.getAttribute("name")] = +value;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function createOptionsEl(name, values, selectionDefault) {
|
||||
var openDiv = '<div style="display: inline-block">' + name + ': ';
|
||||
var select = '<select name=' + name + '>';
|
||||
|
||||
var defaultOption = '';
|
||||
if (selectionDefault == undefined) {
|
||||
defaultOption = '<option value="">default</option>';
|
||||
}
|
||||
|
||||
var options = '';
|
||||
if (typeof values == 'boolean') {
|
||||
values = { 'true': 1, 'false': 0 };
|
||||
}
|
||||
for (var k in values) {
|
||||
var isSelected = '';
|
||||
if (selectionDefault) {
|
||||
if (selectionDefault[0] == k) {
|
||||
isSelected = 'selected';
|
||||
}
|
||||
}
|
||||
options += '<option value="' + values[k] + '" ' + isSelected + '>' + k + '</option>';
|
||||
}
|
||||
|
||||
var closeDiv = '</select></div>';
|
||||
|
||||
return openDiv + select + defaultOption + options + closeDiv;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var info_div = '<h1>Camera</h1>' +
|
||||
'<div id="info">' +
|
||||
'<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>',
|
||||
options_div = '<h2>Cordova Camera API Options</h2>' +
|
||||
'<div id="image-options">' +
|
||||
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) +
|
||||
'</div>',
|
||||
getpicture_div = '<div id="getpicture"></div>',
|
||||
test_procedure = '<h4>Recommended Test Procedure</h4>' +
|
||||
'Options not specified should be the default value' +
|
||||
'<br>Status box should update with image and info whenever an image is taken or selected from library' +
|
||||
'</p><div style="background:#B0C4DE;border:1px solid #FFA07A;margin:15px 6px 0px;min-width:295px;max-width:97%;padding:4px 0px 2px 10px;min-height:160px;max-height:200px;overflow:auto">' +
|
||||
'<ol> <li>All default options. Should be able to edit once picture is taken and will be saved to library.</li>' +
|
||||
'</p><li>sourceType=PHOTOLIBRARY<br>Should be able to see picture that was just taken in previous test and edit when selected</li>' +
|
||||
'</p><li>sourceType=Camera<br>allowEdit=false<br>saveToPhotoAlbum=false<br>Should not be able to edit when taken and will not save to library</li>' +
|
||||
'</p><li>encodingType=PNG<br>allowEdit=true<br>saveToPhotoAlbum=true<br>cameraDirection=FRONT<br>Should bring up front camera. Verify in status box info URL that image is encoded as PNG.</li>' +
|
||||
'</p><li>sourceType=SAVEDPHOTOALBUM<br>mediaType=VIDEO<br>Should only be able to select a video</li>' +
|
||||
'</p><li>sourceType=SAVEDPHOTOALBUM<br>mediaType=PICTURE<br>allowEdit=false<br>Should only be able to select a picture and not edit</li>' +
|
||||
'</p><li>sourceType=PHOTOLIBRARY<br>mediaType=ALLMEDIA<br>allowEdit=true<br>Should be able to select pics and videos and edit picture if selected</li>' +
|
||||
'</p><li>sourceType=CAMERA<br>targetWidth & targetHeight=50<br>allowEdit=false<br>Do Get File Metadata test below and take note of size<br>Repeat test but with width and height=800. Size should be significantly larger.</li>' +
|
||||
'</p><li>quality=0<br>targetWidth & targetHeight=default<br>allowEdit=false<br>Do Get File Metadata test below and take note of size<br>Repeat test but with quality=80. Size should be significantly larger.</li>' +
|
||||
'</ol></div>',
|
||||
inputs_div = '<h2>Native File Inputs</h2>' +
|
||||
'For the following tests, status box should update with file selected' +
|
||||
'</p><div>input type=file <input type="file" class="testInputTag"></div>' +
|
||||
'<div>capture=camera <input type="file" accept="image/*;capture=camera" class="testInputTag"></div>' +
|
||||
'<div>capture=camcorder <input type="file" accept="video/*;capture=camcorder" class="testInputTag"></div>' +
|
||||
'<div>capture=microphone <input type="file" accept="audio/*;capture=microphone" class="testInputTag"></div>',
|
||||
actions_div = '<h2>Actions</h2>' +
|
||||
'For the following tests, ensure that an image is set in status box' +
|
||||
'</p><div id="metadata"></div>' +
|
||||
'Expected result: Get metadata about file selected.<br>Status box will show, along with the metadata, "Call to FileEntry.getMetadata success, Call to FileEntry.setMetadata success, Call to FileEntry.getParent success"' +
|
||||
'</p><div id="reader"></div>' +
|
||||
'Expected result: Read contents of file.<br>Status box will show "Got file: {some metadata}, FileReader.readAsDataURL() - length = someNumber"' +
|
||||
'</p><div id="copy"></div>' +
|
||||
'Expected result: Copy image to new location and move file to different location.<br>Status box will show "Call to FileEntry.copyTo success:{some metadata}, Call to FileEntry.moveTo success:{some metadata}"' +
|
||||
'</p><div id="write"></div>' +
|
||||
'Expected result: Write image to library.<br>Status box will show "Call to FileWriter.write success:{some metadata}, Call to FileWriter.truncate success:{some metadata}"' +
|
||||
'</p><div id="upload"></div>' +
|
||||
'Expected result: Upload image to server.<br>Status box may print out progress. Once finished will show "upload complete"' +
|
||||
'</p><div id="draw_canvas"></div>' +
|
||||
'Expected result: Display image using canvas.<br>Image will be displayed in status box under "canvas:"' +
|
||||
'</p><div id="remove"></div>' +
|
||||
'Expected result: Remove image from library.<br>Status box will show "FileEntry.remove success:["OK"]';
|
||||
|
||||
// We need to wrap this code due to Windows security restrictions
|
||||
// see http://msdn.microsoft.com/en-us/library/windows/apps/hh465380.aspx#differences for details
|
||||
if (window.MSApp && window.MSApp.execUnsafeLocalFunction) {
|
||||
MSApp.execUnsafeLocalFunction(function() {
|
||||
contentEl.innerHTML = info_div + options_div + getpicture_div + test_procedure + inputs_div + actions_div;
|
||||
});
|
||||
} else {
|
||||
contentEl.innerHTML = info_div + options_div + getpicture_div + test_procedure + inputs_div + actions_div;
|
||||
}
|
||||
|
||||
var elements = document.getElementsByClassName("testInputTag");
|
||||
var listener = function (e) {
|
||||
testInputTag(e.target);
|
||||
}
|
||||
for (var i = 0; i < elements.length; ++i) {
|
||||
var item = elements[i];
|
||||
item.addEventListener("change", listener, false);
|
||||
}
|
||||
|
||||
createActionButton('Get picture', function () {
|
||||
getPicture();
|
||||
}, 'getpicture');
|
||||
|
||||
createActionButton('Clear Status', function () {
|
||||
clearStatus();
|
||||
}, 'getpicture');
|
||||
|
||||
createActionButton('Get File Metadata', function () {
|
||||
getFileInfo();
|
||||
}, 'metadata');
|
||||
|
||||
createActionButton('Read with FileReader', function () {
|
||||
readFile();
|
||||
}, 'reader');
|
||||
|
||||
createActionButton('Copy Image', function () {
|
||||
copyImage();
|
||||
}, 'copy');
|
||||
|
||||
createActionButton('Write Image', function () {
|
||||
writeImage();
|
||||
}, 'write');
|
||||
|
||||
createActionButton('Upload Image', function () {
|
||||
uploadImage();
|
||||
}, 'upload');
|
||||
|
||||
createActionButton('Draw Using Canvas', function () {
|
||||
displayImageUsingCanvas();
|
||||
}, 'draw_canvas');
|
||||
|
||||
createActionButton('Remove Image', function () {
|
||||
removeImage();
|
||||
}, 'remove');
|
||||
};
|
||||
@@ -21,8 +21,9 @@
|
||||
|
||||
var argscheck = require('cordova/argscheck'),
|
||||
exec = require('cordova/exec'),
|
||||
Camera = require('./Camera'),
|
||||
CameraPopoverHandle = require('./CameraPopoverHandle');
|
||||
Camera = require('./Camera');
|
||||
// XXX: commented out
|
||||
//CameraPopoverHandle = require('./CameraPopoverHandle');
|
||||
|
||||
var cameraExport = {};
|
||||
|
||||
@@ -63,7 +64,8 @@ cameraExport.getPicture = function(successCallback, errorCallback, options) {
|
||||
mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
|
||||
|
||||
exec(successCallback, errorCallback, "Camera", "takePicture", args);
|
||||
return new CameraPopoverHandle();
|
||||
// XXX: commented out
|
||||
//return new CameraPopoverHandle();
|
||||
};
|
||||
|
||||
cameraExport.cleanup = function(successCallback, errorCallback) {
|
||||
|
||||
82
www/blackberry10/assets/camera.html
Normal file
82
www/blackberry10/assets/camera.html
Normal file
@@ -0,0 +1,82 @@
|
||||
<!--
|
||||
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>
|
||||
46
www/blackberry10/assets/camera.js
Normal file
46
www/blackberry10/assets/camera.js
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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'),
|
||||
canvas = document.getElementById('c'),
|
||||
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');
|
||||
}
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user