Compare commits
No commits in common. "master" and "CB-8438cordova-plugin-camera" have entirely different histories.
master
...
CB-8438cor
@ -1,32 +0,0 @@
|
|||||||
# appveyor file
|
|
||||||
# http://www.appveyor.com/docs/appveyor-yml
|
|
||||||
|
|
||||||
max_jobs: 1
|
|
||||||
|
|
||||||
shallow_clone: true
|
|
||||||
|
|
||||||
init:
|
|
||||||
- git config --global core.autocrlf true
|
|
||||||
|
|
||||||
image:
|
|
||||||
- Visual Studio 2017
|
|
||||||
|
|
||||||
environment:
|
|
||||||
matrix:
|
|
||||||
- nodejs_version: "10"
|
|
||||||
- nodejs_version: "12"
|
|
||||||
|
|
||||||
platform:
|
|
||||||
- x86
|
|
||||||
- x64
|
|
||||||
|
|
||||||
install:
|
|
||||||
- ps: Install-Product node $env:nodejs_version
|
|
||||||
- node --version
|
|
||||||
- npm install -g github:apache/cordova-paramedic
|
|
||||||
- npm install -g cordova
|
|
||||||
|
|
||||||
build: off
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
- cordova-paramedic --config pr\windows-10-store --plugin . --justBuild
|
|
22
.asf.yaml
@ -1,22 +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.
|
|
||||||
|
|
||||||
notifications:
|
|
||||||
commits: commits@cordova.apache.org
|
|
||||||
issues: issues@cordova.apache.org
|
|
||||||
pullrequests_status: issues@cordova.apache.org
|
|
||||||
pullrequests_comment: issues@cordova.apache.org
|
|
@ -1,10 +0,0 @@
|
|||||||
root: true
|
|
||||||
extends: semistandard
|
|
||||||
rules:
|
|
||||||
indent:
|
|
||||||
- error
|
|
||||||
- 4
|
|
||||||
camelcase: off
|
|
||||||
padded-blocks: off
|
|
||||||
operator-linebreak: off
|
|
||||||
no-throw-literal: off
|
|
94
.gitattributes
vendored
@ -1,94 +0,0 @@
|
|||||||
* text eol=lf
|
|
||||||
|
|
||||||
# source code
|
|
||||||
*.php text
|
|
||||||
*.css text
|
|
||||||
*.sass text
|
|
||||||
*.scss text
|
|
||||||
*.less text
|
|
||||||
*.styl text
|
|
||||||
*.js text
|
|
||||||
*.coffee text
|
|
||||||
*.json text
|
|
||||||
*.htm text
|
|
||||||
*.html text
|
|
||||||
*.xml text
|
|
||||||
*.svg text
|
|
||||||
*.txt text
|
|
||||||
*.ini text
|
|
||||||
*.inc text
|
|
||||||
*.pl text
|
|
||||||
*.rb text
|
|
||||||
*.py text
|
|
||||||
*.scm text
|
|
||||||
*.sql text
|
|
||||||
*.sh text
|
|
||||||
*.bat text
|
|
||||||
|
|
||||||
# templates
|
|
||||||
*.ejs text
|
|
||||||
*.hbt text
|
|
||||||
*.jade text
|
|
||||||
*.haml text
|
|
||||||
*.hbs text
|
|
||||||
*.dot text
|
|
||||||
*.tmpl text
|
|
||||||
*.phtml text
|
|
||||||
|
|
||||||
# server config
|
|
||||||
.htaccess text
|
|
||||||
|
|
||||||
# git config
|
|
||||||
.gitattributes text
|
|
||||||
.gitignore text
|
|
||||||
.gitconfig text
|
|
||||||
|
|
||||||
# code analysis config
|
|
||||||
.jshintrc text
|
|
||||||
.jscsrc text
|
|
||||||
.jshintignore text
|
|
||||||
.csslintrc text
|
|
||||||
|
|
||||||
# misc config
|
|
||||||
*.yaml text
|
|
||||||
*.yml text
|
|
||||||
.editorconfig text
|
|
||||||
|
|
||||||
# build config
|
|
||||||
*.npmignore text
|
|
||||||
*.bowerrc text
|
|
||||||
|
|
||||||
# Heroku
|
|
||||||
Procfile text
|
|
||||||
.slugignore text
|
|
||||||
|
|
||||||
# Documentation
|
|
||||||
*.md text
|
|
||||||
LICENSE text
|
|
||||||
AUTHORS text
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
## These files are binary and should be left untouched
|
|
||||||
#
|
|
||||||
|
|
||||||
# (binary is a macro for -text -diff)
|
|
||||||
*.png binary
|
|
||||||
*.jpg binary
|
|
||||||
*.jpeg binary
|
|
||||||
*.gif binary
|
|
||||||
*.ico binary
|
|
||||||
*.mov binary
|
|
||||||
*.mp4 binary
|
|
||||||
*.mp3 binary
|
|
||||||
*.flv binary
|
|
||||||
*.fla binary
|
|
||||||
*.swf binary
|
|
||||||
*.gz binary
|
|
||||||
*.zip binary
|
|
||||||
*.7z binary
|
|
||||||
*.ttf binary
|
|
||||||
*.eot binary
|
|
||||||
*.woff binary
|
|
||||||
*.pyc binary
|
|
||||||
*.pdf binary
|
|
42
.github/ISSUE_TEMPLATE.md
vendored
@ -1,42 +0,0 @@
|
|||||||
<!--
|
|
||||||
Please have a look at the issue templates you get when you click "New issue" in the GitHub UI.
|
|
||||||
We very much prefer issues created by using one of these templates.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Issue Type
|
|
||||||
<!-- Please check the boxes by putting an x in the [ ] like so: [x] -->
|
|
||||||
|
|
||||||
- [ ] Bug Report
|
|
||||||
- [ ] Feature Request
|
|
||||||
- [ ] Support Question
|
|
||||||
|
|
||||||
## Description
|
|
||||||
|
|
||||||
## Information
|
|
||||||
<!-- Include all relevant information that might help understand and reproduce the problem -->
|
|
||||||
|
|
||||||
### Command or Code
|
|
||||||
<!-- What command or code is needed to reproduce the problem? -->
|
|
||||||
|
|
||||||
### Environment, Platform, Device
|
|
||||||
<!-- In what environment, on what platform or on which device are you experiencing the issue? -->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Version information
|
|
||||||
<!--
|
|
||||||
What are relevant versions you are using?
|
|
||||||
For example:
|
|
||||||
Cordova: Cordova CLI, Cordova Platforms, Cordova Plugins
|
|
||||||
Other Frameworks: Ionic Framework and CLI version
|
|
||||||
Operating System, Android Studio, Xcode etc.
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Checklist
|
|
||||||
<!-- Please check the boxes by putting an `x` in the `[ ]` like so: `[x]` -->
|
|
||||||
|
|
||||||
- [ ] I searched for already existing GitHub issues about this
|
|
||||||
- [ ] I updated all Cordova tooling to their most recent version
|
|
||||||
- [ ] I included all the necessary information above
|
|
50
.github/ISSUE_TEMPLATE/BUG_REPORT.md
vendored
@ -1,50 +0,0 @@
|
|||||||
---
|
|
||||||
name: 🐛 Bug Report
|
|
||||||
about: If something isn't working as expected.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Bug Report
|
|
||||||
|
|
||||||
## Problem
|
|
||||||
|
|
||||||
### What is expected to happen?
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### What does actually happen?
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Information
|
|
||||||
<!-- Include all relevant information that might help understand and reproduce the problem -->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Command or Code
|
|
||||||
<!-- What command or code is needed to reproduce the problem? -->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Environment, Platform, Device
|
|
||||||
<!-- In what environment, on what platform or on which device are you experiencing the issue? -->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Version information
|
|
||||||
<!--
|
|
||||||
What are relevant versions you are using?
|
|
||||||
For example:
|
|
||||||
Cordova: Cordova CLI, Cordova Platforms, Cordova Plugins
|
|
||||||
Other Frameworks: Ionic Framework and CLI version
|
|
||||||
Operating System, Android Studio, Xcode etc.
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Checklist
|
|
||||||
<!-- Please check the boxes by putting an x in the [ ] like so: [x] -->
|
|
||||||
|
|
||||||
- [ ] I searched for existing GitHub issues
|
|
||||||
- [ ] I updated all Cordova tooling to most recent version
|
|
||||||
- [ ] I included all the necessary information above
|
|
29
.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
vendored
@ -1,29 +0,0 @@
|
|||||||
---
|
|
||||||
name: 🚀 Feature Request
|
|
||||||
about: A suggestion for a new functionality
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Feature Request
|
|
||||||
|
|
||||||
## Motivation Behind Feature
|
|
||||||
<!-- Why should this feature be implemented? What problem does it solve? -->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Feature Description
|
|
||||||
<!--
|
|
||||||
Describe your feature request in detail
|
|
||||||
Please provide any code examples or screenshots of what this feature would look like
|
|
||||||
Are there any drawbacks? Will this break anything for existing users?
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Alternatives or Workarounds
|
|
||||||
<!--
|
|
||||||
Describe alternatives or workarounds you are currently using
|
|
||||||
Are there ways to do this with existing functionality?
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
27
.github/ISSUE_TEMPLATE/SUPPORT_QUESTION.md
vendored
@ -1,27 +0,0 @@
|
|||||||
---
|
|
||||||
name: 💬 Support Question
|
|
||||||
about: If you have a question, please check out our Slack or StackOverflow!
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!------------^ Click "Preview" for a nicer view! -->
|
|
||||||
|
|
||||||
Apache Cordova uses GitHub Issues as a feature request and bug tracker _only_.
|
|
||||||
For usage and support questions, please check out the resources below. Thanks!
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
You can get answers to your usage and support questions about **Apache Cordova** on:
|
|
||||||
|
|
||||||
* Slack Community Chat: https://cordova.slack.com (you can sign-up at http://slack.cordova.io/)
|
|
||||||
* StackOverflow: https://stackoverflow.com/questions/tagged/cordova using the tag `cordova`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
If you are using a tool that uses Cordova internally, like e.g. Ionic, check their support channels:
|
|
||||||
|
|
||||||
* **Ionic Framework**
|
|
||||||
* [Ionic Community Forum](https://forum.ionicframework.com/)
|
|
||||||
* [Ionic Worldwide Slack](https://ionicworldwide.herokuapp.com/)
|
|
||||||
* **PhoneGap**
|
|
||||||
* [PhoneGap Developer Community](https://forums.adobe.com/community/phonegap)
|
|
35
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,35 +0,0 @@
|
|||||||
<!--
|
|
||||||
Please make sure the checklist boxes are all checked before submitting the PR. The checklist is intended as a quick reference, for complete details please see our Contributor Guidelines:
|
|
||||||
|
|
||||||
http://cordova.apache.org/contribute/contribute_guidelines.html
|
|
||||||
|
|
||||||
Thanks!
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Platforms affected
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Motivation and Context
|
|
||||||
<!-- Why is this change required? What problem does it solve? -->
|
|
||||||
<!-- If it fixes an open issue, please link to the issue here. -->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Description
|
|
||||||
<!-- Describe your changes in detail -->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Testing
|
|
||||||
<!-- Please describe in detail how you tested your changes. -->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Checklist
|
|
||||||
|
|
||||||
- [ ] I've run the tests to see all new and existing tests pass
|
|
||||||
- [ ] I added automated test coverage as appropriate for this change
|
|
||||||
- [ ] Commit is prefixed with `(platform)` if this change only applies to one platform (e.g. `(android)`)
|
|
||||||
- [ ] If this Pull Request resolves an issue, I linked to the issue in the text above (and used the correct [keyword to close issues using keywords](https://help.github.com/articles/closing-issues-using-keywords/))
|
|
||||||
- [ ] I've updated the documentation if necessary
|
|
10
.gitignore
vendored
@ -12,4 +12,12 @@ Thumbs.db
|
|||||||
*.swp
|
*.swp
|
||||||
*.user
|
*.user
|
||||||
|
|
||||||
/node_modules/**
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
.*
|
|
||||||
appveyor.yml
|
|
||||||
tests
|
|
117
.travis.yml
@ -1,117 +0,0 @@
|
|||||||
# This Travis configuration file is built after a Cordova Paramedic
|
|
||||||
# specific template with minimal modifications and adaptations:
|
|
||||||
# https://github.com/apache/cordova-paramedic/blob/master/.travis.yml
|
|
||||||
|
|
||||||
sudo: false
|
|
||||||
|
|
||||||
addons:
|
|
||||||
jwt:
|
|
||||||
# SAUCE_ACCESS_KEY
|
|
||||||
secure: QivPLlqTVvOo3TJeHxuBOfxU6lho1I0IxQ3b68yntkEQQJko6kzleXHfgjf0a8aw8m38E3+fxaBWF1bGyucGwOLDWY8Ddt2P2xg44zdXH5EXHd9oIqAgngIdzLvUtH3Db2TbQEtIGOkrnNR2STovjqB7vHGLASQrgs4oL7r32/s=
|
|
||||||
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- SAUCE_USERNAME=snay
|
|
||||||
- TRAVIS_NODE_VERSION=12
|
|
||||||
- ANDROID_API_LEVEL=28
|
|
||||||
- ANDROID_BUILD_TOOLS_VERSION=28.0.3
|
|
||||||
|
|
||||||
language: node_js
|
|
||||||
node_js: 12
|
|
||||||
|
|
||||||
# yaml anchor/alias: https://medium.com/@tommyvn/travis-yml-dry-with-anchors-8b6a3ac1b027
|
|
||||||
|
|
||||||
_ios: &_ios
|
|
||||||
os: osx
|
|
||||||
osx_image: xcode10.3
|
|
||||||
|
|
||||||
_android: &_android
|
|
||||||
language: android
|
|
||||||
os: linux
|
|
||||||
jdk: oraclejdk8
|
|
||||||
android:
|
|
||||||
components:
|
|
||||||
- tools
|
|
||||||
- build-tools-$ANDROID_BUILD_TOOLS_VERSION
|
|
||||||
- android-$ANDROID_API_LEVEL
|
|
||||||
licenses:
|
|
||||||
- "android-sdk-preview-license-.+"
|
|
||||||
- "android-sdk-license-.+"
|
|
||||||
- "google-gdk-license-.+"
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
# additional tests
|
|
||||||
- env: ADDITIONAL_TESTS_DIR=./tests/ios
|
|
||||||
language: objective-c
|
|
||||||
|
|
||||||
# local tests, without saucelabs
|
|
||||||
- env: PLATFORM=local/browser
|
|
||||||
<<: *_ios
|
|
||||||
- env: PLATFORM=local/ios-10.0
|
|
||||||
<<: *_ios
|
|
||||||
|
|
||||||
# many tests with saucelabs
|
|
||||||
- env: PLATFORM=browser-chrome
|
|
||||||
- env: PLATFORM=browser-firefox
|
|
||||||
- env: PLATFORM=browser-safari
|
|
||||||
- env: PLATFORM=browser-edge
|
|
||||||
|
|
||||||
- env: PLATFORM=ios-11.3
|
|
||||||
<<: *_ios
|
|
||||||
- env: PLATFORM=ios-12.0
|
|
||||||
<<: *_ios
|
|
||||||
- env: PLATFORM=ios-12.2
|
|
||||||
<<: *_ios
|
|
||||||
|
|
||||||
- env: PLATFORM=android-5.1
|
|
||||||
<<: *_android
|
|
||||||
- env: PLATFORM=android-6.0
|
|
||||||
<<: *_android
|
|
||||||
- env: PLATFORM=android-7.0
|
|
||||||
<<: *_android
|
|
||||||
- env: PLATFORM=android-7.1
|
|
||||||
<<: *_android
|
|
||||||
- env: PLATFORM=android-8.0
|
|
||||||
<<: *_android
|
|
||||||
- env: PLATFORM=android-8.1
|
|
||||||
<<: *_android
|
|
||||||
- env: PLATFORM=android-9.0
|
|
||||||
<<: *_android
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
# manually install Node for `language: android`
|
|
||||||
- if [[ "$PLATFORM" =~ android ]]; then nvm install $TRAVIS_NODE_VERSION; fi
|
|
||||||
- node --version
|
|
||||||
- if [[ "$PLATFORM" =~ android ]]; then gradle --version; fi
|
|
||||||
- if [[ "$PLATFORM" =~ ios ]]; then npm install -g ios-deploy; fi
|
|
||||||
- npm install -g cordova
|
|
||||||
# install paramedic if not running on paramedic repo
|
|
||||||
- if ! [[ "$TRAVIS_REPO_SLUG" =~ cordova-paramedic ]]; then npm install -g github:apache/cordova-paramedic; fi
|
|
||||||
|
|
||||||
install:
|
|
||||||
- npm install
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- |
|
|
||||||
if [[ "$TRAVIS_REPO_SLUG" =~ cordova-paramedic ]]; then
|
|
||||||
# when used in the cordova-paramedic repo
|
|
||||||
TEST_COMMAND="npm run eslint"
|
|
||||||
PARAMEDIC_PLUGIN_TO_TEST="./spec/testable-plugin/"
|
|
||||||
PARAMEDIC_COMMAND="node main.js"
|
|
||||||
else
|
|
||||||
# when used in any other (plugin) repo
|
|
||||||
TEST_COMMAND="npm test"
|
|
||||||
PARAMEDIC_PLUGIN_TO_TEST=$(pwd)
|
|
||||||
PARAMEDIC_COMMAND="cordova-paramedic"
|
|
||||||
fi
|
|
||||||
- PARAMEDIC_BUILDNAME=travis-$TRAVIS_REPO_SLUG-$TRAVIS_JOB_NUMBER
|
|
||||||
|
|
||||||
script:
|
|
||||||
- $TEST_COMMAND
|
|
||||||
- |
|
|
||||||
if [[ "$ADDITIONAL_TESTS_DIR" != "" ]];
|
|
||||||
then cd $ADDITIONAL_TESTS_DIR && npm install && npm test;
|
|
||||||
else
|
|
||||||
$PARAMEDIC_COMMAND --config ./pr/$PLATFORM --plugin $PARAMEDIC_PLUGIN_TO_TEST --buildName $PARAMEDIC_BUILDNAME;
|
|
||||||
fi
|
|
@ -25,13 +25,13 @@ Anyone can contribute to Cordova. And we need your contributions.
|
|||||||
|
|
||||||
There are multiple ways to contribute: report bugs, improve the docs, and
|
There are multiple ways to contribute: report bugs, improve the docs, and
|
||||||
contribute code.
|
contribute code.
|
||||||
|
|
||||||
For instructions on this, start with the
|
For instructions on this, start with the
|
||||||
[contribution overview](http://cordova.apache.org/contribute/).
|
[contribution overview](http://cordova.apache.org/#contribute).
|
||||||
|
|
||||||
The details are explained there, but the important items are:
|
The details are explained there, but the important items are:
|
||||||
- Check for Github issues that corresponds to your contribution and link or create them if necessary.
|
- 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.
|
- Run the tests so your patch doesn't break existing functionality.
|
||||||
|
|
||||||
We look forward to your contributions!
|
We look forward to your contributions!
|
||||||
|
|
||||||
|
39
README.md
@ -1,25 +1,22 @@
|
|||||||
---
|
<!---
|
||||||
title: Camera
|
license: Licensed to the Apache Software Foundation (ASF) under one
|
||||||
description: Take pictures with the device camera.
|
or more contributor license agreements. See the NOTICE file
|
||||||
---
|
distributed with this work for additional information
|
||||||
# cordova-plugin-splashscreen
|
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
|
||||||
|
|
||||||
在 [cordova-plugin-camera](https://github.com/apache/cordova-plugin-camera.git) 的基础上修改了ios端的代码为[customCamera](https://github.com/geneanet/customCamera.git)的ios的代码,防止ios疯狂调用造成的webview卡死的问题
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
- [Installation](#installation)
|
Unless required by applicable law or agreed to in writing,
|
||||||
- [Preferences](#preferences)
|
software distributed under the License is distributed on an
|
||||||
- [Other](#other)
|
"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.
|
||||||
|
-->
|
||||||
|
|
||||||
## Installation
|
# org.apache.cordova.camera
|
||||||
|
|
||||||
```bash
|
Plugin documentation: [doc/index.md](doc/index.md)
|
||||||
# 安装前请先卸载 `cordova-plugin-camera` 和 `org.geneanet.customCamera` 插件
|
|
||||||
cordova plugin rm cordova-plugin-camera
|
|
||||||
cordova plugin rm org.geneanet.customCamera
|
|
||||||
# 安装插件
|
|
||||||
cordova plugin add https://gitee.com/shuto/cordova-plugin-camera.git
|
|
||||||
```
|
|
||||||
## Preferences
|
|
||||||
- iOS端由于代码调整,导致原插件仅支持 `quality` `saveToPhotoAlbum` 参数,返回数据格式为 **base64**;
|
|
||||||
## Other
|
|
||||||
- 其他配置及插件使用方法请移步[cordova-plugin-camera](https://github.com/apache/cordova-plugin-camera.git)
|
|
||||||
|
552
RELEASENOTES.md
@ -7,9 +7,9 @@
|
|||||||
# to you under the Apache License, Version 2.0 (the
|
# to you under the Apache License, Version 2.0 (the
|
||||||
# "License"); you may not use this file except in compliance
|
# "License"); you may not use this file except in compliance
|
||||||
# with the License. You may obtain a copy of the License at
|
# with the License. You may obtain a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing,
|
# Unless required by applicable law or agreed to in writing,
|
||||||
# software distributed under the License is distributed on an
|
# software distributed under the License is distributed on an
|
||||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
@ -20,398 +20,33 @@
|
|||||||
-->
|
-->
|
||||||
# Release Notes
|
# Release Notes
|
||||||
|
|
||||||
### 4.2.0 (May 07, 2020)
|
### 0.2.1 (Sept 5, 2013)
|
||||||
* Cache images in device storage, devices have enough space now.
|
* [CB-4656] Don't add line-breaks to base64-encoded images (Fixes type=DataURI)
|
||||||
* docs(readme): app renamed to Google Photos
|
* [CB-4432] copyright notice change
|
||||||
* chore(asf): update git notification settings
|
|
||||||
* fix(ios): return copy of video when picking from gallery on **iOS** 13 (#580)
|
|
||||||
* Update CONTRIBUTING.md
|
|
||||||
* Fix UI API called on a background thread (#550, #530, #447) (#551)
|
|
||||||
* ci: updates Node.js versions (#576)
|
|
||||||
* chore(npm): adds ignore list (#575)
|
|
||||||
* docs(README): remove confusing comment (#513)
|
|
||||||
* docs(README): remove orphan **Windows** phone 7 note (#512)
|
|
||||||
* ImagePicker returning same image (#306)
|
|
||||||
|
|
||||||
### 4.1.0 (Jun 27, 2019)
|
### 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
|
||||||
|
|
||||||
- docs: remove outdated test docs translations ([`06dc38f`](https://github.com/apache/cordova-plugin-camera/commit/06dc38f))
|
### 0.2.4 (Oct 28, 2013)
|
||||||
- build: remove `.ratignore` file that is not needed any more ([`5dc9527`](https://github.com/apache/cordova-plugin-camera/commit/5dc9527))
|
* CB-5128: added repo + issue tag to plugin.xml for camera plugin
|
||||||
- chore: fix repo and issue urls and license in package.json and plugin.xml ([`cad8bd1`](https://github.com/apache/cordova-plugin-camera/commit/cad8bd1))
|
* CB-4958 - iOS - Camera plugin should not show the status bar
|
||||||
- fix: temporarily remove Appium tests to unbreak CI ([#468](https://github.com/apache/cordova-plugin-camera/issues/468)) ([`19d8e2f`](https://github.com/apache/cordova-plugin-camera/commit/19d8e2f))
|
* [CB-4919] updated plugin.xml for FxOS
|
||||||
- ci(travis): Update Travis CI configuration for new paramedic ([#455](https://github.com/apache/cordova-plugin-camera/issues/455)) ([`cffd0ac`](https://github.com/apache/cordova-plugin-camera/commit/cffd0ac))
|
* [CB-4915] Incremented plugin version on dev branch.
|
||||||
- fix(android): Fix NullPointerException error on some Android phones ([#429](https://github.com/apache/cordova-plugin-camera/issues/429)) ([`295e928`](https://github.com/apache/cordova-plugin-camera/commit/295e928))
|
|
||||||
- ci: Update CI Environment Setup for Node.js 6 ([#438](https://github.com/apache/cordova-plugin-camera/issues/438)) ([`fae190e`](https://github.com/apache/cordova-plugin-camera/commit/fae190e))
|
|
||||||
- refactor(android): Enhancement: Camera plugin code cleanup ([#425](https://github.com/apache/cordova-plugin-camera/issues/425)) ([`a13665d`](https://github.com/apache/cordova-plugin-camera/commit/a13665d))
|
|
||||||
- fix(android): Exif data lost on many cases ([#331](https://github.com/apache/cordova-plugin-camera/issues/331)) ([`81b878d`](https://github.com/apache/cordova-plugin-camera/commit/81b878d))
|
|
||||||
- chore(github): Add or update GitHub pull request and issue template ([`b261d31`](https://github.com/apache/cordova-plugin-camera/commit/b261d31))
|
|
||||||
- fix(ios): fixes UIImagePickerController cancel handling for iOS11+ ([#377](https://github.com/apache/cordova-plugin-camera/issues/377)) ([`24c8b6c`](https://github.com/apache/cordova-plugin-camera/commit/24c8b6c))
|
|
||||||
- docs: Remove deprecated platforms from docs ([#394](https://github.com/apache/cordova-plugin-camera/issues/394)) ([`7ddb3df`](https://github.com/apache/cordova-plugin-camera/commit/7ddb3df))
|
|
||||||
- fix(android): return DATA_URL for ALLMEDIA if it's an image ([#382](https://github.com/apache/cordova-plugin-camera/issues/382)) ([`60e7795`](https://github.com/apache/cordova-plugin-camera/commit/60e7795))
|
|
||||||
- refactor(ios): [CB-13813](https://issues.apache.org/jira/browse/13813): Remove old iOS code ([#381](https://github.com/apache/cordova-plugin-camera/issues/381)) ([`ce77aab`](https://github.com/apache/cordova-plugin-camera/commit/ce77aab))
|
|
||||||
- feat(ios): [CB-13865](https://issues.apache.org/jira/browse/13865): (Ipad) Making popover Window Size configurable using popoverOptions - imagePicker ([#314](https://github.com/apache/cordova-plugin-camera/issues/314)) ([`cd72047`](https://github.com/apache/cordova-plugin-camera/commit/cd72047))
|
|
||||||
- chore(types): [CB-13837](https://issues.apache.org/jira/browse/13837): fix TypeScript Definition for CameraPopoverOptions ([#379](https://github.com/apache/cordova-plugin-camera/issues/379)) ([`86b0bf2`](https://github.com/apache/cordova-plugin-camera/commit/86b0bf2))
|
|
||||||
- docs(android): clarify android quirk of cameraDirection ([`a5a3d88`](https://github.com/apache/cordova-plugin-camera/commit/a5a3d88), [`bfbe4a1`](https://github.com/apache/cordova-plugin-camera/commit/bfbe4a1))
|
|
||||||
- chore(release): Bump minor version ([#370](https://github.com/apache/cordova-plugin-camera/issues/370)) ([`eed4433`](https://github.com/apache/cordova-plugin-camera/commit/eed4433))
|
|
||||||
- build: Remove automatic README generation ([#365](https://github.com/apache/cordova-plugin-camera/issues/365)) ([`07e8574`](https://github.com/apache/cordova-plugin-camera/commit/07e8574))
|
|
||||||
- docs: remove JIRA link ([`bcb26fb`](https://github.com/apache/cordova-plugin-camera/commit/bcb26fb))
|
|
||||||
- ci(travis): also accept terms for android sdk `android-27` ([`a346212`](https://github.com/apache/cordova-plugin-camera/commit/a346212))
|
|
||||||
- docs: remove outdated docs translations that haven't been touched for 3 years ([`403682b`](https://github.com/apache/cordova-plugin-camera/commit/403682b))
|
|
||||||
- fix(android): [CB-14097](https://issues.apache.org/jira/browse/14097): Fix crash when selecting some files with getPicture ([#322](https://github.com/apache/cordova-plugin-camera/issues/322)) ([`5c23b65`](https://github.com/apache/cordova-plugin-camera/commit/5c23b65))
|
|
||||||
- fix(browser): [CB-13384](https://issues.apache.org/jira/browse/13384): Added deprecation of video.src compatibility ([#288](https://github.com/apache/cordova-plugin-camera/issues/288)) ([`5163d38`](https://github.com/apache/cordova-plugin-camera/commit/5163d38))
|
|
||||||
- fix(browser): Remove audio flag from getUserMedia ([#284](https://github.com/apache/cordova-plugin-camera/issues/284)) ([`36343a8`](https://github.com/apache/cordova-plugin-camera/commit/36343a8))
|
|
||||||
- docs: replace warning emoji with warning unicode ([#317](https://github.com/apache/cordova-plugin-camera/issues/317)) ([`ead7d5e`](https://github.com/apache/cordova-plugin-camera/commit/ead7d5e))
|
|
||||||
- feat(android): Update engines to use variables ([#323](https://github.com/apache/cordova-plugin-camera/issues/323)) ([`6899c5e`](https://github.com/apache/cordova-plugin-camera/commit/6899c5e))
|
|
||||||
- feat(android): [CB-14017](https://issues.apache.org/jira/browse/14017): Make com.android.support:support-v4 version configurable ([#318](https://github.com/apache/cordova-plugin-camera/issues/318)) ([`e334656`](https://github.com/apache/cordova-plugin-camera/commit/e334656))
|
|
||||||
- refactor(android): [CB-14047](https://issues.apache.org/jira/browse/14047): CameraLauncher: Replacing Repeated String literals with final variables ([#319](https://github.com/apache/cordova-plugin-camera/issues/319)) ([`5ec121b`](https://github.com/apache/cordova-plugin-camera/commit/5ec121b))
|
|
||||||
- fix(windows): [CB-11714](https://issues.apache.org/jira/browse/11714): added extra check for content-type in savePhoto() without options.targetWidth/Height ([#242](https://github.com/apache/cordova-plugin-camera/issues/242)) ([`a201722`](https://github.com/apache/cordova-plugin-camera/commit/a201722), [`dc73954`](https://github.com/apache/cordova-plugin-camera/commit/dc73954), [`dca4b9c`](https://github.com/apache/cordova-plugin-camera/commit/dca4b9c), [`c1b9772`](https://github.com/apache/cordova-plugin-camera/commit/c1b9772), [`eb57b02`](https://github.com/apache/cordova-plugin-camera/commit/eb57b02))
|
|
||||||
|
|
||||||
|
|
||||||
### 4.0.3 (Apr 12, 2018)
|
|
||||||
* [CB-12593](https://issues.apache.org/jira/browse/CB-12593) **Android** Fix potential `FileProvider` conflicts
|
|
||||||
* Fix a mistake in the examples of usage descriptions (#313)
|
|
||||||
* CB-13854(ios): fix Camera opens in portrait orientation on iphones
|
|
||||||
* [CB-13415](https://issues.apache.org/jira/browse/CB-13415) **Android** Importing corrupt images using the Camera plugin crashes the app
|
|
||||||
|
|
||||||
### 4.0.2 (Jan 24, 2018)
|
|
||||||
* [CB-13781](https://issues.apache.org/jira/browse/CB-13781) (android) Fixed permissions request on **Android** 8 to save a photo into the photo album
|
|
||||||
* [CB-13747](https://issues.apache.org/jira/browse/CB-13747) Add build-tools-26.0.2 to travis
|
|
||||||
|
|
||||||
### 4.0.1 (Dec 27, 2017)
|
|
||||||
* CB-13701Fix to allow 4.0.0 version install
|
|
||||||
|
|
||||||
### 4.0.0 (Dec 15, 2017)
|
|
||||||
* [CB-13661](https://issues.apache.org/jira/browse/CB-13661) Remove deprecated platforms
|
|
||||||
|
|
||||||
### 3.0.0 (Nov 06, 2017)
|
|
||||||
* Added `cordova-OSX` support
|
|
||||||
* [CB-13515](https://issues.apache.org/jira/browse/CB-13515) (all): Add 'protective' entry to `cordovaDependencies`
|
|
||||||
* [CB-13332](https://issues.apache.org/jira/browse/CB-13332) (iOS): document `NSPhotoLibraryAddUsageDescription`
|
|
||||||
* [CB-13264](https://issues.apache.org/jira/browse/CB-13264) (iOS): Remove **iOS** usage descriptions
|
|
||||||
* [CB-13473](https://issues.apache.org/jira/browse/CB-13473) (CI) Removed **Browser** builds from AppVeyor
|
|
||||||
* [CB-13446](https://issues.apache.org/jira/browse/CB-13446) Sync template with previous doc changes
|
|
||||||
* [CB-13294](https://issues.apache.org/jira/browse/CB-13294) Removed `cordova-plugin-compat`
|
|
||||||
* [CB-13299](https://issues.apache.org/jira/browse/CB-13299) (CI) Fix **Android** builds
|
|
||||||
* [CB-12985](https://issues.apache.org/jira/browse/CB-12985) setup `eslint` and removed `jshint`
|
|
||||||
* [CB-13028](https://issues.apache.org/jira/browse/CB-13028) (CI) **Browser** builds on Travis and AppVeyor
|
|
||||||
* [CB-13002](https://issues.apache.org/jira/browse/CB-13002) (Android, **iOS**) Fix occasional Appium tests failures
|
|
||||||
* [CB-13000](https://issues.apache.org/jira/browse/CB-13000) (CI) Speed up **Android** builds
|
|
||||||
* [CB-12991](https://issues.apache.org/jira/browse/CB-12991) (CI) Updated CI badges
|
|
||||||
* [CB-12964](https://issues.apache.org/jira/browse/CB-12964) (android) Fix of bug when Pictures folder did not exist.
|
|
||||||
* [CB-12982](https://issues.apache.org/jira/browse/CB-12982) (Android, **iOS**) Appium tests: try to create a session harder
|
|
||||||
* [CB-12682](https://issues.apache.org/jira/browse/CB-12682) (ios, **Android**): changes cancel error message to be consistent for **iOS** **Android**
|
|
||||||
* [CB-12764](https://issues.apache.org/jira/browse/CB-12764) (android) Adapt Appium tests for **Android** 7
|
|
||||||
* [CB-12847](https://issues.apache.org/jira/browse/CB-12847) added `bugs` entry to `package.json`.
|
|
||||||
|
|
||||||
### 2.4.1 (Apr 27, 2017)
|
|
||||||
* [CB-12622](https://issues.apache.org/jira/browse/CB-12622) Updated build badges in `README`
|
|
||||||
* [CB-12650](https://issues.apache.org/jira/browse/CB-12650) Fix manual test for uploading image
|
|
||||||
* [CB-12685](https://issues.apache.org/jira/browse/CB-12685) added `package.json` to tests folder
|
|
||||||
* [CB-12622](https://issues.apache.org/jira/browse/CB-12622) (android) Appium tests: Bust **Android** 6 and 7 permission dialogs
|
|
||||||
* [CB-12618](https://issues.apache.org/jira/browse/CB-12618) (android) Appium tests: Handle native cling
|
|
||||||
|
|
||||||
### 2.4.0 (Feb 28, 2017)
|
|
||||||
* [CB-12501](https://issues.apache.org/jira/browse/CB-12501) **Android**: Appium tests don't use `XPath` selectors anymore
|
|
||||||
* [CB-12469](https://issues.apache.org/jira/browse/CB-12469) Appium tests can now run on **iOS 10**
|
|
||||||
* [CB-12005](https://issues.apache.org/jira/browse/CB-12005) Changing the `getOrientation` method to return the defined enumerated `EXIF` instead of orientation in degrees for Consistency
|
|
||||||
* [CB-12368](https://issues.apache.org/jira/browse/CB-12368) Fix permission check on **Android**
|
|
||||||
* [CB-12353](https://issues.apache.org/jira/browse/CB-12353) Corrected merges usage in `plugin.xml`
|
|
||||||
* [CB-12369](https://issues.apache.org/jira/browse/CB-12369) Add plugin typings from `DefinitelyTyped`
|
|
||||||
* [CB-12363](https://issues.apache.org/jira/browse/CB-12363) Added build badges for **iOS 9.3** and **iOS 10.0**
|
|
||||||
* [CB-12312](https://issues.apache.org/jira/browse/CB-12312) [Appium] [Android] A few changes to the tests: - updated comments on how to run the tests. extra comments around functionality at certain points in the automation. - stub of a resolution checker on test startup - still need to figure out acceptable values. - moved session shutdown to an afterAll clause. - changed resolution determiner from using webview-based values to using the native windows dimensions - this helps as the webview values may be scaled down intentionally by manufacturers (via changing devicePixelRatio). furthermore, since the screen dimension automation is used purely for native UI automation, better to use the dimensions reported by the native context rather than the web context. - when finding elements by XPath, use multiple calls to avoid a Windows emulator + Android bug. Made this pattern consistent in the entire test.
|
|
||||||
* [CB-12236](https://issues.apache.org/jira/browse/CB-12236) - Fixed RELEASENOTES for cordova-plugin-camera
|
|
||||||
* [CB-12230](https://issues.apache.org/jira/browse/CB-12230) Removed Windows 8.1 build badges
|
|
||||||
|
|
||||||
### 2.3.1 (Dec 07, 2016)
|
|
||||||
* [CB-12224](https://issues.apache.org/jira/browse/CB-12224) Updated version and RELEASENOTES.md for release 2.3.1
|
|
||||||
* Fix missing license headers.
|
|
||||||
* [CB-12086](https://issues.apache.org/jira/browse/CB-12086) Regenerate README.md from template
|
|
||||||
* Added NSPhotoLibraryUsageDescription parameter to example install command Fixing some usages of NSPhotoLibraryUsageDescriptionentry
|
|
||||||
* Updating compat dependency to 1.1.0 or better
|
|
||||||
* [CB-11625](https://issues.apache.org/jira/browse/CB-11625) Forgot to add CordovaUri.java to plugin.xml
|
|
||||||
* [CB-11625](https://issues.apache.org/jira/browse/CB-11625) Files Provider does not work with Android 4.4.4 or lower, and I have no idea why. Working around with CordovaUri
|
|
||||||
* [CB-11625](https://issues.apache.org/jira/browse/CB-11625) (Android) : Make this work with previous versions of Cordova via cordova-plugin-compat
|
|
||||||
* BuildConfig from test project crept in source code thanks to Android Studio, removing
|
|
||||||
* [CB-11625](https://issues.apache.org/jira/browse/CB-11625) Managed to get Content Providers to work with a weird mix of Content Providers and non-Content Providers
|
|
||||||
* [CB-11625](https://issues.apache.org/jira/browse/CB-11625) Working on fix to API 24 no longer allowing File URIs to be passed across intents
|
|
||||||
* [CB-11917](https://issues.apache.org/jira/browse/CB-11917) - Remove pull request template checklist item: "iCLA has been submitted…"
|
|
||||||
* [CB-11832](https://issues.apache.org/jira/browse/CB-11832) Incremented plugin version.
|
|
||||||
|
|
||||||
### 2.3.0 (Sep 08, 2016)
|
|
||||||
* [CB-11795](https://issues.apache.org/jira/browse/CB-11795) Add 'protective' entry to cordovaDependencies
|
|
||||||
* [CB-11661](https://issues.apache.org/jira/browse/CB-11661) Add mandatory **iOS 10** privacy description
|
|
||||||
* [CB-11714](https://issues.apache.org/jira/browse/CB-11714) **windows** added more explicit content-type when converting to target data on canvas
|
|
||||||
* [CB-11295](https://issues.apache.org/jira/browse/CB-11295) Add **WP8.1** quirk when choosing image from `photoalbum`
|
|
||||||
* [CB-10067](https://issues.apache.org/jira/browse/CB-10067) Update `PictureSourceType` JSDoc to reflect `README` update
|
|
||||||
* [CB-9070](https://issues.apache.org/jira/browse/CB-9070) Update `CameraPopoverHandle` docs to reflect `README` update
|
|
||||||
* Plugin uses `Android Log class` and not `Cordova LOG class`
|
|
||||||
* [CB-11631](https://issues.apache.org/jira/browse/CB-11631) Appium tests: A working fix for a flaky `selection canceled` failure
|
|
||||||
* [CB-11709](https://issues.apache.org/jira/browse/CB-11709) Tests should use `resolveLocalFileSystemURL()` instead of deprecated `resolveFileSystemURI()`
|
|
||||||
* [CB-11695](https://issues.apache.org/jira/browse/CB-11695) Increased session creation timeout for Appium tests
|
|
||||||
* [CB-11656](https://issues.apache.org/jira/browse/CB-11656) (**Android**) Appium tests: Fixed side menu opening on some more resolutions
|
|
||||||
* [CB-11376](https://issues.apache.org/jira/browse/CB-11376) (**ios**): fix `CameraUsesGeolocation` error
|
|
||||||
* [CB-10067](https://issues.apache.org/jira/browse/CB-10067) (**ios**) clarifications on `PictureSourceType`
|
|
||||||
* [CB-11410](https://issues.apache.org/jira/browse/CB-11410) (**ios**) fix `cameraPopoverHandle.setPosition`
|
|
||||||
* [CB-9070](https://issues.apache.org/jira/browse/CB-9070) (**ios**) Fixed `CameraPopoverHandle` documentation
|
|
||||||
* [CB-11447](https://issues.apache.org/jira/browse/CB-11447) Respect output format when retrieving images from gallery
|
|
||||||
* [CB-11447](https://issues.apache.org/jira/browse/CB-11447) Resolve **iOS** tests failures due to **iOS** quirks
|
|
||||||
* [CB-11553](https://issues.apache.org/jira/browse/CB-11553) Pend failing Appium tests on Sauce Labs for the time being (reverted from commit b69571724035f41642f3ee612c5b66e1f0c4386c)
|
|
||||||
* [CB-11553](https://issues.apache.org/jira/browse/CB-11553) Pend failing Appium tests on Sauce Labs for the time being
|
|
||||||
* [CB-11498](https://issues.apache.org/jira/browse/CB-11498) [**Android**] Appium tests should not fail when there is no camera
|
|
||||||
* Add badges for paramedic builds on Jenkins
|
|
||||||
* [CB-11296](https://issues.apache.org/jira/browse/CB-11296) Appium: Better element clicking and session error handling
|
|
||||||
* [CB-11232](https://issues.apache.org/jira/browse/CB-11232) Appium tests: fixed element tapping on **iOS 9**
|
|
||||||
* [CB-11183](https://issues.apache.org/jira/browse/CB-11183) Appium tests: Added image verification
|
|
||||||
* fixed some bad formatting that hid `HTML` tags and added link to sample
|
|
||||||
* Set **android** quality default value to 50 on the java code
|
|
||||||
* Moving message in PR template to a comment
|
|
||||||
* Add pull request template. This closes #213
|
|
||||||
* [CB-11228](https://issues.apache.org/jira/browse/CB-11228) **browser**: Add classes for styling purposes
|
|
||||||
* [CB-10139](https://issues.apache.org/jira/browse/CB-10139) **browser**: Respect target width and height
|
|
||||||
* [CB-11227](https://issues.apache.org/jira/browse/CB-11227) **browser**: Fix incorrect `mime type`
|
|
||||||
* [CB-11162](https://issues.apache.org/jira/browse/CB-11162) Appium tests: retry spec on failure
|
|
||||||
* [CB-4078](https://issues.apache.org/jira/browse/CB-4078) Fix for `orientation/scaling` on **Android 4.4+** devices
|
|
||||||
* [CB-11165](https://issues.apache.org/jira/browse/CB-11165) removed peer dependency
|
|
||||||
* [CB-11147](https://issues.apache.org/jira/browse/CB-11147) Appium tests: generate descriptive spec names
|
|
||||||
* [CB-10996](https://issues.apache.org/jira/browse/CB-10996) Adding front matter to `README.md`
|
|
||||||
* [CB-11128](https://issues.apache.org/jira/browse/CB-11128) Appum tests: Fixed some of the flaky failures
|
|
||||||
* [CB-11003](https://issues.apache.org/jira/browse/CB-11003) Added Sample section to the Camera plugin README
|
|
||||||
|
|
||||||
### 2.2.0 (Apr 15, 2016)
|
|
||||||
* [CB-10873](https://issues.apache.org/jira/browse/CB-10873) Avoid crash due to usage of uninitialized variable when writing geolocation data to image destination. Properly handle 'CameraUsesGeolocation' option by properly setting geolocation data in EXIF header in all cases
|
|
||||||
* [CB-11073](https://issues.apache.org/jira/browse/CB-11073) Appium tests stability improvements
|
|
||||||
* Replace `PermissionHelper.java` with `cordova-plugin-compat`
|
|
||||||
* Making focus handler work only for **windows 10** phone
|
|
||||||
* [CB-10865](https://issues.apache.org/jira/browse/CB-10865) Run **ios** native tests on **Travis**
|
|
||||||
* [CB-10120](https://issues.apache.org/jira/browse/CB-10120) Fixing use of constants and `PermissionHelper`
|
|
||||||
* [CB-10120](https://issues.apache.org/jira/browse/CB-10120) Fix missing CAMERA permission for **Android M**
|
|
||||||
* [CB-10756](https://issues.apache.org/jira/browse/CB-10756) Adding sterner warnings about `DATA_URL`
|
|
||||||
* [CB-10460](https://issues.apache.org/jira/browse/CB-10460) `getRealPath` return null in some cases
|
|
||||||
|
|
||||||
### 2.1.1 (Mar 09, 2016)
|
|
||||||
* [CB-10825](https://issues.apache.org/jira/browse/CB-10825) **Android** should request READ permission for gallery source
|
|
||||||
* added apache license header to appium files
|
|
||||||
* [CB-10720](https://issues.apache.org/jira/browse/CB-10720) Fixed spelling, capitalization, and other small issues.
|
|
||||||
* [CB-10414](https://issues.apache.org/jira/browse/CB-10414) Adding focus handler to resume video when user comes back on leaving the app while preview was running
|
|
||||||
* Appium tests: adjust swipe distance on **Android**
|
|
||||||
* [CB-10750](https://issues.apache.org/jira/browse/CB-10750) Appium tests: fail fast if session is irrecoverable
|
|
||||||
* Adding missing semi colon
|
|
||||||
* Adding focus handler to make sure filepicker gets launched when app is active on **Windows**
|
|
||||||
* [CB-10128](https://issues.apache.org/jira/browse/CB-10128) **iOS** Fixed how checks access authorization to camera & library. This closes #146
|
|
||||||
* [CB-10636](https://issues.apache.org/jira/browse/CB-10636) Add JSHint for plugins
|
|
||||||
* [CB-10639](https://issues.apache.org/jira/browse/CB-10639) Appium tests: Added some timeouts, Taking a screenshot on failure, Retry taking a picture up to 3 times, Try to restart the Appium session if it's lost
|
|
||||||
* [CB-10552](https://issues.apache.org/jira/browse/CB-10552) Replacing images in README.md.
|
|
||||||
* Added a lot of more cases to get the real path on **Android**
|
|
||||||
* [CB-10625](https://issues.apache.org/jira/browse/CB-10625) **Android** getPicture fails when getting a photo from the Photo Library - Google Photos
|
|
||||||
* [CB-10619](https://issues.apache.org/jira/browse/CB-10619) Appium tests: Properly switch to webview on **Android**
|
|
||||||
* [CB-10397](https://issues.apache.org/jira/browse/CB-10397) Added Appium tests
|
|
||||||
* [CB-10576](https://issues.apache.org/jira/browse/CB-10576) MobileSpec can't get results for **Windows**-Store 8.1 Builds
|
|
||||||
* chore: edit package.json license to match SPDX id
|
|
||||||
* [CB-10539](https://issues.apache.org/jira/browse/CB-10539) Commenting out the verySmallQvga maxResolution option on **Windows**
|
|
||||||
* [CB-10541](https://issues.apache.org/jira/browse/CB-10541) Changing default maxResoltion to be highestAvailable for CameraCaptureUI on **Windows**
|
|
||||||
* [CB-10113](https://issues.apache.org/jira/browse/CB-10113) **Browse** - Layer camera UI on top of all!
|
|
||||||
* [CB-10502](https://issues.apache.org/jira/browse/CB-10502) **Browser** - Fix camera plugin exception in Chrome when click capture.
|
|
||||||
* Adding comments
|
|
||||||
* Camera tapping fix on **Windows**
|
|
||||||
|
|
||||||
### 2.1.0 (Jan 15, 2016)
|
|
||||||
* added `.ratignore`
|
|
||||||
* [CB-10319](https://issues.apache.org/jira/browse/CB-10319) **Android** Adding reflective helper methods for permission requests
|
|
||||||
* [CB-9189](https://issues.apache.org/jira/browse/CB-9189) **Android** Implementing `save/restore` API to handle Activity destruction
|
|
||||||
* [CB-10241](https://issues.apache.org/jira/browse/CB-10241) App Crash cause by Camera Plugin **iOS 7**
|
|
||||||
* [CB-8940](https://issues.apache.org/jira/browse/CB-8940) Setting `z-index` values to maximum for UI buttons.
|
|
||||||
|
|
||||||
### 2.0.0 (Nov 18, 2015)
|
|
||||||
* [CB-10035](https://issues.apache.org/jira/browse/CB-10035) Updated `RELEASENOTES` to be newest to oldest
|
|
||||||
* [CB-8863](https://issues.apache.org/jira/browse/CB-8863) correct block usage for `async` calls
|
|
||||||
* [CB-5479](https://issues.apache.org/jira/browse/CB-5479) changed `saveToPhotoAlbum` to save uncompressed images for **Android**
|
|
||||||
* [CB-9169](https://issues.apache.org/jira/browse/CB-9169) Fixed `filetype` for uncompressed images and added quirk for **Android**
|
|
||||||
* [CB-9446](https://issues.apache.org/jira/browse/CB-9446) Removing `CordovaResource` library code in favour of the code we're supposed to be deprecating because that at least works.
|
|
||||||
* [CB-9942](https://issues.apache.org/jira/browse/CB-9942) Normalize line endings in Camera plugin docs
|
|
||||||
* [CB-9910](https://issues.apache.org/jira/browse/CB-9910) Add permission request for some gallery requests for **Android**
|
|
||||||
* [CB-7668](https://issues.apache.org/jira/browse/CB-7668) Adding a sterner warning for `allowedit` on **Android**
|
|
||||||
* Fixing contribute link.
|
|
||||||
* Using the `CordovaResourceApi` to fine paths of files in the background thread. If the file doesn't exist, return the content `URI`.
|
|
||||||
* Add engine tag for **Cordova-Android 5.0.x**
|
|
||||||
* [CB-9583](https://issues.apache.org/jira/browse/CB-9583): Added support for **Marshmallow** permissions (**Android 6.0**)
|
|
||||||
* Try to use `realpath` filename instead of default `modified.jpg`
|
|
||||||
* [CB-6190](https://issues.apache.org/jira/browse/CB-6190) **iOS** camera plugin ignores quality parameter
|
|
||||||
* [CB-9633](https://issues.apache.org/jira/browse/CB-9633) **iOS** Taking a Picture With Option `destinationType:NATIVE_URI` doesn't show image
|
|
||||||
* [CB-9745](https://issues.apache.org/jira/browse/CB-9745) Camera plugin docs should be generated from the source
|
|
||||||
* [CB-9622](https://issues.apache.org/jira/browse/CB-9622) **WP8** Camera Option `destinationType:NATIVE_URI` is a `NO-OP`
|
|
||||||
* [CB-9623](https://issues.apache.org/jira/browse/CB-9623) Fixes various issues when `encodingType` set to `png`
|
|
||||||
* [CB-9591](https://issues.apache.org/jira/browse/CB-9591) Retaining aspect ratio when resizing
|
|
||||||
* [CB-9443](https://issues.apache.org/jira/browse/CB-9443) Pick correct `maxResolution`
|
|
||||||
* [CB-9151](https://issues.apache.org/jira/browse/CB-9151) Trigger `captureAction` only once
|
|
||||||
* [CB-9413](https://issues.apache.org/jira/browse/CB-9413) Close `RandomAccessStream` once copied
|
|
||||||
* [CB-5661](https://issues.apache.org/jira/browse/CB-5661) Remove outdated **iOS** quirks about memory
|
|
||||||
* [CB-9349](https://issues.apache.org/jira/browse/CB-9349) Focus control and nice UI
|
|
||||||
* [CB-9259](https://issues.apache.org/jira/browse/CB-9259) Forgot to add another check on which `URI` we're using when fixing this thing the first time
|
|
||||||
* [CB-9247](https://issues.apache.org/jira/browse/CB-9247) Added macro to conditionally add `NSData+Base64.h`
|
|
||||||
* [CB-9247](https://issues.apache.org/jira/browse/CB-9247) Fixes compilation errors with **cordova-ios 4.x**
|
|
||||||
* Fix returning native url on **Windows**.
|
|
||||||
|
|
||||||
### 1.2.0 (Jun 17, 2015)
|
|
||||||
* Closing stale pull request: close #84
|
|
||||||
* Closing stale pull request: close #66
|
|
||||||
* [CB-9128](https://issues.apache.org/jira/browse/CB-9128) cordova-plugin-camera documentation translation: cordova-plugin-camera
|
|
||||||
* Update docs. This closes #100
|
|
||||||
* attempt to fix npm markdown issue
|
|
||||||
* [CB-8883](https://issues.apache.org/jira/browse/CB-8883) fix picture rotation issue
|
|
||||||
* one more alias
|
|
||||||
* Fixed some nit white-space issues, aliased a little more
|
|
||||||
* major refactor : readability
|
|
||||||
* Patch for [CB-8498](https://issues.apache.org/jira/browse/CB-8498), this closes #64
|
|
||||||
* [CB-8879](https://issues.apache.org/jira/browse/CB-8879) fix stripe issue with correct aspect ratio
|
|
||||||
* [CB-8601](https://issues.apache.org/jira/browse/CB-8601) - iOS camera unit tests broken
|
|
||||||
* [CB-7667](https://issues.apache.org/jira/browse/CB-7667) iOS8: Handle case where camera is not authorized (closes #49)
|
|
||||||
* add missing license header
|
|
||||||
|
|
||||||
### 1.1.0 (May 06, 2015)
|
|
||||||
* [CB-8943](https://issues.apache.org/jira/browse/CB-8943) fix `PickAndContinue` issue on *Win10Phone*
|
|
||||||
* [CB-8253](https://issues.apache.org/jira/browse/CB-8253) Fix potential unreleased resources
|
|
||||||
* [CB-8909](https://issues.apache.org/jira/browse/CB-8909): Remove unused import from File
|
|
||||||
* [CB-8404](https://issues.apache.org/jira/browse/CB-8404) typo fix `cameraproxy.js`
|
|
||||||
* [CB-8404](https://issues.apache.org/jira/browse/CB-8404) Rotate camera feed with device orientation
|
|
||||||
* [CB-8054](https://issues.apache.org/jira/browse/CB-8054) Support taking pictures from file for *WP8*
|
|
||||||
* [CB-8405](https://issues.apache.org/jira/browse/CB-8405) Use `z-index` instead of `z-order`
|
|
||||||
|
|
||||||
### 1.0.0 (Apr 15, 2015)
|
|
||||||
* [CB-8780](https://issues.apache.org/jira/browse/CB-8780) - Display popover using main thread. Fixes popover slowness (closes #81)
|
|
||||||
* [CB-8746](https://issues.apache.org/jira/browse/CB-8746) bumped version of file dependency
|
|
||||||
* [CB-8746](https://issues.apache.org/jira/browse/CB-8746) gave plugin major version bump
|
|
||||||
* [CB-8707](https://issues.apache.org/jira/browse/CB-8707) refactoring windows code to improve readability
|
|
||||||
* [CB-8706](https://issues.apache.org/jira/browse/CB-8706) use filePicker if saveToPhotoAlbum is true
|
|
||||||
* [CB-8706](https://issues.apache.org/jira/browse/CB-8706) remove unnecessary capabilities from xml
|
|
||||||
* [CB-8747](https://issues.apache.org/jira/browse/CB-8747) updated dependency, added peer dependency
|
|
||||||
* [CB-8683](https://issues.apache.org/jira/browse/CB-8683) updated blackberry specific references of org.apache.cordova.camera to cordova-plugin-camera
|
|
||||||
* [CB-8782](https://issues.apache.org/jira/browse/CB-8782): Updated the docs to talk about the allowEdit quirks, it's not 100% working, but better than it was
|
|
||||||
* [CB-8782](https://issues.apache.org/jira/browse/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](https://issues.apache.org/jira/browse/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](https://issues.apache.org/jira/browse/CB-8740): Partial fix for Save Image to Gallery error found in MobileSpec
|
|
||||||
* [CB-8683](https://issues.apache.org/jira/browse/CB-8683) changed plugin-id to pacakge-name
|
|
||||||
* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) properly updated translated docs to use new id
|
|
||||||
* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) updated translated docs to use new id
|
|
||||||
* [CB-8351](https://issues.apache.org/jira/browse/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](https://issues.apache.org/jira/browse/CB-8653) Updated Readme
|
|
||||||
* [CB-8659](https://issues.apache.org/jira/browse/CB-8659): ios: 4.0.x Compatibility: Remove use of deprecated headers
|
|
||||||
|
|
||||||
### 0.3.6 (Mar 10, 2015)
|
|
||||||
* Fix localize key for Videos. This closes #58
|
|
||||||
* [CB-8235](https://issues.apache.org/jira/browse/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](https://issues.apache.org/jira/browse/CB-8599) fix threading issue with cameraPicker (fixes #72)
|
|
||||||
* [CB-8559](https://issues.apache.org/jira/browse/CB-8559) Integrate TravisCI
|
|
||||||
* [CB-8438](https://issues.apache.org/jira/browse/CB-8438) cordova-plugin-camera documentation translation: cordova-plugin-camera
|
|
||||||
* [CB-8538](https://issues.apache.org/jira/browse/CB-8538) Added package.json file
|
|
||||||
|
|
||||||
### 0.3.5 (Feb 04, 2015)
|
|
||||||
* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) ios: Stop using now-deprecated [NSData base64EncodedString]
|
|
||||||
* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) ios: Stop using now-deprecated integerValueForKey: class extension
|
|
||||||
* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) ios: Use argumentForIndex rather than NSArray extension
|
|
||||||
* [CB-8032](https://issues.apache.org/jira/browse/CB-8032) ios: Add nativeURL external method support for CDVFileSystem->makeEntryForPath:isDirectory:
|
|
||||||
* [CB-7938](https://issues.apache.org/jira/browse/CB-7938) ios: Added XCTest unit tests project, with stubs (adapted from SplashScreen unit test setup)
|
|
||||||
* [CB-7937](https://issues.apache.org/jira/browse/CB-7937) ios: Re-factor iOS Camera plugin so that it is testable
|
|
||||||
|
|
||||||
### 0.3.4 (Dec 02, 2014)
|
|
||||||
* [CB-7977](https://issues.apache.org/jira/browse/CB-7977) Mention `deviceready` in plugin docs
|
|
||||||
* [CB-7979](https://issues.apache.org/jira/browse/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](https://issues.apache.org/jira/browse/CB-7700) cordova-plugin-camera documentation translation: cordova-plugin-camera
|
|
||||||
|
|
||||||
### 0.3.3 (Oct 03, 2014)
|
|
||||||
* [CB-7600](https://issues.apache.org/jira/browse/CB-7600) Adds informative message to error callback in manual test.
|
|
||||||
|
|
||||||
### 0.3.2 (Sep 17, 2014)
|
|
||||||
* [CB-7551](https://issues.apache.org/jira/browse/CB-7551) [Camera][iOS 8] Scaled images show a white line
|
|
||||||
* [CB-7558](https://issues.apache.org/jira/browse/CB-7558) hasPendingOperation flag in Camera plugin's takePicture should be reversed to fix memory errors
|
|
||||||
* [CB-7557](https://issues.apache.org/jira/browse/CB-7557) Camera plugin tests is missing a File dependency
|
|
||||||
* [CB-7423](https://issues.apache.org/jira/browse/CB-7423) do cleanup after copyImage manual test
|
|
||||||
* [CB-7471](https://issues.apache.org/jira/browse/CB-7471) cordova-plugin-camera documentation translation: cordova-plugin-camera
|
|
||||||
* [CB-7413](https://issues.apache.org/jira/browse/CB-7413) Resolve 'ms-appdata' URIs with File plugin
|
|
||||||
* Fixed minor bugs with the browser
|
|
||||||
* [CB-7433](https://issues.apache.org/jira/browse/CB-7433) Adds missing window reference to prevent manual tests failure on Android and iOS
|
|
||||||
* [CB-7249](https://issues.apache.org/jira/browse/CB-7249) cordova-plugin-camera documentation translation: cordova-plugin-camera
|
|
||||||
* [CB-4003](https://issues.apache.org/jira/browse/CB-4003) Add config option to not use location information in Camera plugin (and default to not use it)
|
|
||||||
* [CB-7461](https://issues.apache.org/jira/browse/CB-7461) Geolocation fails in Camera plugin in iOS 8
|
|
||||||
* [CB-7378](https://issues.apache.org/jira/browse/CB-7378) Use single Proxy for both windows8 and windows.
|
|
||||||
* [CB-7378](https://issues.apache.org/jira/browse/CB-7378) Adds support for windows platform
|
|
||||||
* [CB-7433](https://issues.apache.org/jira/browse/CB-7433) Fixes manual tests failure on windows
|
|
||||||
* [CB-6958](https://issues.apache.org/jira/browse/CB-6958) Get the correct default for "quality" in the test
|
|
||||||
* add documentation for manual tests
|
|
||||||
* [CB-7249](https://issues.apache.org/jira/browse/CB-7249) cordova-plugin-camera documentation translation: cordova-plugin-camera
|
|
||||||
* [CB-4003](https://issues.apache.org/jira/browse/CB-4003) Add config option to not use location information in Camera plugin (and default to not use it)
|
|
||||||
* [CB-7461](https://issues.apache.org/jira/browse/CB-7461) Geolocation fails in Camera plugin in iOS 8
|
|
||||||
* [CB-7433](https://issues.apache.org/jira/browse/CB-7433) Fixes manual tests failure on windows
|
|
||||||
* [CB-7378](https://issues.apache.org/jira/browse/CB-7378) Use single Proxy for both windows8 and windows.
|
|
||||||
* [CB-7378](https://issues.apache.org/jira/browse/CB-7378) Adds support for windows platform
|
|
||||||
* [CB-6958](https://issues.apache.org/jira/browse/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](https://issues.apache.org/jira/browse/CB-7286) [BlackBerry10] Use getUserMedia if camera card is unavailable
|
|
||||||
* [CB-7180](https://issues.apache.org/jira/browse/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](https://issues.apache.org/jira/browse/CB-6958) added manual tests
|
|
||||||
* [CB-6958](https://issues.apache.org/jira/browse/CB-6958) Port camera tests to plugin-test-framework
|
|
||||||
|
|
||||||
### 0.3.1 (Aug 06, 2014)
|
|
||||||
* **FFOS** update CameraProxy.js
|
|
||||||
* [CB-7187](https://issues.apache.org/jira/browse/CB-7187) ios: Add explicit dependency on CoreLocation.framework
|
|
||||||
* [BlackBerry10] Doc correction - sourceType is supported
|
|
||||||
* [CB-7071](https://issues.apache.org/jira/browse/CB-7071) android: Fix callback firing before CROP intent is sent when allowEdit=true
|
|
||||||
* [CB-6875](https://issues.apache.org/jira/browse/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](https://issues.apache.org/jira/browse/CB-6127) Updated translations for docs
|
|
||||||
|
|
||||||
### 0.3.0 (Jun 05, 2014)
|
|
||||||
* [CB-5895](https://issues.apache.org/jira/browse/CB-5895) documented saveToPhotoAlbum quirk on WP8
|
|
||||||
* Remove deprecated symbols for iOS < 6
|
|
||||||
* documentation translation: cordova-plugin-camera
|
|
||||||
* ubuntu: use application directory for images
|
|
||||||
* [CB-6795](https://issues.apache.org/jira/browse/CB-6795) Add license
|
|
||||||
* Little fix in code formatting
|
|
||||||
* [CB-6613](https://issues.apache.org/jira/browse/CB-6613) Use WinJS functionality to get base64-encoded content of image instead of File plugin functionality
|
|
||||||
* [CB-6612](https://issues.apache.org/jira/browse/CB-6612) camera.getPicture now always returns encoded JPEG image
|
|
||||||
* Removed invalid note from [CB-5398](https://issues.apache.org/jira/browse/CB-5398)
|
|
||||||
* [CB-6576](https://issues.apache.org/jira/browse/CB-6576) - Returns a specific error message when app has no access to library.
|
|
||||||
* [CB-6491](https://issues.apache.org/jira/browse/CB-6491) add CONTRIBUTING.md
|
|
||||||
* [CB-6546](https://issues.apache.org/jira/browse/CB-6546) android: Fix a couple bugs with allowEdit pull request
|
|
||||||
* [CB-6546](https://issues.apache.org/jira/browse/CB-6546) android: Add support for allowEdit Camera option
|
|
||||||
|
|
||||||
### 0.2.9 (Apr 17, 2014)
|
|
||||||
* [CB-6460](https://issues.apache.org/jira/browse/CB-6460): Update license headers
|
|
||||||
* [CB-6422](https://issues.apache.org/jira/browse/CB-6422): [windows8] use cordova/exec/proxy
|
|
||||||
* [WP8] When only targetWidth or targetHeight is provided, use it as the only bound
|
|
||||||
* [CB-4027](https://issues.apache.org/jira/browse/CB-4027), [CB-5102](https://issues.apache.org/jira/browse/CB-5102), [CB-2737](https://issues.apache.org/jira/browse/CB-2737), [CB-2387](https://issues.apache.org/jira/browse/CB-2387): [WP] Fix camera issues, cropping, memory leaks
|
|
||||||
* [CB-6212](https://issues.apache.org/jira/browse/CB-6212): [iOS] fix warnings compiled under arm64 64-bit
|
|
||||||
* [BlackBerry10] Add rim xml namespaces declaration
|
|
||||||
* Add NOTICE file
|
|
||||||
|
|
||||||
### 0.2.8 (Feb 26, 2014)
|
|
||||||
* [CB-1826](https://issues.apache.org/jira/browse/CB-1826) Catch OOM on gallery image resize
|
|
||||||
|
|
||||||
### 0.2.7 (Feb 05, 2014)
|
|
||||||
* [CB-4919](https://issues.apache.org/jira/browse/CB-4919) firefox os quirks added and supported platforms list is updated
|
|
||||||
* getPicture via web activities
|
|
||||||
* Documented quirk for [CB-5335](https://issues.apache.org/jira/browse/CB-5335) + [CB-5206](https://issues.apache.org/jira/browse/CB-5206) for WP7+8
|
|
||||||
* reference the correct firefoxos implementation
|
|
||||||
* [BlackBerry10] Add permission to access_shared
|
|
||||||
|
|
||||||
### 0.2.6 (Jan 02, 2014)
|
|
||||||
* [CB-5658](https://issues.apache.org/jira/browse/CB-5658) Add doc/index.md for Camera plugin
|
|
||||||
* [CB-2442](https://issues.apache.org/jira/browse/CB-2442) [CB-2419](https://issues.apache.org/jira/browse/CB-2419) Use Windows.Storage.ApplicationData.current.localFolder, instead of writing to app package.
|
|
||||||
* [BlackBerry10] Adding platform level permissions
|
|
||||||
* [CB-5599](https://issues.apache.org/jira/browse/CB-5599) Android: Catch and ignore OutOfMemoryError in getRotatedBitmap()
|
|
||||||
|
|
||||||
### 0.2.5 (Dec 4, 2013)
|
### 0.2.5 (Dec 4, 2013)
|
||||||
* fix camera for firefox os
|
* fix camera for firefox os
|
||||||
@ -421,30 +56,113 @@
|
|||||||
* 1. User Agent detection now detects AmazonWebView. 2. Change to use amazon-fireos as the platform if user agent string contains 'cordova-amazon-fireos'
|
* 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.
|
* Added amazon-fireos platform.
|
||||||
|
|
||||||
### 0.2.4 (Oct 28, 2013)
|
### 0.2.6 (Jan 02, 2014)
|
||||||
* [CB-5128](https://issues.apache.org/jira/browse/CB-5128): added repo + issue tag to plugin.xml for camera plugin
|
* CB-5658 Add doc/index.md for Camera plugin
|
||||||
* [CB-4958](https://issues.apache.org/jira/browse/CB-4958) - iOS - Camera plugin should not show the status bar
|
* CB-2442 CB-2419 Use Windows.Storage.ApplicationData.current.localFolder, instead of writing to app package.
|
||||||
* [CB-4919](https://issues.apache.org/jira/browse/CB-4919) updated plugin.xml for FxOS
|
* [BlackBerry10] Adding platform level permissions
|
||||||
* [CB-4915](https://issues.apache.org/jira/browse/CB-4915) Incremented plugin version on dev branch.
|
* CB-5599 Android: Catch and ignore OutOfMemoryError in getRotatedBitmap()
|
||||||
|
|
||||||
### 0.2.3 (Sept 25, 2013)
|
### 0.2.7 (Feb 05, 2014)
|
||||||
* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) bumping&resetting version
|
* CB-4919 firefox os quirks added and supported platforms list is updated
|
||||||
* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) forgot index.html
|
* getPicture via web activities
|
||||||
* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) renaming core inside cameraProxy
|
* Documented quirk for CB-5335 + CB-5206 for WP7+8
|
||||||
* [Windows8] commandProxy has moved
|
* reference the correct firefoxos implementation
|
||||||
* [Windows8] commandProxy has moved
|
* [BlackBerry10] Add permission to access_shared
|
||||||
* added Camera API for FirefoxOS
|
|
||||||
* Rename CHANGELOG.md -> RELEASENOTES.md
|
|
||||||
* [CB-4823](https://issues.apache.org/jira/browse/CB-4823) Fix XCode 5 camera plugin warnings
|
|
||||||
* Fix compiler warnings
|
|
||||||
* [CB-4765](https://issues.apache.org/jira/browse/CB-4765) Move ExifHelper.java into Camera Plugin
|
|
||||||
* [CB-4764](https://issues.apache.org/jira/browse/CB-4764) Remove reference to DirectoryManager from CameraLauncher
|
|
||||||
* [CB-4763](https://issues.apache.org/jira/browse/CB-4763) Use a copy of FileHelper.java within camera-plugin.
|
|
||||||
* [CB-4752](https://issues.apache.org/jira/browse/CB-4752) Incremented plugin version on dev branch.
|
|
||||||
* [CB-4633](https://issues.apache.org/jira/browse/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](https://issues.apache.org/jira/browse/CB-4889) renaming org.apache.cordova.core.camera to org.apache.cordova.camera
|
|
||||||
|
|
||||||
### 0.2.1 (Sept 5, 2013)
|
### 0.2.8 (Feb 26, 2014)
|
||||||
* [CB-4656](https://issues.apache.org/jira/browse/CB-4656) Don't add line-breaks to base64-encoded images (Fixes type=DataURI)
|
* CB-1826 Catch OOM on gallery image resize
|
||||||
* [CB-4432](https://issues.apache.org/jira/browse/CB-4432) copyright notice change
|
|
||||||
|
### 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
|
||||||
|
409
doc/de/index.md
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
<!---
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# org.apache.cordova.camera
|
||||||
|
|
||||||
|
Dieses Plugin stellt eine API für Aufnahmen und für die Auswahl der Bilder aus dem System-Image-Library.
|
||||||
|
|
||||||
|
cordova plugin add org.apache.cordova.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 eine base64-codierte übergeben `String` , oder als den URI für die Image-Datei. 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 standardmäßig, wenn `Camera.sourceType` gleich `Camera.PictureSourceType.CAMERA` . Sobald der Benutzer die Fotoschnäpper, die Kameraanwendung geschlossen wird und die Anwendung wird wiederhergestellt.
|
||||||
|
|
||||||
|
Wenn `Camera.sourceType` ist `Camera.PictureSourceType.PHOTOLIBRARY` oder `Camera.PictureSourceType.SAVEDPHOTOALBUM` , dann ein Dialog-Displays, die Benutzern ermöglicht, ein vorhandenes Bild auszuwählen. Die `camera.getPicture` Funktion gibt ein `CameraPopoverHandle` -Objekt, das verwendet werden kann, um den Bild-Auswahl-Dialog, zum Beispiel beim ändert sich der Orientierung des Geräts neu positionieren.
|
||||||
|
|
||||||
|
Der Rückgabewert wird gesendet, um die `cameraSuccess` Callback-Funktion in einem der folgenden Formate, je nach dem angegebenen `cameraOptions` :
|
||||||
|
|
||||||
|
* 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 auch wenn ein `quality` -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
|
||||||
|
|
||||||
|
Darunter eine JavaScript `alert()` entweder des Rückrufs Funktionen können Probleme verursachen. Wickeln Sie die Warnung innerhalb einer `setTimeout()` erlauben die iOS-Bild-Picker oder Popover vollständig zu schließen, bevor die Warnung angezeigt:
|
||||||
|
|
||||||
|
setTimeout(function() {/ / Mach dein Ding hier!}, 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 eine `destinationType` der `Camera.DestinationType.FILE_URI` und eine `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.
|
||||||
|
|
||||||
|
{Qualität: 75, DestinationType: Camera.DestinationType.DATA_URL, SourceType: Camera.PictureSourceType.CAMERA, AllowEdit: stimmt, 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, Breite: 320, Höhe: 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)*
|
||||||
|
|
||||||
|
* **Breite**: Breite in Pixeln, das Bildschirmelement auf dem der Popover zu verankern. *(Anzahl)*
|
||||||
|
|
||||||
|
* **Höhe**: 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
|
||||||
|
|
||||||
|
Entfernt Mittelstufe Image-Dateien, die nach der Berufung in vorübergehender Verwahrung gehalten werden `camera.getPicture` . Gilt nur, wenn der Wert des `Camera.sourceType` ist gleich `Camera.PictureSourceType.CAMERA` und der `Camera.destinationType` entspricht`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);
|
||||||
|
}
|
424
doc/es/index.md
Normal file
@ -0,0 +1,424 @@
|
|||||||
|
<!---
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# org.apache.cordova.camera
|
||||||
|
|
||||||
|
Este plugin proporciona una API para tomar fotografías y por elegir imágenes de biblioteca de imágenes del sistema.
|
||||||
|
|
||||||
|
cordova plugin add org.apache.cordova.camera
|
||||||
|
|
||||||
|
|
||||||
|
## navigator.camera.getPicture
|
||||||
|
|
||||||
|
Toma una foto con la cámara, u obtiene una foto de la galería de imágenes del dispositivo. La imagen es retornada como un objeto `String` codificada en base64 o como la URI de esta. El método devuelve un objeto `CameraPopoverHandle` que puede usarse para reposicionar el diálogo de selección de archivo.
|
||||||
|
|
||||||
|
navigator.camera.getPicture( cameraSuccess, cameraError, cameraOptions );
|
||||||
|
|
||||||
|
|
||||||
|
### Descripción
|
||||||
|
|
||||||
|
La función `camera.getPicture` abre la aplicación predeterminada de cámara del dispositivo que permite a los usuarios tomar fotografías. Este comportamiento es el predeterminado, cuando `Camera.sourceType` es igual a `Camera.PictureSourceType.CAMERA`. Una vez que el usuario toma la foto, la aplicación de la cámara se cierra y se restablece la aplicación.
|
||||||
|
|
||||||
|
Si `Camera.sourceType` es `Camera.PictureSourceType.PHOTOLIBRARY` o `Camera.PictureSourceType.SAVEDPHOTOALBUM`, entonces aperece un cuadro de diálogo que permite a los usuarios seleccionar una imagen existente. La función `camera.getPicture` devuelve un objeto `CameraPopoverHandle`, que puede utilizarse para reposicionar el diálogo de selección de imagen, por ejemplo, cuando cambia la orientación del dispositivo.
|
||||||
|
|
||||||
|
El valor devuelto es enviado a la función `cameraSuccess`, en uno de los formatos siguientes, dependiendo de `cameraOptions` especificadas:
|
||||||
|
|
||||||
|
* 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 se especifica un parámetro de `quality`. Para evitar problemas comunes de memoria, establezca `Camera.destinationType` como `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 puede que no aparezca cuando se restaura la actividad de cordova.
|
||||||
|
|
||||||
|
### Rarezas Android
|
||||||
|
|
||||||
|
Android utiliza los intents para iniciar la actividad de la cámara del dispositivo para capturar imágenes y en teléfonos con poca memoria, la actividad de Cordova puede ser terminada. 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 las funciones de devolución de llamada puede causar problemas. Envolver la alerta dentro un `setTimeout()` para permitir el iOS image picker o popover cerrar completamente antes de Mostrar la alerta:
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
// do your thing here!
|
||||||
|
}, 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 admite 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 image = document.getElementById('myImage');
|
||||||
|
image.src = "data:image/jpeg;base64," + imageData;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFail(message) {
|
||||||
|
alert('Failed because: ' + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 image = document.getElementById('myImage');
|
||||||
|
image.src = imageURI;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFail(message) {
|
||||||
|
alert('Failed because: ' + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
## CameraOptions
|
||||||
|
|
||||||
|
Parámetros opcionales para personalizar la configuración de la cámara.
|
||||||
|
|
||||||
|
{ 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 };
|
||||||
|
|
||||||
|
|
||||||
|
### 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) {
|
||||||
|
// Show a helpful message
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### 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) {
|
||||||
|
// Do something with the image
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
|
// Show image
|
||||||
|
//
|
||||||
|
function cameraCallback(imageData) {
|
||||||
|
var image = document.getElementById('myImage');
|
||||||
|
image.src = "data: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: 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
|
||||||
|
|
||||||
|
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,
|
||||||
|
width : 320,
|
||||||
|
height : 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 los archivos de imagen intermedia que se mantienen en depósito temporal después de llamar a `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("Camera cleanup success.")
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFail(message) {
|
||||||
|
alert('Failed because: ' + message);
|
||||||
|
}
|
417
doc/fr/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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# org.apache.cordova.camera
|
||||||
|
|
||||||
|
Ce plugin fournit une API pour la prise de photos et de choisir des images de la bibliothèque d'images du système.
|
||||||
|
|
||||||
|
cordova plugin add org.apache.cordova.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ée au callback "succès" comme une `String` encodée en base64 ou l'URI du fichier de l'image. La méthode elle-même renvoie un objet `CameraPopoverHandle` qui permet de repositionner la boite de dialogue de selection d'image.
|
||||||
|
|
||||||
|
navigator.camera.getPicture( cameraSuccess, cameraError, cameraOptions );
|
||||||
|
|
||||||
|
|
||||||
|
### Description
|
||||||
|
|
||||||
|
La fonction `camera.getPicture` ouvre l'application 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 a pris la photo, l'application "camera" se ferme et l'application est restaurée.
|
||||||
|
|
||||||
|
Si `Camera.sourceType` est `Camera.PictureSourceType.PHOTOLIBRARY` ou `Camera.PictureSourceType.SAVEDPHOTOALBUM`, alors une boîte de dialogue s'affiche pour permettre aux utilisateurs de sélectionner une image existante. La fonction `camera.getPicture` retourne un objet `CameraPopoverHandle` 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 fonction callback `cameraSuccess`, dans l'un des formats suivants, selon spécifié par `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 encodée ou l'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. Les photos sélectionnées de la Galerie de l'appareil ne sont pas réduites avec une baisse de la qualité, même si un paramètre de `qualité` est spécifié. Pour éviter les problèmes de mémoire, définissez `Camera.destinationType` à `FILE_URI` plutôt que `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() {/ / votre code 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 = "data:image/jpeg;base64," + imageData;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFail(message) {
|
||||||
|
alert('Failed because: ' + 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('Failed because: ' + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
## CameraOptions
|
||||||
|
|
||||||
|
Paramètres optionnels pour personnaliser les réglages de l'appareil.
|
||||||
|
|
||||||
|
{ 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
|
||||||
|
|
||||||
|
* **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) {
|
||||||
|
// Show a helpful message
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### 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) {
|
||||||
|
// Do something with the image
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### Paramètres
|
||||||
|
|
||||||
|
* **imageData**: codage Base64 de l'image, *ou* le fichier image URI, selon `cameraOptions` en vigueur. *(String)*
|
||||||
|
|
||||||
|
### Exemple
|
||||||
|
|
||||||
|
// Show image
|
||||||
|
//
|
||||||
|
function cameraCallback(imageData) {
|
||||||
|
var image = document.getElementById('myImage');
|
||||||
|
image.src = "data: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,
|
||||||
|
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 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, width : 320, height : 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);
|
||||||
|
|
||||||
|
function onSuccess() {
|
||||||
|
console.log("Camera cleanup success.")
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFail(message) {
|
||||||
|
alert('Failed because: ' + message);
|
||||||
|
}
|
455
doc/index.md
Normal file
@ -0,0 +1,455 @@
|
|||||||
|
<!---
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# org.apache.cordova.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 org.apache.cordova.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
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
- Ignores the `allowEdit` parameter.
|
||||||
|
|
||||||
|
- `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);
|
||||||
|
}
|
||||||
|
|
409
doc/it/index.md
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
<!---
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# org.apache.cordova.camera
|
||||||
|
|
||||||
|
Questo plugin fornisce un'API per scattare foto e per aver scelto immagini dalla libreria di immagini del sistema.
|
||||||
|
|
||||||
|
cordova plugin add org.apache.cordova.camera
|
||||||
|
|
||||||
|
|
||||||
|
## navigator.camera.getPicture
|
||||||
|
|
||||||
|
Prende una foto utilizzando la fotocamera, o recupera una foto dalla galleria di immagini del dispositivo. L'immagine viene passata al metodo di callback successo come una codifica base64 `String` , o come l'URI per il file di immagine. Il metodo stesso restituisce un `CameraPopoverHandle` che può essere utilizzato per riposizionare il Muffin di selezione file.
|
||||||
|
|
||||||
|
navigator.camera.getPicture( cameraSuccess, cameraError, cameraOptions );
|
||||||
|
|
||||||
|
|
||||||
|
### Descrizione
|
||||||
|
|
||||||
|
il `camera.getPicture` funzione 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` , quindi un display finestra di dialogo che consente agli utenti di selezionare un'immagine esistente. La `camera.getPicture` la funzione restituisce un `CameraPopoverHandle` oggetto, che può essere utilizzato per riposizionare la finestra di selezione immagine, ad esempio, quando l'orientamento del dispositivo.
|
||||||
|
|
||||||
|
Il valore restituito viene inviato alla `cameraSuccess` funzione di callback, in uno dei seguenti formati, a seconda che l'oggetto specificato `cameraOptions` :
|
||||||
|
|
||||||
|
* 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 un `quality` è specificato il parametro. Per evitare problemi di memoria comune, impostare `Camera.destinationType` a `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 [Attività Web][2].
|
||||||
|
|
||||||
|
[2]: https://hacks.mozilla.org/2013/01/introducing-web-activities/
|
||||||
|
|
||||||
|
### iOS stranezze
|
||||||
|
|
||||||
|
Compreso un JavaScript `alert()` in entrambi il callback funzioni possono 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() {/ / fai la tua cosa qui!}, 0);
|
||||||
|
|
||||||
|
|
||||||
|
### Windows Phone 7 capricci
|
||||||
|
|
||||||
|
Richiamando l'applicazione nativa fotocamera mentre il dispositivo è collegato tramite Zune non funziona e innesca un callback di errore.
|
||||||
|
|
||||||
|
### Tizen stranezze
|
||||||
|
|
||||||
|
Tizen supporta solo un `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.
|
||||||
|
|
||||||
|
{qualità: 75, destinationType: Camera.DestinationType.DATA_URL, sourceType: Camera.PictureSourceType.CAMERA, allowEdit: vero, encodingType: Camera.EncodingType.JPEG, targetWidth: 100, targetHeight: 100, popoverOptions: CameraPopoverOptions, saveToPhotoAlbum: false};
|
||||||
|
|
||||||
|
|
||||||
|
### Opzioni
|
||||||
|
|
||||||
|
* **qualità**: 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
|
||||||
|
|
||||||
|
* **messaggio**: 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, larghezza: 320, altezza: 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)*
|
||||||
|
|
||||||
|
* **larghezza**: larghezza, in pixel, dell'elemento dello schermo su cui ancorare il muffin. *(Numero)*
|
||||||
|
|
||||||
|
* **altezza**: 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 intermedio i file di immagine che vengono tenuti in custodia temporanea dopo la chiamata `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);
|
||||||
|
}
|
409
doc/ja/index.md
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
<!---
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# org.apache.cordova.camera
|
||||||
|
|
||||||
|
このプラグインは写真を撮るため、システムのイメージ ライブラリからイメージを選択するために API を提供します。
|
||||||
|
|
||||||
|
cordova plugin add org.apache.cordova.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
|
||||||
|
* アンドロイド
|
||||||
|
* ブラックベリー 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()` 関数コールバックのいずれかの問題を引き起こすことができます。 内でアラートのラップ、 `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
|
||||||
|
|
||||||
|
カメラの設定をカスタマイズするオプションのパラメーター。
|
||||||
|
|
||||||
|
{品質: 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 です。 *(数)*(カメラの解像度についての情報が利用できないことに注意してください)。
|
||||||
|
|
||||||
|
* **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 のポップ オーバーの場所を指定する 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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### パラメーター
|
||||||
|
|
||||||
|
* **メッセージ**: メッセージは、デバイスのネイティブ コードによって提供されます。*(文字列)*
|
||||||
|
|
||||||
|
## 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、幅: 320、高さ: 480、arrowDir: Camera.PopoverArrowDirection.ARROW_ANY};
|
||||||
|
|
||||||
|
|
||||||
|
### CameraPopoverOptions
|
||||||
|
|
||||||
|
* **x**: ピクセルの x 座標画面要素にポップ オーバーのアンカーになります。*(数)*
|
||||||
|
|
||||||
|
* **y**: y ピクセル座標の画面要素にポップ オーバーのアンカーになります。*(数)*
|
||||||
|
|
||||||
|
* **幅**: ポップ オーバーのアンカーになる上の画面要素のピクセル単位の幅。*(数)*
|
||||||
|
|
||||||
|
* **高さ**: ポップ オーバーのアンカーになる上の画面要素のピクセル単位の高さ。*(数)*
|
||||||
|
|
||||||
|
* **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);
|
||||||
|
}
|
409
doc/ko/index.md
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
<!---
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# org.apache.cordova.camera
|
||||||
|
|
||||||
|
이 플러그인 사진 촬영을 위한 및 시스템의 이미지 라이브러리에서 이미지를 선택 하기 위한 API를 제공 합니다.
|
||||||
|
|
||||||
|
cordova plugin add org.apache.cordova.camera
|
||||||
|
|
||||||
|
|
||||||
|
## navigator.camera.getPicture
|
||||||
|
|
||||||
|
카메라를 사용 하 여 사진을 걸립니다 또는 소자의 이미지 갤러리에서 사진을 검색 합니다. 이미지 base64 인코딩으로 성공 콜백에 전달 됩니다 `String` , 또는 이미지 파일에 대 한 URI로. 방법 자체는 반환 합니다 한 `CameraPopoverHandle` 개체 파일 선택 popover를 재배치 하는 데 사용할 수 있습니다.
|
||||||
|
|
||||||
|
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`.
|
||||||
|
|
||||||
|
### 지원 되는 플랫폼
|
||||||
|
|
||||||
|
* 아마존 화재 운영 체제
|
||||||
|
* 안 드 로이드
|
||||||
|
* 블랙베리 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()` 함수는 콜백 중에 문제를 일으킬 수 있습니다. 내 경고를 래핑하는 `setTimeout()` 허용 iOS 이미지 피커 또는 popover를 완벽 하 게 경고를 표시 하기 전에 닫습니다:
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
카메라 설정을 사용자 지정 하는 선택적 매개 변수.
|
||||||
|
|
||||||
|
{품질: 75, destinationType: Camera.DestinationType.DATA_URL, sourceType: Camera.PictureSourceType.CAMERA, allowEdit: 사실, 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
|
||||||
|
|
||||||
|
에 의해 만들어진 popover 대화에 대 한 핸들`navigator.camera.getPicture`.
|
||||||
|
|
||||||
|
### 메서드
|
||||||
|
|
||||||
|
* **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, 폭: 320, 높이: 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);
|
||||||
|
}
|
424
doc/pl/index.md
Normal file
@ -0,0 +1,424 @@
|
|||||||
|
<!---
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# org.apache.cordova.camera
|
||||||
|
|
||||||
|
Wtyczka dostarcza API do robienia zdjęć i wybór zdjęć z biblioteki obrazu systemu.
|
||||||
|
|
||||||
|
cordova plugin add org.apache.cordova.camera
|
||||||
|
|
||||||
|
|
||||||
|
## navigator.camera.getPicture
|
||||||
|
|
||||||
|
Pobiera zdjęcia za pomocą aparatu lub z galerii zdjęć w urządzeniu. Obraz jest przekazywany do funkcji zwrotnej success jako `String` kodowany za pomocą base64 lub jako URI do pliku. Sama metoda zwraca obiekt `CameraPopoverHandle`, który może służyć do zmiany położenia wyskakującego okna wyboru pliku.
|
||||||
|
|
||||||
|
navigator.camera.getPicture( cameraSuccess, cameraError, cameraOptions );
|
||||||
|
|
||||||
|
|
||||||
|
### Opis
|
||||||
|
|
||||||
|
Funkcja `camera.getPicture` otwiera na urządzeniu domyślną aplikację aparatu, która pozwala użytkownikowi zrobić zdjęcie. To zachowanie występuje domyślnie, gdy `Camera.sourceType` jest równe `Camera.PictureSourceType.CAMERA`. Gdy użytkownik wykona zdjęcie, aplikacja aparatu zakończy działanie i nastąpi powrót do głównej aplikacji.
|
||||||
|
|
||||||
|
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łana do funkcji zwrotnej `cameraSuccess` w jednym z następujących formatów, w zależności od określonego parametru `cameraOptions`:
|
||||||
|
|
||||||
|
* `String` zawierający obraz zakodowany przy pomocy base64.
|
||||||
|
|
||||||
|
* `String` reprezentujący lokalizację pliku obrazu w lokalnym magazynie (domyślnie).
|
||||||
|
|
||||||
|
Z zakodowanym obrazem lub URI możesz zrobić co zechcesz, 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 nie są skalowane do niższej jakości, nawet jeśli określono parametr `quality`. Aby uniknąć typowych problemów z pamięcią lepiej ustawić`Camera.destinationType` na `FILE_URI` niż `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 takim scenariuszu obrazy mogą nie być wyświetlane po przywróceniu aktywności Cordovy.
|
||||||
|
|
||||||
|
### Dziwactwa Androida
|
||||||
|
|
||||||
|
Android używa Intencji (Intents) do uruchomienia aktywności aparatu i na urządzeniach z małą ilością dostępnej pamięci aktywność Cordova może zostać przerwana. 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
|
||||||
|
|
||||||
|
Umieszczenie w funkcji zwrotnej wywołania `alert()` w JavaScript może powodować problemy. Aby umożliwić systemowi iOS na całkowite zamknięcie okna wyboru obrazu lub wyskakującego powiadomienia przed wyświetleniem alarmu należy opakować go w `setTimeout()`:
|
||||||
|
|
||||||
|
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 parametr `destinationType` jako `Camera.DestinationType.FILE_URI` oraz `sourceType` jako `Camera.PictureSourceType.PHOTOLIBRARY`.
|
||||||
|
|
||||||
|
### Przykład
|
||||||
|
|
||||||
|
Zrobienie zdjęcia i pobranie go jako obraz zakodowany 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Zrobienie zdjęcia i pobranie lokacji 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 dostosowania ustawień 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, // umożliwia wybór tylko zdjęcia. DOMYŚLNIE. 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, // Używa tylnej kamery
|
||||||
|
FRONT : 1 // Używa przedniej kamery
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
### 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 zwrotna onError, 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
|
||||||
|
|
||||||
|
Funkcja zwrotna onSuccess, która 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
|
||||||
|
|
||||||
|
Ustawia pozycję wyskakującego okna.
|
||||||
|
|
||||||
|
**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
|
||||||
|
|
||||||
|
Parametry dotyczące tylko platformy iOS, które określają pozycję zakotwiczenia elementu oraz kierunek strzałki wyskakującego okna podczas wybierania obrazów z biblioteki lub albumu iPada.
|
||||||
|
|
||||||
|
{ 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
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Pamiętaj, że wielkość wyskakującego okna może ulec zmianie by dostosować się do kierunku strzałki oraz orientacji ekranu. Upewnij się co do zmiany orientacji podczas określania położenia zakotwiczenia elementu.
|
||||||
|
|
||||||
|
## Navigator.Camera.CleanUp
|
||||||
|
|
||||||
|
Usuwa pośrednie zdjęcia zrobione przez aparat z tymczasowego magazynu.
|
||||||
|
|
||||||
|
navigator.camera.cleanup( cameraSuccess, cameraError );
|
||||||
|
|
||||||
|
|
||||||
|
### Opis
|
||||||
|
|
||||||
|
Usuwa pośrednie pliki graficzne, które po wywołaniu `camera.getPicture` są przechowywane w tymczasowym magazynie. 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
@ -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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# org.apache.cordova.camera
|
||||||
|
|
||||||
|
Этот плагин предоставляет API для съемки и для выбора изображения из библиотеки изображений системы.
|
||||||
|
|
||||||
|
cordova plugin add org.apache.cordova.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);
|
||||||
|
}
|
410
doc/zh/index.md
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
<!---
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# org.apache.cordova.camera
|
||||||
|
|
||||||
|
這個外掛程式提供了一個 API,拍照,從系統的圖像庫中選擇圖像。
|
||||||
|
|
||||||
|
cordova plugin add org.apache.cordova.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() {/ / 做你的事!},0) ;
|
||||||
|
|
||||||
|
|
||||||
|
### Windows Phone 7 的怪癖
|
||||||
|
|
||||||
|
調用本機攝像頭應用程式,而通過 Zune 所連接的設備不能工作,並且觸發錯誤回檔。
|
||||||
|
|
||||||
|
### 泰怪癖
|
||||||
|
|
||||||
|
泰僅支援 `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
|
||||||
|
|
||||||
|
要自訂相機設置的可選參數。
|
||||||
|
|
||||||
|
{品質: 75,destinationType: Camera.DestinationType.DATA_URL,sourceType: Camera.PictureSourceType.CAMERA,allowEdit: 為 true,encodingType: Camera.EncodingType.JPEG,targetWidth: 100,targetHeight: 100,popoverOptions: CameraPopoverOptions,saveToPhotoAlbum: 虛假} ;
|
||||||
|
|
||||||
|
|
||||||
|
### 選項
|
||||||
|
|
||||||
|
* **品質**: 保存的圖像,表示為範圍 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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### 參數
|
||||||
|
|
||||||
|
* **消息**: 消息提供的設備的本機代碼。*(字串)*
|
||||||
|
|
||||||
|
## cameraSuccess
|
||||||
|
|
||||||
|
提供的圖像資料的 onSuccess 回呼函數。
|
||||||
|
|
||||||
|
function(imageData) {
|
||||||
|
// Do something with the image
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### 參數
|
||||||
|
|
||||||
|
* **圖像資料**: 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 螢幕元素到其錨定氣泡框上的圖元座標。*(人數)*
|
||||||
|
|
||||||
|
* **y**: 螢幕元素到其錨定氣泡框上的 y 圖元座標。*(人數)*
|
||||||
|
|
||||||
|
* **寬度**: 寬度以圖元為單位),到其錨定氣泡框上的螢幕元素。*(人數)*
|
||||||
|
|
||||||
|
* **高度**: 高度以圖元為單位),到其錨定氣泡框上的螢幕元素。*(人數)*
|
||||||
|
|
||||||
|
* **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);
|
||||||
|
}
|
59
package.json
@ -1,62 +1,43 @@
|
|||||||
{
|
{
|
||||||
"name": "cordova-plugin-camera",
|
"name": "cordova-plugin-camera",
|
||||||
"version": "4.2.0-dev",
|
"version": "0.3.6-dev",
|
||||||
"description": "Cordova Camera Plugin",
|
"description": "Cordova Camera Plugin",
|
||||||
"types": "./types/index.d.ts",
|
|
||||||
"cordova": {
|
"cordova": {
|
||||||
"id": "cordova-plugin-camera",
|
"id": "org.apache.cordova.camera",
|
||||||
"platforms": [
|
"platforms": [
|
||||||
|
"firefoxos",
|
||||||
"android",
|
"android",
|
||||||
|
"amazon-fireos",
|
||||||
|
"ubuntu",
|
||||||
"ios",
|
"ios",
|
||||||
|
"blackberry10",
|
||||||
|
"wp7",
|
||||||
|
"wp8",
|
||||||
|
"windows8",
|
||||||
"browser",
|
"browser",
|
||||||
"windows",
|
"windows"
|
||||||
"osx"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/apache/cordova-plugin-camera"
|
"url": "https://git-wip-us.apache.org/repos/asf/cordova-plugin-camera.git"
|
||||||
},
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/apache/cordova-plugin-camera/issues"
|
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"cordova",
|
"cordova",
|
||||||
"camera",
|
"camera",
|
||||||
"ecosystem:cordova",
|
"ecosystem:cordova",
|
||||||
|
"cordova-firefoxos",
|
||||||
"cordova-android",
|
"cordova-android",
|
||||||
|
"cordova-amazon-fireos",
|
||||||
|
"cordova-ubuntu",
|
||||||
"cordova-ios",
|
"cordova-ios",
|
||||||
|
"cordova-blackberry10",
|
||||||
|
"cordova-wp7",
|
||||||
|
"cordova-wp8",
|
||||||
|
"cordova-windows8",
|
||||||
"cordova-browser",
|
"cordova-browser",
|
||||||
"cordova-windows",
|
"cordova-windows"
|
||||||
"cordova-osx"
|
|
||||||
],
|
],
|
||||||
"scripts": {
|
|
||||||
"test": "npm run eslint",
|
|
||||||
"eslint": "node node_modules/eslint/bin/eslint www && node node_modules/eslint/bin/eslint src && node node_modules/eslint/bin/eslint tests"
|
|
||||||
},
|
|
||||||
"author": "Apache Software Foundation",
|
"author": "Apache Software Foundation",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache 2.0"
|
||||||
"engines": {
|
|
||||||
"cordovaDependencies": {
|
|
||||||
"3.0.0": {
|
|
||||||
"cordova-android": ">=6.3.0"
|
|
||||||
},
|
|
||||||
"4.1.0": {
|
|
||||||
"cordova-android": ">=6.3.0",
|
|
||||||
"cordova": ">=7.1.0"
|
|
||||||
},
|
|
||||||
"5.0.0": {
|
|
||||||
"cordova": ">100"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"eslint": "^4.3.0",
|
|
||||||
"eslint-config-semistandard": "^11.0.0",
|
|
||||||
"eslint-config-standard": "^10.2.1",
|
|
||||||
"eslint-plugin-import": "^2.3.0",
|
|
||||||
"eslint-plugin-node": "^5.0.0",
|
|
||||||
"eslint-plugin-promise": "^3.5.0",
|
|
||||||
"eslint-plugin-standard": "^3.0.1"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
257
plugin.xml
@ -20,19 +20,15 @@
|
|||||||
|
|
||||||
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
id="cordova-plugin-camera"
|
xmlns:rim="http://www.blackberry.com/ns/widgets"
|
||||||
version="4.2.0-dev">
|
id="org.apache.cordova.camera"
|
||||||
|
version="0.3.6-dev">
|
||||||
<name>Camera</name>
|
<name>Camera</name>
|
||||||
<description>Cordova Camera Plugin</description>
|
<description>Cordova Camera Plugin</description>
|
||||||
<license>Apache 2.0</license>
|
<license>Apache 2.0</license>
|
||||||
<keywords>cordova,camera</keywords>
|
<keywords>cordova,camera</keywords>
|
||||||
<repo>https://github.com/apache/cordova-plugin-camera</repo>
|
<repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-camera.git</repo>
|
||||||
<issue>https://github.com/apache/cordova-plugin-camera/issues</issue>
|
<issue>https://issues.apache.org/jira/browse/CB/component/12320645</issue>
|
||||||
|
|
||||||
<engines>
|
|
||||||
<engine name="cordova" version=">=7.1.0"/>
|
|
||||||
<engine name="cordova-android" version=">=6.3.0" />
|
|
||||||
</engines>
|
|
||||||
|
|
||||||
<js-module src="www/CameraConstants.js" name="Camera">
|
<js-module src="www/CameraConstants.js" name="Camera">
|
||||||
<clobbers target="Camera" />
|
<clobbers target="Camera" />
|
||||||
@ -42,10 +38,25 @@
|
|||||||
<clobbers target="CameraPopoverOptions" />
|
<clobbers target="CameraPopoverOptions" />
|
||||||
</js-module>
|
</js-module>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<js-module src="www/Camera.js" name="camera">
|
<js-module src="www/Camera.js" name="camera">
|
||||||
<clobbers target="navigator.camera" />
|
<clobbers target="navigator.camera" />
|
||||||
</js-module>
|
</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 -->
|
<!-- android -->
|
||||||
<platform name="android">
|
<platform name="android">
|
||||||
<config-file target="res/xml/config.xml" parent="/*">
|
<config-file target="res/xml/config.xml" parent="/*">
|
||||||
@ -56,36 +67,61 @@
|
|||||||
<config-file target="AndroidManifest.xml" parent="/*">
|
<config-file target="AndroidManifest.xml" parent="/*">
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
</config-file>
|
</config-file>
|
||||||
<config-file target="AndroidManifest.xml" parent="application">
|
|
||||||
<provider
|
|
||||||
android:name="org.apache.cordova.camera.FileProvider"
|
|
||||||
android:authorities="${applicationId}.camera.provider"
|
|
||||||
android:exported="false"
|
|
||||||
android:grantUriPermissions="true" >
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
|
||||||
android:resource="@xml/camera_provider_paths"/>
|
|
||||||
</provider>
|
|
||||||
</config-file>
|
|
||||||
|
|
||||||
<source-file src="src/android/CameraLauncher.java" target-dir="src/org/apache/cordova/camera" />
|
<source-file src="src/android/CameraLauncher.java" target-dir="src/org/apache/cordova/camera" />
|
||||||
<source-file src="src/android/CordovaUri.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/FileHelper.java" target-dir="src/org/apache/cordova/camera" />
|
||||||
<source-file src="src/android/ExifHelper.java" target-dir="src/org/apache/cordova/camera" />
|
<source-file src="src/android/ExifHelper.java" target-dir="src/org/apache/cordova/camera" />
|
||||||
<source-file src="src/android/FileProvider.java" target-dir="src/org/apache/cordova/camera" />
|
|
||||||
<source-file src="src/android/xml/camera_provider_paths.xml" target-dir="res/xml" />
|
|
||||||
|
|
||||||
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
||||||
<clobbers target="CameraPopoverHandle" />
|
<clobbers target="CameraPopoverHandle" />
|
||||||
</js-module>
|
</js-module>
|
||||||
|
|
||||||
<preference name="ANDROID_SUPPORT_V4_VERSION" default="27.+"/>
|
</platform>
|
||||||
<framework src="com.android.support:support-v4:$ANDROID_SUPPORT_V4_VERSION"/>
|
|
||||||
|
|
||||||
</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>
|
||||||
|
|
||||||
<!-- old plugin's ios -->
|
<source-file src="src/android/CameraLauncher.java" target-dir="src/org/apache/cordova/camera" />
|
||||||
<!-- <platform name="ios">
|
<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="/*">
|
<config-file target="config.xml" parent="/*">
|
||||||
<feature name="Camera">
|
<feature name="Camera">
|
||||||
<param name="ios-package" value="CDVCamera" />
|
<param name="ios-package" value="CDVCamera" />
|
||||||
@ -110,73 +146,86 @@
|
|||||||
<framework src="AssetsLibrary.framework" />
|
<framework src="AssetsLibrary.framework" />
|
||||||
<framework src="MobileCoreServices.framework" />
|
<framework src="MobileCoreServices.framework" />
|
||||||
<framework src="CoreGraphics.framework" />
|
<framework src="CoreGraphics.framework" />
|
||||||
<framework src="AVFoundation.framework" />
|
|
||||||
|
<config-file target="*-Info.plist" parent="NSLocationWhenInUseUsageDescription">
|
||||||
|
<string></string>
|
||||||
|
</config-file>
|
||||||
|
|
||||||
|
</platform>
|
||||||
|
|
||||||
</platform> -->
|
<!-- blackberry10 -->
|
||||||
<!-- ios -->
|
<platform name="blackberry10">
|
||||||
<platform name="ios">
|
<source-file src="src/blackberry10/index.js" target-dir="Camera" />
|
||||||
|
<config-file target="www/config.xml" parent="/widget">
|
||||||
|
<feature name="Camera" value="Camera"/>
|
||||||
|
</config-file>
|
||||||
|
<config-file target="www/config.xml" parent="/widget/rim:permissions">
|
||||||
|
<rim:permit>access_shared</rim:permit>
|
||||||
|
<rim:permit>use_camera</rim:permit>
|
||||||
|
</config-file>
|
||||||
|
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
||||||
|
<clobbers target="CameraPopoverHandle" />
|
||||||
|
</js-module>
|
||||||
|
<asset src="www/blackberry10/assets" target="chrome" />
|
||||||
|
</platform>
|
||||||
|
|
||||||
|
<!-- wp7 -->
|
||||||
|
<platform name="wp7">
|
||||||
<config-file target="config.xml" parent="/*">
|
<config-file target="config.xml" parent="/*">
|
||||||
<feature name="Camera">
|
<feature name="Camera">
|
||||||
<param name="ios-package" value="CustomCamera" />
|
<param name="wp-package" value="Camera"/>
|
||||||
</feature>
|
|
||||||
</config-file>
|
|
||||||
<config-file target="config.xml" parent="/*">
|
|
||||||
<feature name="LocalStorage">
|
|
||||||
<param name="ios-package" value="CDVLocalStorage" />
|
|
||||||
</feature>
|
</feature>
|
||||||
</config-file>
|
</config-file>
|
||||||
|
|
||||||
<header-file src="src/ios/UIImage+CropScaleOrientation.h" />
|
<config-file target="Properties/WMAppManifest.xml" parent="/Deployment/App/Capabilities">
|
||||||
<source-file src="src/ios/UIImage+CropScaleOrientation.m" />
|
<Capability Name="ID_CAP_ISV_CAMERA" />
|
||||||
|
<Capability Name="ID_CAP_MEDIALIB" />
|
||||||
<header-file src="src/ios/classes/CustomCamera.h" />
|
|
||||||
<source-file src="src/ios/classes/CustomCamera.m" />
|
|
||||||
|
|
||||||
<header-file src="src/ios/classes/AVCamPreviewView.h" />
|
|
||||||
<source-file src="src/ios/classes/AVCamPreviewView.m" />
|
|
||||||
|
|
||||||
<header-file src="src/ios/classes/AVCamViewController.h" />
|
|
||||||
<source-file src="src/ios/classes/AVCamViewController.m" />
|
|
||||||
|
|
||||||
<header-file src="src/ios/classes/CameraParameter.h" />
|
|
||||||
<source-file src="src/ios/classes/CameraParameter.m" />
|
|
||||||
|
|
||||||
<resource-file src="src/ios/classes/AVCamViewController_iPhone.xib" />
|
|
||||||
<resource-file src="src/ios/classes/AVCamViewController_iPad.xib" />
|
|
||||||
|
|
||||||
<resource-file src="src/ios/image/icon_back.png" />
|
|
||||||
<resource-file src="src/ios/image/icon_capture_pressed.png" />
|
|
||||||
<resource-file src="src/ios/image/icon_capture.png" />
|
|
||||||
<resource-file src="src/ios/image/icon_delete.png" />
|
|
||||||
<resource-file src="src/ios/image/icon_flash_auto.png" />
|
|
||||||
<resource-file src="src/ios/image/icon_flash_off.png" />
|
|
||||||
<resource-file src="src/ios/image/icon_flash.png" />
|
|
||||||
<resource-file src="src/ios/image/icon_flip.png" />
|
|
||||||
<resource-file src="src/ios/image/icon_max.png" />
|
|
||||||
<resource-file src="src/ios/image/icon_min.png" />
|
|
||||||
<resource-file src="src/ios/image/icon_submit.png" />
|
|
||||||
<resource-file src="src/ios/image/sample.png" />
|
|
||||||
|
|
||||||
<framework src="CoreGraphics.framework" weak="true" />
|
|
||||||
<framework src="AssetsLibrary.framework" weak="true" />
|
|
||||||
<framework src="AVFoundation.framework" weak="true" />
|
|
||||||
<framework src="CoreAudio.framework" weak="true" />
|
|
||||||
<framework src="CoreLocation.framework" weak="true" />
|
|
||||||
<framework src="MobileCoreServices.framework" weak="true" />
|
|
||||||
|
|
||||||
<preference name="CAMERA_USAGE_DESCRIPTION" default="This app requires access to your camera to take pictures" />
|
|
||||||
<config-file target="*-Info.plist" parent="NSCameraUsageDescription">
|
|
||||||
<string>$CAMERA_USAGE_DESCRIPTION</string>
|
|
||||||
</config-file>
|
|
||||||
<preference name="MICROPHONE_USAGE_DESCRIPTION" default="This app requires access to your microphone to take pictures" />
|
|
||||||
<config-file target="*-Info.plist" parent="NSMicrophoneUsageDescription">
|
|
||||||
<string>$MICROPHONE_USAGE_DESCRIPTION</string>
|
|
||||||
</config-file>
|
|
||||||
<preference name="PHOTO_LIBRARY_ADD_USAGE_DESCRIPTION" default="This app requires access to your photo library to save your pictures" />
|
|
||||||
<config-file target="*-Info.plist" parent="NSPhotoLibraryAddUsageDescription">
|
|
||||||
<string>$PHOTO_LIBRARY_ADD_USAGE_DESCRIPTION</string>
|
|
||||||
</config-file>
|
</config-file>
|
||||||
|
|
||||||
|
<source-file src="src/wp/Camera.cs" />
|
||||||
|
|
||||||
|
|
||||||
|
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
||||||
|
<clobbers target="CameraPopoverHandle" />
|
||||||
|
</js-module>
|
||||||
</platform>
|
</platform>
|
||||||
|
|
||||||
|
<!-- wp8 -->
|
||||||
|
<platform name="wp8">
|
||||||
|
<config-file target="config.xml" parent="/*">
|
||||||
|
<feature name="Camera">
|
||||||
|
<param name="wp-package" value="Camera"/>
|
||||||
|
</feature>
|
||||||
|
</config-file>
|
||||||
|
|
||||||
|
<config-file target="Properties/WMAppManifest.xml" parent="/Deployment/App/Capabilities">
|
||||||
|
<Capability Name="ID_CAP_ISV_CAMERA" />
|
||||||
|
<Capability Name="ID_CAP_MEDIALIB_PHOTO"/>
|
||||||
|
</config-file>
|
||||||
|
|
||||||
|
<source-file src="src/wp/Camera.cs" />
|
||||||
|
|
||||||
|
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
||||||
|
<clobbers target="CameraPopoverHandle" />
|
||||||
|
</js-module>
|
||||||
|
</platform>
|
||||||
|
|
||||||
|
<!-- windows8 -->
|
||||||
|
<platform name="windows8">
|
||||||
|
|
||||||
|
<config-file target="package.appxmanifest" parent="/Package/Capabilities">
|
||||||
|
<Capability Name="picturesLibrary" />
|
||||||
|
<DeviceCapability Name="webcam" />
|
||||||
|
</config-file>
|
||||||
|
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
||||||
|
<clobbers target="CameraPopoverHandle" />
|
||||||
|
</js-module>
|
||||||
|
<js-module src="src/windows/CameraProxy.js" name="CameraProxy">
|
||||||
|
<merges target="" />
|
||||||
|
</js-module>
|
||||||
|
|
||||||
|
</platform>
|
||||||
|
|
||||||
<!-- browser -->
|
<!-- browser -->
|
||||||
<platform name="browser">
|
<platform name="browser">
|
||||||
<config-file target="config.xml" parent="/*">
|
<config-file target="config.xml" parent="/*">
|
||||||
@ -192,34 +241,26 @@
|
|||||||
|
|
||||||
<!-- windows -->
|
<!-- windows -->
|
||||||
<platform name="windows">
|
<platform name="windows">
|
||||||
<config-file target="package.appxmanifest" parent="/Package/Capabilities">
|
<config-file target="package.windows.appxmanifest" parent="/Package/Capabilities">
|
||||||
|
<Capability Name="picturesLibrary" />
|
||||||
|
<DeviceCapability Name="webcam" />
|
||||||
|
</config-file>
|
||||||
|
<config-file target="package.windows80.appxmanifest" parent="/Package/Capabilities">
|
||||||
|
<Capability Name="picturesLibrary" />
|
||||||
|
<DeviceCapability Name="webcam" />
|
||||||
|
</config-file>
|
||||||
|
<config-file target="package.phone.appxmanifest" parent="/Package/Capabilities">
|
||||||
|
<Capability Name="picturesLibrary" />
|
||||||
<DeviceCapability Name="webcam" />
|
<DeviceCapability Name="webcam" />
|
||||||
</config-file>
|
</config-file>
|
||||||
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
||||||
<clobbers target="CameraPopoverHandle" />
|
<clobbers target="CameraPopoverHandle" />
|
||||||
</js-module>
|
</js-module>
|
||||||
<js-module src="src/windows/CameraProxy.js" name="CameraProxy">
|
<js-module src="src/windows/CameraProxy.js" name="CameraProxy">
|
||||||
<runs />
|
<merges target="" />
|
||||||
</js-module>
|
</js-module>
|
||||||
</platform>
|
</platform>
|
||||||
|
|
||||||
<!-- osx -->
|
|
||||||
<platform name="osx">
|
|
||||||
<config-file target="config.xml" parent="/*">
|
|
||||||
<feature name="Camera">
|
|
||||||
<param name="osx-package" value="CDVCamera"/>
|
|
||||||
</feature>
|
|
||||||
</config-file>
|
|
||||||
|
|
||||||
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
|
||||||
<clobbers target="CameraPopoverHandle" />
|
|
||||||
</js-module>
|
|
||||||
|
|
||||||
<header-file src="src/osx/CDVCamera.h" />
|
|
||||||
<source-file src="src/osx/CDVCamera.m" />
|
|
||||||
|
|
||||||
<framework src="Quartz.framework" />
|
|
||||||
<framework src="AppKit.framework" />
|
|
||||||
</platform>
|
|
||||||
|
|
||||||
</plugin>
|
</plugin>
|
||||||
|
@ -1,103 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.apache.cordova.camera;
|
|
||||||
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.support.v4.content.FileProvider;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This class exists because Andorid FilesProvider doesn't work on Android 4.4.4 and below and throws
|
|
||||||
* weird errors. I'm not sure why writing to shared cache directories is somehow verboten, but it is
|
|
||||||
* and this error is irritating for a Compatibility library to have.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class CordovaUri {
|
|
||||||
|
|
||||||
private Uri androidUri;
|
|
||||||
private String fileName;
|
|
||||||
private Uri fileUri;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We always expect a FileProvider string to be passed in for the file that we create
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
CordovaUri (File dir,Uri inputUri)
|
|
||||||
{
|
|
||||||
//Determine whether the file is a content or file URI
|
|
||||||
if(inputUri.getScheme().equals("content"))
|
|
||||||
{
|
|
||||||
androidUri = inputUri;
|
|
||||||
fileName = getFileNameFromUri(dir,androidUri);
|
|
||||||
fileUri = Uri.parse("file://" + fileName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fileUri = inputUri;
|
|
||||||
fileName = FileHelper.stripFileProtocol(inputUri.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Uri getFileUri()
|
|
||||||
{
|
|
||||||
return fileUri;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFilePath()
|
|
||||||
{
|
|
||||||
return fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This only gets called by takePicture
|
|
||||||
*/
|
|
||||||
|
|
||||||
public Uri getCorrectUri()
|
|
||||||
{
|
|
||||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
|
||||||
return androidUri;
|
|
||||||
else
|
|
||||||
return fileUri;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is dirty, but it does the job.
|
|
||||||
*
|
|
||||||
* Since the FilesProvider doesn't really provide you a way of getting a URL from the file,
|
|
||||||
* and since we actually need the Camera to create the file for us most of the time, we don't
|
|
||||||
* actually write the file, just generate the location based on a timestamp, we need to get it
|
|
||||||
* back from the Intent.
|
|
||||||
*
|
|
||||||
* However, the FilesProvider preserves the path, so we can at least write to it from here, since
|
|
||||||
* we own the context in this case.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private String getFileNameFromUri(File external_storage,Uri uri) {
|
|
||||||
String fullUri = uri.toString();
|
|
||||||
String partial_path = fullUri.split("external_files")[1];
|
|
||||||
String path = external_storage.getAbsolutePath() + partial_path;
|
|
||||||
return path;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,7 +6,9 @@
|
|||||||
to you under the Apache License, Version 2.0 (the
|
to you under the Apache License, Version 2.0 (the
|
||||||
"License"); you may not use this file except in compliance
|
"License"); you may not use this file except in compliance
|
||||||
with the License. You may obtain a copy of the License at
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing,
|
Unless required by applicable law or agreed to in writing,
|
||||||
software distributed under the License is distributed on an
|
software distributed under the License is distributed on an
|
||||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
@ -16,16 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova.camera;
|
package org.apache.cordova.camera;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.content.ContentUris;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.CursorLoader;
|
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.provider.DocumentsContract;
|
|
||||||
import android.provider.MediaStore;
|
|
||||||
import android.webkit.MimeTypeMap;
|
import android.webkit.MimeTypeMap;
|
||||||
|
|
||||||
import org.apache.cordova.CordovaInterface;
|
import org.apache.cordova.CordovaInterface;
|
||||||
@ -49,15 +43,27 @@ public class FileHelper {
|
|||||||
* @return the full path to the file
|
* @return the full path to the file
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public static String getRealPath(Uri uri, CordovaInterface cordova) {
|
public static String getRealPath(String uriString, CordovaInterface cordova) {
|
||||||
String realPath = null;
|
String realPath = null;
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT < 11)
|
if (uriString.startsWith("content://")) {
|
||||||
realPath = FileHelper.getRealPathFromURI_BelowAPI11(cordova.getActivity(), uri);
|
String[] proj = { _DATA };
|
||||||
|
Cursor cursor = cordova.getActivity().managedQuery(Uri.parse(uriString), proj, null, null, null);
|
||||||
// SDK >= 11
|
int column_index = cursor.getColumnIndexOrThrow(_DATA);
|
||||||
else
|
cursor.moveToFirst();
|
||||||
realPath = FileHelper.getRealPathFromURI_API11_And_Above(cordova.getActivity(), uri);
|
realPath = cursor.getString(column_index);
|
||||||
|
if (realPath == null) {
|
||||||
|
LOG.e(LOG_TAG, "Could get real path for URI string %s", uriString);
|
||||||
|
}
|
||||||
|
} else if (uriString.startsWith("file://")) {
|
||||||
|
realPath = uriString.substring(7);
|
||||||
|
if (realPath.startsWith("/android_asset/")) {
|
||||||
|
LOG.e(LOG_TAG, "Cannot get real path for URI string %s because it is a file:///android_asset/ URI.", uriString);
|
||||||
|
realPath = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
realPath = uriString;
|
||||||
|
}
|
||||||
|
|
||||||
return realPath;
|
return realPath;
|
||||||
}
|
}
|
||||||
@ -70,103 +76,8 @@ public class FileHelper {
|
|||||||
* @param cordova the current application context
|
* @param cordova the current application context
|
||||||
* @return the full path to the file
|
* @return the full path to the file
|
||||||
*/
|
*/
|
||||||
public static String getRealPath(String uriString, CordovaInterface cordova) {
|
public static String getRealPath(Uri uri, CordovaInterface cordova) {
|
||||||
return FileHelper.getRealPath(Uri.parse(uriString), cordova);
|
return FileHelper.getRealPath(uri.toString(), cordova);
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
|
||||||
public static String getRealPathFromURI_API11_And_Above(final Context context, final Uri uri) {
|
|
||||||
|
|
||||||
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
|
||||||
// DocumentProvider
|
|
||||||
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
|
|
||||||
|
|
||||||
// ExternalStorageProvider
|
|
||||||
if (isExternalStorageDocument(uri)) {
|
|
||||||
final String docId = DocumentsContract.getDocumentId(uri);
|
|
||||||
final String[] split = docId.split(":");
|
|
||||||
final String type = split[0];
|
|
||||||
|
|
||||||
if ("primary".equalsIgnoreCase(type)) {
|
|
||||||
return Environment.getExternalStorageDirectory() + "/" + split[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO handle non-primary volumes
|
|
||||||
}
|
|
||||||
// DownloadsProvider
|
|
||||||
else if (isDownloadsDocument(uri)) {
|
|
||||||
|
|
||||||
final String id = DocumentsContract.getDocumentId(uri);
|
|
||||||
if (id != null && id.length() > 0) {
|
|
||||||
if (id.startsWith("raw:")) {
|
|
||||||
return id.replaceFirst("raw:", "");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
final Uri contentUri = ContentUris.withAppendedId(
|
|
||||||
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
|
|
||||||
|
|
||||||
return getDataColumn(context, contentUri, null, null);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// MediaProvider
|
|
||||||
else if (isMediaDocument(uri)) {
|
|
||||||
final String docId = DocumentsContract.getDocumentId(uri);
|
|
||||||
final String[] split = docId.split(":");
|
|
||||||
final String type = split[0];
|
|
||||||
|
|
||||||
Uri contentUri = null;
|
|
||||||
if ("image".equals(type)) {
|
|
||||||
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
|
||||||
} else if ("video".equals(type)) {
|
|
||||||
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
|
||||||
} else if ("audio".equals(type)) {
|
|
||||||
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String selection = "_id=?";
|
|
||||||
final String[] selectionArgs = new String[] {
|
|
||||||
split[1]
|
|
||||||
};
|
|
||||||
|
|
||||||
return getDataColumn(context, contentUri, selection, selectionArgs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// MediaStore (and general)
|
|
||||||
else if ("content".equalsIgnoreCase(uri.getScheme())) {
|
|
||||||
|
|
||||||
// Return the remote address
|
|
||||||
if (isGooglePhotosUri(uri))
|
|
||||||
return uri.getLastPathSegment();
|
|
||||||
|
|
||||||
return getDataColumn(context, uri, null, null);
|
|
||||||
}
|
|
||||||
// File
|
|
||||||
else if ("file".equalsIgnoreCase(uri.getScheme())) {
|
|
||||||
return uri.getPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -177,36 +88,25 @@ public class FileHelper {
|
|||||||
* @return an input stream into the data at the given URI or null if given an invalid URI string
|
* @return an input stream into the data at the given URI or null if given an invalid URI string
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static InputStream getInputStreamFromUriString(String uriString, CordovaInterface cordova)
|
public static InputStream getInputStreamFromUriString(String uriString, CordovaInterface cordova) throws IOException {
|
||||||
throws IOException {
|
|
||||||
InputStream returnValue = null;
|
|
||||||
if (uriString.startsWith("content")) {
|
if (uriString.startsWith("content")) {
|
||||||
Uri uri = Uri.parse(uriString);
|
Uri uri = Uri.parse(uriString);
|
||||||
returnValue = cordova.getActivity().getContentResolver().openInputStream(uri);
|
return cordova.getActivity().getContentResolver().openInputStream(uri);
|
||||||
} else if (uriString.startsWith("file://")) {
|
} else if (uriString.startsWith("file://")) {
|
||||||
int question = uriString.indexOf("?");
|
int question = uriString.indexOf("?");
|
||||||
if (question > -1) {
|
if (question > -1) {
|
||||||
uriString = uriString.substring(0, question);
|
uriString = uriString.substring(0,question);
|
||||||
}
|
}
|
||||||
if (uriString.startsWith("file:///android_asset/")) {
|
if (uriString.startsWith("file:///android_asset/")) {
|
||||||
Uri uri = Uri.parse(uriString);
|
Uri uri = Uri.parse(uriString);
|
||||||
String relativePath = uri.getPath().substring(15);
|
String relativePath = uri.getPath().substring(15);
|
||||||
returnValue = cordova.getActivity().getAssets().open(relativePath);
|
return cordova.getActivity().getAssets().open(relativePath);
|
||||||
} else {
|
} else {
|
||||||
// might still be content so try that first
|
return new FileInputStream(getRealPath(uriString, cordova));
|
||||||
try {
|
|
||||||
returnValue = cordova.getActivity().getContentResolver().openInputStream(Uri.parse(uriString));
|
|
||||||
} catch (Exception e) {
|
|
||||||
returnValue = null;
|
|
||||||
}
|
|
||||||
if (returnValue == null) {
|
|
||||||
returnValue = new FileInputStream(getRealPath(uriString, cordova));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
returnValue = new FileInputStream(uriString);
|
return new FileInputStream(getRealPath(uriString, cordova));
|
||||||
}
|
}
|
||||||
return returnValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -255,76 +155,4 @@ public class FileHelper {
|
|||||||
|
|
||||||
return mimeType;
|
return mimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of the data column for this Uri. This is useful for
|
|
||||||
* MediaStore Uris, and other file-based ContentProviders.
|
|
||||||
*
|
|
||||||
* @param context The context.
|
|
||||||
* @param uri The Uri to query.
|
|
||||||
* @param selection (Optional) Filter used in the query.
|
|
||||||
* @param selectionArgs (Optional) Selection arguments used in the query.
|
|
||||||
* @return The value of the _data column, which is typically a file path.
|
|
||||||
* @author paulburke
|
|
||||||
*/
|
|
||||||
public static String getDataColumn(Context context, Uri uri, String selection,
|
|
||||||
String[] selectionArgs) {
|
|
||||||
|
|
||||||
Cursor cursor = null;
|
|
||||||
final String column = "_data";
|
|
||||||
final String[] projection = {
|
|
||||||
column
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
|
|
||||||
null);
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
|
|
||||||
final int column_index = cursor.getColumnIndexOrThrow(column);
|
|
||||||
return cursor.getString(column_index);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
} finally {
|
|
||||||
if (cursor != null)
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param uri The Uri to check.
|
|
||||||
* @return Whether the Uri authority is ExternalStorageProvider.
|
|
||||||
* @author paulburke
|
|
||||||
*/
|
|
||||||
public static boolean isExternalStorageDocument(Uri uri) {
|
|
||||||
return "com.android.externalstorage.documents".equals(uri.getAuthority());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param uri The Uri to check.
|
|
||||||
* @return Whether the Uri authority is DownloadsProvider.
|
|
||||||
* @author paulburke
|
|
||||||
*/
|
|
||||||
public static boolean isDownloadsDocument(Uri uri) {
|
|
||||||
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param uri The Uri to check.
|
|
||||||
* @return Whether the Uri authority is MediaProvider.
|
|
||||||
* @author paulburke
|
|
||||||
*/
|
|
||||||
public static boolean isMediaDocument(Uri uri) {
|
|
||||||
return "com.android.providers.media.documents".equals(uri.getAuthority());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param uri The Uri to check.
|
|
||||||
* @return Whether the Uri authority is Google Photos.
|
|
||||||
*/
|
|
||||||
public static boolean isGooglePhotosUri(Uri uri) {
|
|
||||||
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,21 +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.
|
|
||||||
*/
|
|
||||||
package org.apache.cordova.camera;
|
|
||||||
|
|
||||||
public class FileProvider extends android.support.v4.content.FileProvider {}
|
|
@ -1,21 +0,0 @@
|
|||||||
<?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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<cache-path name="external_files" path="."/>
|
|
||||||
</paths>
|
|
224
src/blackberry10/index.js
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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 PictureSourceType = {
|
||||||
|
PHOTOLIBRARY : 0, // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
|
||||||
|
CAMERA : 1, // Take picture from camera
|
||||||
|
SAVEDPHOTOALBUM : 2 // Choose image from picture library (same as PHOTOLIBRARY for Android)
|
||||||
|
},
|
||||||
|
DestinationType = {
|
||||||
|
DATA_URL: 0, // Return base64 encoded string
|
||||||
|
FILE_URI: 1, // Return file uri (content://media/external/images/media/2 for Android)
|
||||||
|
NATIVE_URI: 2 // Return native uri (eg. asset-library://... for iOS)
|
||||||
|
},
|
||||||
|
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] === 'org.apache.cordova.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
|
||||||
|
errorHandler = function (err) {
|
||||||
|
var msg = "An error occured: ";
|
||||||
|
|
||||||
|
switch (err.code) {
|
||||||
|
case FileError.NOT_FOUND_ERR:
|
||||||
|
msg += "File or directory not found";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileError.NOT_READABLE_ERR:
|
||||||
|
msg += "File or directory not readable";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileError.PATH_EXISTS_ERR:
|
||||||
|
msg += "File or directory already exists";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileError.TYPE_MISMATCH_ERR:
|
||||||
|
msg += "Invalid file type";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
msg += "Unknown Error";
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
// set it back to original value
|
||||||
|
window.qnx.webplatform.getController().setFileSystemSandbox = sandbox;
|
||||||
|
callback(msg);
|
||||||
|
},
|
||||||
|
gotFile = function (fileEntry) {
|
||||||
|
fileEntry.file(function (file) {
|
||||||
|
var reader = new FileReader();
|
||||||
|
|
||||||
|
reader.onloadend = function (e) {
|
||||||
|
// set it back to original value
|
||||||
|
window.qnx.webplatform.getController().setFileSystemSandbox = sandbox;
|
||||||
|
callback(this.result);
|
||||||
|
};
|
||||||
|
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
}, errorHandler);
|
||||||
|
},
|
||||||
|
onInitFs = function (fs) {
|
||||||
|
window.qnx.webplatform.getController().setFileSystemSandbox = false;
|
||||||
|
fs.root.getFile(filePath, {create: false}, gotFile, errorHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.webkitRequestFileSystem(window.TEMPORARY, 10 * 1024 * 1024, onInitFs, errorHandler); // set size to 10MB max
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
takePicture: function (success, fail, args, env) {
|
||||||
|
var destinationType = JSON.parse(decodeURIComponent(args[1])),
|
||||||
|
sourceType = JSON.parse(decodeURIComponent(args[2])),
|
||||||
|
result = new PluginResult(args, env),
|
||||||
|
done = function (data) {
|
||||||
|
if (destinationType === DestinationType.FILE_URI) {
|
||||||
|
data = "file://" + data;
|
||||||
|
result.callbackOk(data, false);
|
||||||
|
} else {
|
||||||
|
encodeBase64(data, function (data) {
|
||||||
|
if (/^data:/.test(data)) {
|
||||||
|
data = data.slice(data.indexOf(",") + 1);
|
||||||
|
result.callbackOk(data, false);
|
||||||
|
} else {
|
||||||
|
result.callbackError(data, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cancel = function (reason) {
|
||||||
|
result.callbackError(reason, false);
|
||||||
|
},
|
||||||
|
invoked = function (error) {
|
||||||
|
if (error) {
|
||||||
|
result.callbackError(error, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
switch(sourceType) {
|
||||||
|
case PictureSourceType.CAMERA:
|
||||||
|
if (invokeAvailable) {
|
||||||
|
window.qnx.webplatform.getApplication().cards.camera.open("photo", done, cancel, invoked);
|
||||||
|
} else {
|
||||||
|
showCameraDialog(done, cancel, fail);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PictureSourceType.PHOTOLIBRARY:
|
||||||
|
case PictureSourceType.SAVEDPHOTOALBUM:
|
||||||
|
window.qnx.webplatform.getApplication().cards.filePicker.open({
|
||||||
|
mode: "Picker",
|
||||||
|
type: ["picture"]
|
||||||
|
}, done, cancel, invoked);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.noResult(true);
|
||||||
|
}
|
||||||
|
};
|
@ -19,28 +19,25 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var HIGHEST_POSSIBLE_Z_INDEX = 2147483647;
|
function takePicture(success, error, opts) {
|
||||||
|
|
||||||
function takePicture (success, error, opts) {
|
|
||||||
if (opts && opts[2] === 1) {
|
if (opts && opts[2] === 1) {
|
||||||
capture(success, error, opts);
|
capture(success, error);
|
||||||
} else {
|
} else {
|
||||||
var input = document.createElement('input');
|
var input = document.createElement('input');
|
||||||
input.style.position = 'relative';
|
|
||||||
input.style.zIndex = HIGHEST_POSSIBLE_Z_INDEX;
|
|
||||||
input.className = 'cordova-camera-select';
|
|
||||||
input.type = 'file';
|
input.type = 'file';
|
||||||
input.name = 'files[]';
|
input.name = 'files[]';
|
||||||
|
|
||||||
input.onchange = function (inputEvent) {
|
input.onchange = function(inputEvent) {
|
||||||
var reader = new FileReader(); /* eslint no-undef : 0 */
|
var canvas = document.createElement('canvas');
|
||||||
reader.onload = function (readerEvent) {
|
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function(readerEvent) {
|
||||||
input.parentNode.removeChild(input);
|
input.parentNode.removeChild(input);
|
||||||
|
|
||||||
var imageData = readerEvent.target.result;
|
var imageData = readerEvent.target.result;
|
||||||
|
|
||||||
return success(imageData.substr(imageData.indexOf(',') + 1));
|
return success(imageData.substr(imageData.indexOf(',') + 1));
|
||||||
};
|
}
|
||||||
|
|
||||||
reader.readAsDataURL(inputEvent.target.files[0]);
|
reader.readAsDataURL(inputEvent.target.files[0]);
|
||||||
};
|
};
|
||||||
@ -49,70 +46,49 @@ function takePicture (success, error, opts) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function capture (success, errorCallback, opts) {
|
function capture(success, errorCallback) {
|
||||||
var localMediaStream;
|
var localMediaStream;
|
||||||
var targetWidth = opts[3];
|
|
||||||
var targetHeight = opts[4];
|
|
||||||
|
|
||||||
targetWidth = targetWidth === -1 ? 320 : targetWidth;
|
|
||||||
targetHeight = targetHeight === -1 ? 240 : targetHeight;
|
|
||||||
|
|
||||||
var video = document.createElement('video');
|
var video = document.createElement('video');
|
||||||
var button = document.createElement('button');
|
var button = document.createElement('button');
|
||||||
var parent = document.createElement('div');
|
|
||||||
parent.style.position = 'relative';
|
|
||||||
parent.style.zIndex = HIGHEST_POSSIBLE_Z_INDEX;
|
|
||||||
parent.className = 'cordova-camera-capture';
|
|
||||||
parent.appendChild(video);
|
|
||||||
parent.appendChild(button);
|
|
||||||
|
|
||||||
video.width = targetWidth;
|
video.width = 320;
|
||||||
video.height = targetHeight;
|
video.height = 240;
|
||||||
button.innerHTML = 'Capture!';
|
button.innerHTML = 'Capture!';
|
||||||
|
|
||||||
button.onclick = function () {
|
button.onclick = function() {
|
||||||
// create a canvas and capture a frame from video stream
|
// create a canvas and capture a frame from video stream
|
||||||
var canvas = document.createElement('canvas');
|
var canvas = document.createElement('canvas');
|
||||||
canvas.width = targetWidth;
|
canvas.getContext('2d').drawImage(video, 0, 0, 320, 240);
|
||||||
canvas.height = targetHeight;
|
|
||||||
canvas.getContext('2d').drawImage(video, 0, 0, targetWidth, targetHeight);
|
|
||||||
|
|
||||||
// convert image stored in canvas to base64 encoded image
|
// convert image stored in canvas to base64 encoded image
|
||||||
var imageData = canvas.toDataURL('image/png');
|
var imageData = canvas.toDataURL('img/png');
|
||||||
imageData = imageData.replace('data:image/png;base64,', '');
|
imageData = imageData.replace('data:image/png;base64,', '');
|
||||||
|
|
||||||
// stop video stream, remove video and button.
|
// stop video stream, remove video and button
|
||||||
// Note that MediaStream.stop() is deprecated as of Chrome 47.
|
localMediaStream.stop();
|
||||||
if (localMediaStream.stop) {
|
video.parentNode.removeChild(video);
|
||||||
localMediaStream.stop();
|
button.parentNode.removeChild(button);
|
||||||
} else {
|
|
||||||
localMediaStream.getTracks().forEach(function (track) {
|
|
||||||
track.stop();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
parent.parentNode.removeChild(parent);
|
|
||||||
|
|
||||||
return success(imageData);
|
return success(imageData);
|
||||||
};
|
}
|
||||||
|
|
||||||
navigator.getUserMedia = navigator.getUserMedia ||
|
navigator.getUserMedia = navigator.getUserMedia ||
|
||||||
navigator.webkitGetUserMedia ||
|
navigator.webkitGetUserMedia ||
|
||||||
navigator.mozGetUserMedia ||
|
navigator.mozGetUserMedia ||
|
||||||
navigator.msGetUserMedia;
|
navigator.msGetUserMedia;
|
||||||
|
|
||||||
var successCallback = function (stream) {
|
var successCallback = function(stream) {
|
||||||
localMediaStream = stream;
|
localMediaStream = stream;
|
||||||
if ('srcObject' in video) {
|
video.src = window.URL.createObjectURL(localMediaStream);
|
||||||
video.srcObject = localMediaStream;
|
|
||||||
} else {
|
|
||||||
video.src = window.URL.createObjectURL(localMediaStream);
|
|
||||||
}
|
|
||||||
video.play();
|
video.play();
|
||||||
document.body.appendChild(parent);
|
|
||||||
};
|
document.body.appendChild(video);
|
||||||
|
document.body.appendChild(button);
|
||||||
|
}
|
||||||
|
|
||||||
if (navigator.getUserMedia) {
|
if (navigator.getUserMedia) {
|
||||||
navigator.getUserMedia({video: true, audio: false}, successCallback, errorCallback);
|
navigator.getUserMedia({video: true, audio: true}, successCallback, errorCallback);
|
||||||
} else {
|
} else {
|
||||||
alert('Browser does not support camera :(');
|
alert('Browser does not support camera :(');
|
||||||
}
|
}
|
||||||
@ -120,7 +96,7 @@ function capture (success, errorCallback, opts) {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
takePicture: takePicture,
|
takePicture: takePicture,
|
||||||
cleanup: function () {}
|
cleanup: function(){}
|
||||||
};
|
};
|
||||||
|
|
||||||
require('cordova/exec/proxy').add('Camera', module.exports);
|
require("cordova/exec/proxy").add("Camera",module.exports);
|
||||||
|
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);
|
@ -20,20 +20,18 @@
|
|||||||
#import "CDVCamera.h"
|
#import "CDVCamera.h"
|
||||||
#import "CDVJpegHeaderWriter.h"
|
#import "CDVJpegHeaderWriter.h"
|
||||||
#import "UIImage+CropScaleOrientation.h"
|
#import "UIImage+CropScaleOrientation.h"
|
||||||
|
#import <Cordova/NSArray+Comparisons.h>
|
||||||
|
#import <Cordova/NSData+Base64.h>
|
||||||
|
#import <Cordova/NSDictionary+Extensions.h>
|
||||||
#import <ImageIO/CGImageProperties.h>
|
#import <ImageIO/CGImageProperties.h>
|
||||||
#import <AssetsLibrary/ALAssetRepresentation.h>
|
#import <AssetsLibrary/ALAssetRepresentation.h>
|
||||||
#import <AssetsLibrary/AssetsLibrary.h>
|
#import <AssetsLibrary/AssetsLibrary.h>
|
||||||
#import <AVFoundation/AVFoundation.h>
|
|
||||||
#import <ImageIO/CGImageSource.h>
|
#import <ImageIO/CGImageSource.h>
|
||||||
#import <ImageIO/CGImageProperties.h>
|
#import <ImageIO/CGImageProperties.h>
|
||||||
#import <ImageIO/CGImageDestination.h>
|
#import <ImageIO/CGImageDestination.h>
|
||||||
#import <MobileCoreServices/UTCoreTypes.h>
|
#import <MobileCoreServices/UTCoreTypes.h>
|
||||||
#import <objc/message.h>
|
#import <objc/message.h>
|
||||||
|
|
||||||
#ifndef __CORDOVA_4_0_0
|
|
||||||
#import <Cordova/NSData+Base64.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CDV_PHOTO_PREFIX @"cdv_photo_"
|
#define CDV_PHOTO_PREFIX @"cdv_photo_"
|
||||||
|
|
||||||
static NSSet* org_apache_cordova_validArrowDirections;
|
static NSSet* org_apache_cordova_validArrowDirections;
|
||||||
@ -41,20 +39,9 @@ static NSSet* org_apache_cordova_validArrowDirections;
|
|||||||
static NSString* toBase64(NSData* data) {
|
static NSString* toBase64(NSData* data) {
|
||||||
SEL s1 = NSSelectorFromString(@"cdv_base64EncodedString");
|
SEL s1 = NSSelectorFromString(@"cdv_base64EncodedString");
|
||||||
SEL s2 = NSSelectorFromString(@"base64EncodedString");
|
SEL s2 = NSSelectorFromString(@"base64EncodedString");
|
||||||
SEL s3 = NSSelectorFromString(@"base64EncodedStringWithOptions:");
|
SEL realSel = [data respondsToSelector:s1] ? s1 : s2;
|
||||||
|
NSString* (*func)(id, SEL) = (void *)[data methodForSelector:realSel];
|
||||||
if ([data respondsToSelector:s1]) {
|
return func(data, realSel);
|
||||||
NSString* (*func)(id, SEL) = (void *)[data methodForSelector:s1];
|
|
||||||
return func(data, s1);
|
|
||||||
} else if ([data respondsToSelector:s2]) {
|
|
||||||
NSString* (*func)(id, SEL) = (void *)[data methodForSelector:s2];
|
|
||||||
return func(data, s2);
|
|
||||||
} else if ([data respondsToSelector:s3]) {
|
|
||||||
NSString* (*func)(id, SEL, NSUInteger) = (void *)[data methodForSelector:s3];
|
|
||||||
return func(data, s3, 0);
|
|
||||||
} else {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@implementation CDVPictureOptions
|
@implementation CDVPictureOptions
|
||||||
@ -63,10 +50,10 @@ static NSString* toBase64(NSData* data) {
|
|||||||
{
|
{
|
||||||
CDVPictureOptions* pictureOptions = [[CDVPictureOptions alloc] init];
|
CDVPictureOptions* pictureOptions = [[CDVPictureOptions alloc] init];
|
||||||
|
|
||||||
pictureOptions.quality = [command argumentAtIndex:0 withDefault:@(100)];
|
pictureOptions.quality = [command argumentAtIndex:0 withDefault:@(50)];
|
||||||
pictureOptions.destinationType = [[command argumentAtIndex:1 withDefault:@(DestinationTypeFileUri)] unsignedIntegerValue];
|
pictureOptions.destinationType = [[command argumentAtIndex:1 withDefault:@(DestinationTypeFileUri)] unsignedIntegerValue];
|
||||||
pictureOptions.sourceType = [[command argumentAtIndex:2 withDefault:@(UIImagePickerControllerSourceTypeCamera)] unsignedIntegerValue];
|
pictureOptions.sourceType = [[command argumentAtIndex:2 withDefault:@(UIImagePickerControllerSourceTypeCamera)] unsignedIntegerValue];
|
||||||
|
|
||||||
NSNumber* targetWidth = [command argumentAtIndex:3 withDefault:nil];
|
NSNumber* targetWidth = [command argumentAtIndex:3 withDefault:nil];
|
||||||
NSNumber* targetHeight = [command argumentAtIndex:4 withDefault:nil];
|
NSNumber* targetHeight = [command argumentAtIndex:4 withDefault:nil];
|
||||||
pictureOptions.targetSize = CGSizeMake(0, 0);
|
pictureOptions.targetSize = CGSizeMake(0, 0);
|
||||||
@ -81,10 +68,10 @@ static NSString* toBase64(NSData* data) {
|
|||||||
pictureOptions.saveToPhotoAlbum = [[command argumentAtIndex:9 withDefault:@(NO)] boolValue];
|
pictureOptions.saveToPhotoAlbum = [[command argumentAtIndex:9 withDefault:@(NO)] boolValue];
|
||||||
pictureOptions.popoverOptions = [command argumentAtIndex:10 withDefault:nil];
|
pictureOptions.popoverOptions = [command argumentAtIndex:10 withDefault:nil];
|
||||||
pictureOptions.cameraDirection = [[command argumentAtIndex:11 withDefault:@(UIImagePickerControllerCameraDeviceRear)] unsignedIntegerValue];
|
pictureOptions.cameraDirection = [[command argumentAtIndex:11 withDefault:@(UIImagePickerControllerCameraDeviceRear)] unsignedIntegerValue];
|
||||||
|
|
||||||
pictureOptions.popoverSupported = NO;
|
pictureOptions.popoverSupported = NO;
|
||||||
pictureOptions.usesGeolocation = NO;
|
pictureOptions.usesGeolocation = NO;
|
||||||
|
|
||||||
return pictureOptions;
|
return pictureOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +96,7 @@ static NSString* toBase64(NSData* data) {
|
|||||||
- (NSURL*) urlTransformer:(NSURL*)url
|
- (NSURL*) urlTransformer:(NSURL*)url
|
||||||
{
|
{
|
||||||
NSURL* urlToTransform = url;
|
NSURL* urlToTransform = url;
|
||||||
|
|
||||||
// for backwards compatibility - we check if this property is there
|
// for backwards compatibility - we check if this property is there
|
||||||
SEL sel = NSSelectorFromString(@"urlTransformer");
|
SEL sel = NSSelectorFromString(@"urlTransformer");
|
||||||
if ([self.commandDelegate respondsToSelector:sel]) {
|
if ([self.commandDelegate respondsToSelector:sel]) {
|
||||||
@ -120,7 +107,7 @@ static NSString* toBase64(NSData* data) {
|
|||||||
urlToTransform = urlTransformer(url);
|
urlToTransform = urlTransformer(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return urlToTransform;
|
return urlToTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,14 +126,16 @@ static NSString* toBase64(NSData* data) {
|
|||||||
- (void)takePicture:(CDVInvokedUrlCommand*)command
|
- (void)takePicture:(CDVInvokedUrlCommand*)command
|
||||||
{
|
{
|
||||||
self.hasPendingOperation = YES;
|
self.hasPendingOperation = YES;
|
||||||
|
|
||||||
__weak CDVCamera* weakSelf = self;
|
__weak CDVCamera* weakSelf = self;
|
||||||
|
|
||||||
[self.commandDelegate runInBackground:^{
|
[self.commandDelegate runInBackground:^{
|
||||||
|
|
||||||
CDVPictureOptions* pictureOptions = [CDVPictureOptions createFromTakePictureArguments:command];
|
CDVPictureOptions* pictureOptions = [CDVPictureOptions createFromTakePictureArguments:command];
|
||||||
pictureOptions.popoverSupported = [weakSelf popoverSupported];
|
pictureOptions.popoverSupported = [self popoverSupported];
|
||||||
pictureOptions.usesGeolocation = [weakSelf usesGeolocation];
|
pictureOptions.usesGeolocation = [self usesGeolocation];
|
||||||
pictureOptions.cropToSize = NO;
|
pictureOptions.cropToSize = NO;
|
||||||
|
|
||||||
BOOL hasCamera = [UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType];
|
BOOL hasCamera = [UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType];
|
||||||
if (!hasCamera) {
|
if (!hasCamera) {
|
||||||
NSLog(@"Camera.getPicture: source type %lu not available.", (unsigned long)pictureOptions.sourceType);
|
NSLog(@"Camera.getPicture: source type %lu not available.", (unsigned long)pictureOptions.sourceType);
|
||||||
@ -154,95 +143,49 @@ static NSString* toBase64(NSData* data) {
|
|||||||
[weakSelf.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
[weakSelf.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a popover is already open, close it; we only want one at a time.
|
||||||
|
if (([[weakSelf pickerController] pickerPopoverController] != nil) && [[[weakSelf pickerController] pickerPopoverController] isPopoverVisible]) {
|
||||||
|
[[[weakSelf pickerController] pickerPopoverController] dismissPopoverAnimated:YES];
|
||||||
|
[[[weakSelf pickerController] pickerPopoverController] setDelegate:nil];
|
||||||
|
[[weakSelf pickerController] setPickerPopoverController:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
CDVCameraPicker* cameraPicker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
||||||
|
weakSelf.pickerController = cameraPicker;
|
||||||
|
|
||||||
|
cameraPicker.delegate = weakSelf;
|
||||||
|
cameraPicker.callbackId = command.callbackId;
|
||||||
|
// we need to capture this state for memory warnings that dealloc this object
|
||||||
|
cameraPicker.webView = weakSelf.webView;
|
||||||
|
|
||||||
|
if ([weakSelf popoverSupported] && (pictureOptions.sourceType != UIImagePickerControllerSourceTypeCamera)) {
|
||||||
|
if (cameraPicker.pickerPopoverController == nil) {
|
||||||
|
cameraPicker.pickerPopoverController = [[NSClassFromString(@"UIPopoverController") alloc] initWithContentViewController:cameraPicker];
|
||||||
|
}
|
||||||
|
[weakSelf displayPopover:pictureOptions.popoverOptions];
|
||||||
|
weakSelf.hasPendingOperation = NO;
|
||||||
|
|
||||||
// Validate the app has permission to access the camera
|
|
||||||
if (pictureOptions.sourceType == UIImagePickerControllerSourceTypeCamera) {
|
|
||||||
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted)
|
|
||||||
{
|
|
||||||
if(!granted)
|
|
||||||
{
|
|
||||||
// Denied; show an alert
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
|
||||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"] message:NSLocalizedString(@"Access to the camera has been prohibited; please enable it in the Settings app to continue.", nil) preferredStyle:UIAlertControllerStyleAlert];
|
|
||||||
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
|
||||||
[weakSelf sendNoPermissionResult:command.callbackId];
|
|
||||||
}]];
|
|
||||||
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Settings", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
|
||||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
|
|
||||||
[weakSelf sendNoPermissionResult:command.callbackId];
|
|
||||||
}]];
|
|
||||||
[weakSelf.viewController presentViewController:alertController animated:YES completion:nil];
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
[weakSelf showCameraPicker:command.callbackId withOptions:pictureOptions];
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
} else {
|
} else {
|
||||||
[weakSelf showCameraPicker:command.callbackId withOptions:pictureOptions];
|
[weakSelf.viewController presentViewController:cameraPicker animated:YES completion:^{
|
||||||
|
weakSelf.hasPendingOperation = NO;
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)showCameraPicker:(NSString*)callbackId withOptions:(CDVPictureOptions *) pictureOptions
|
|
||||||
{
|
|
||||||
// Perform UI operations on the main thread
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
|
||||||
CDVCameraPicker* cameraPicker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
|
||||||
self.pickerController = cameraPicker;
|
|
||||||
|
|
||||||
cameraPicker.delegate = self;
|
|
||||||
cameraPicker.callbackId = callbackId;
|
|
||||||
// we need to capture this state for memory warnings that dealloc this object
|
|
||||||
cameraPicker.webView = self.webView;
|
|
||||||
|
|
||||||
// If a popover is already open, close it; we only want one at a time.
|
|
||||||
if (([[self pickerController] pickerPopoverController] != nil) && [[[self pickerController] pickerPopoverController] isPopoverVisible]) {
|
|
||||||
[[[self pickerController] pickerPopoverController] dismissPopoverAnimated:YES];
|
|
||||||
[[[self pickerController] pickerPopoverController] setDelegate:nil];
|
|
||||||
[[self pickerController] setPickerPopoverController:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([self popoverSupported] && (pictureOptions.sourceType != UIImagePickerControllerSourceTypeCamera)) {
|
|
||||||
if (cameraPicker.pickerPopoverController == nil) {
|
|
||||||
cameraPicker.pickerPopoverController = [[NSClassFromString(@"UIPopoverController") alloc] initWithContentViewController:cameraPicker];
|
|
||||||
}
|
|
||||||
[self displayPopover:pictureOptions.popoverOptions];
|
|
||||||
self.hasPendingOperation = NO;
|
|
||||||
} else {
|
|
||||||
cameraPicker.modalPresentationStyle = UIModalPresentationCurrentContext;
|
|
||||||
[self.viewController presentViewController:cameraPicker animated:YES completion:^{
|
|
||||||
self.hasPendingOperation = NO;
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)sendNoPermissionResult:(NSString*)callbackId
|
|
||||||
{
|
|
||||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"has no access to camera"]; // error callback expects string ATM
|
|
||||||
|
|
||||||
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
|
|
||||||
|
|
||||||
self.hasPendingOperation = NO;
|
|
||||||
self.pickerController = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)repositionPopover:(CDVInvokedUrlCommand*)command
|
- (void)repositionPopover:(CDVInvokedUrlCommand*)command
|
||||||
{
|
{
|
||||||
if (([[self pickerController] pickerPopoverController] != nil) && [[[self pickerController] pickerPopoverController] isPopoverVisible]) {
|
NSDictionary* options = [command argumentAtIndex:0 withDefault:nil];
|
||||||
|
|
||||||
[[[self pickerController] pickerPopoverController] dismissPopoverAnimated:NO];
|
[self displayPopover:options];
|
||||||
|
|
||||||
NSDictionary* options = [command argumentAtIndex:0 withDefault:nil];
|
|
||||||
[self displayPopover:options];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSInteger)integerValueForKey:(NSDictionary*)dict key:(NSString*)key defaultValue:(NSInteger)defaultValue
|
- (NSInteger)integerValueForKey:(NSDictionary*)dict key:(NSString*)key defaultValue:(NSInteger)defaultValue
|
||||||
{
|
{
|
||||||
NSInteger value = defaultValue;
|
NSInteger value = defaultValue;
|
||||||
|
|
||||||
NSNumber* val = [dict valueForKey:key]; // value is an NSNumber
|
NSNumber* val = [self valueForKey:key]; // value is an NSNumber
|
||||||
|
|
||||||
if (val != nil) {
|
if (val != nil) {
|
||||||
value = [val integerValue];
|
value = [val integerValue];
|
||||||
@ -279,23 +222,10 @@ static NSString* toBase64(NSData* data) {
|
|||||||
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
|
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
|
||||||
{
|
{
|
||||||
if([navigationController isKindOfClass:[UIImagePickerController class]]){
|
if([navigationController isKindOfClass:[UIImagePickerController class]]){
|
||||||
|
|
||||||
// If popoverWidth and popoverHeight are specified and are greater than 0, then set popover size, else use apple's default popoverSize
|
|
||||||
NSDictionary* options = self.pickerController.pictureOptions.popoverOptions;
|
|
||||||
if(options) {
|
|
||||||
NSInteger popoverWidth = [self integerValueForKey:options key:@"popoverWidth" defaultValue:0];
|
|
||||||
NSInteger popoverHeight = [self integerValueForKey:options key:@"popoverHeight" defaultValue:0];
|
|
||||||
if(popoverWidth > 0 && popoverHeight > 0)
|
|
||||||
{
|
|
||||||
[viewController setPreferredContentSize:CGSizeMake(popoverWidth,popoverHeight)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
UIImagePickerController* cameraPicker = (UIImagePickerController*)navigationController;
|
UIImagePickerController* cameraPicker = (UIImagePickerController*)navigationController;
|
||||||
|
|
||||||
if(![cameraPicker.mediaTypes containsObject:(NSString*)kUTTypeImage]){
|
if(![cameraPicker.mediaTypes containsObject:(NSString*)kUTTypeImage]){
|
||||||
[viewController.navigationItem setTitle:NSLocalizedString(@"Videos", nil)];
|
[viewController.navigationItem setTitle:NSLocalizedString(@"Videos title", nil)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -353,35 +283,35 @@ static NSString* toBase64(NSData* data) {
|
|||||||
- (NSData*)processImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPictureOptions*)options
|
- (NSData*)processImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPictureOptions*)options
|
||||||
{
|
{
|
||||||
NSData* data = nil;
|
NSData* data = nil;
|
||||||
|
|
||||||
switch (options.encodingType) {
|
switch (options.encodingType) {
|
||||||
case EncodingTypePNG:
|
case EncodingTypePNG:
|
||||||
data = UIImagePNGRepresentation(image);
|
data = UIImagePNGRepresentation(image);
|
||||||
break;
|
break;
|
||||||
case EncodingTypeJPEG:
|
case EncodingTypeJPEG:
|
||||||
{
|
{
|
||||||
if ((options.allowsEditing == NO) && (options.targetSize.width <= 0) && (options.targetSize.height <= 0) && (options.correctOrientation == NO) && (([options.quality integerValue] == 100) || (options.sourceType != UIImagePickerControllerSourceTypeCamera))){
|
if ((options.allowsEditing == NO) && (options.targetSize.width <= 0) && (options.targetSize.height <= 0) && (options.correctOrientation == NO)){
|
||||||
// use image unedited as requested , don't resize
|
// use image unedited as requested , don't resize
|
||||||
data = UIImageJPEGRepresentation(image, 1.0);
|
data = UIImageJPEGRepresentation(image, 1.0);
|
||||||
} else {
|
} else {
|
||||||
data = UIImageJPEGRepresentation(image, [options.quality floatValue] / 100.0f);
|
if (options.usesGeolocation) {
|
||||||
}
|
NSDictionary* controllerMetadata = [info objectForKey:@"UIImagePickerControllerMediaMetadata"];
|
||||||
|
if (controllerMetadata) {
|
||||||
if (options.usesGeolocation) {
|
self.data = data;
|
||||||
NSDictionary* controllerMetadata = [info objectForKey:@"UIImagePickerControllerMediaMetadata"];
|
self.metadata = [[NSMutableDictionary alloc] init];
|
||||||
if (controllerMetadata) {
|
|
||||||
self.data = data;
|
NSMutableDictionary* EXIFDictionary = [[controllerMetadata objectForKey:(NSString*)kCGImagePropertyExifDictionary]mutableCopy];
|
||||||
self.metadata = [[NSMutableDictionary alloc] init];
|
if (EXIFDictionary) {
|
||||||
|
[self.metadata setObject:EXIFDictionary forKey:(NSString*)kCGImagePropertyExifDictionary];
|
||||||
NSMutableDictionary* EXIFDictionary = [[controllerMetadata objectForKey:(NSString*)kCGImagePropertyExifDictionary]mutableCopy];
|
}
|
||||||
if (EXIFDictionary) {
|
|
||||||
[self.metadata setObject:EXIFDictionary forKey:(NSString*)kCGImagePropertyExifDictionary];
|
if (IsAtLeastiOSVersion(@"8.0")) {
|
||||||
|
[[self locationManager] performSelector:NSSelectorFromString(@"requestWhenInUseAuthorization") withObject:nil afterDelay:0];
|
||||||
|
}
|
||||||
|
[[self locationManager] startUpdatingLocation];
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if (IsAtLeastiOSVersion(@"8.0")) {
|
data = UIImageJPEGRepresentation(image, [options.quality floatValue] / 100.0f);
|
||||||
[[self locationManager] performSelector:NSSelectorFromString(@"requestWhenInUseAuthorization") withObject:nil afterDelay:0];
|
|
||||||
}
|
|
||||||
[[self locationManager] startUpdatingLocation];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -389,7 +319,7 @@ static NSString* toBase64(NSData* data) {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,14 +328,13 @@ static NSString* toBase64(NSData* data) {
|
|||||||
NSString* docsPath = [NSTemporaryDirectory()stringByStandardizingPath];
|
NSString* docsPath = [NSTemporaryDirectory()stringByStandardizingPath];
|
||||||
NSFileManager* fileMgr = [[NSFileManager alloc] init]; // recommended by Apple (vs [NSFileManager defaultManager]) to be threadsafe
|
NSFileManager* fileMgr = [[NSFileManager alloc] init]; // recommended by Apple (vs [NSFileManager defaultManager]) to be threadsafe
|
||||||
NSString* filePath;
|
NSString* filePath;
|
||||||
|
|
||||||
// unique file name
|
// generate unique file name
|
||||||
NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
|
int i = 1;
|
||||||
NSNumber *timeStampObj = [NSNumber numberWithDouble: timeStamp];
|
|
||||||
do {
|
do {
|
||||||
filePath = [NSString stringWithFormat:@"%@/%@%ld.%@", docsPath, CDV_PHOTO_PREFIX, [timeStampObj longValue], extension];
|
filePath = [NSString stringWithFormat:@"%@/%@%03d.%@", docsPath, CDV_PHOTO_PREFIX, i++, extension];
|
||||||
} while ([fileMgr fileExistsAtPath:filePath]);
|
} while ([fileMgr fileExistsAtPath:filePath]);
|
||||||
|
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,13 +347,13 @@ static NSString* toBase64(NSData* data) {
|
|||||||
} else {
|
} else {
|
||||||
image = [info objectForKey:UIImagePickerControllerOriginalImage];
|
image = [info objectForKey:UIImagePickerControllerOriginalImage];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.correctOrientation) {
|
if (options.correctOrientation) {
|
||||||
image = [image imageCorrectedForCaptureOrientation];
|
image = [image imageCorrectedForCaptureOrientation];
|
||||||
}
|
}
|
||||||
|
|
||||||
UIImage* scaledImage = nil;
|
UIImage* scaledImage = nil;
|
||||||
|
|
||||||
if ((options.targetSize.width > 0) && (options.targetSize.height > 0)) {
|
if ((options.targetSize.width > 0) && (options.targetSize.height > 0)) {
|
||||||
// if cropToSize, resize image and crop to target size, otherwise resize to fit target without cropping
|
// if cropToSize, resize image and crop to target size, otherwise resize to fit target without cropping
|
||||||
if (options.cropToSize) {
|
if (options.cropToSize) {
|
||||||
@ -433,11 +362,11 @@ static NSString* toBase64(NSData* data) {
|
|||||||
scaledImage = [image imageByScalingNotCroppingForSize:options.targetSize];
|
scaledImage = [image imageByScalingNotCroppingForSize:options.targetSize];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (scaledImage == nil ? image : scaledImage);
|
return (scaledImage == nil ? image : scaledImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)resultForImage:(CDVPictureOptions*)options info:(NSDictionary*)info completion:(void (^)(CDVPluginResult* res))completion
|
- (CDVPluginResult*)resultForImage:(CDVPictureOptions*)options info:(NSDictionary*)info
|
||||||
{
|
{
|
||||||
CDVPluginResult* result = nil;
|
CDVPluginResult* result = nil;
|
||||||
BOOL saveToPhotoAlbum = options.saveToPhotoAlbum;
|
BOOL saveToPhotoAlbum = options.saveToPhotoAlbum;
|
||||||
@ -446,28 +375,10 @@ static NSString* toBase64(NSData* data) {
|
|||||||
switch (options.destinationType) {
|
switch (options.destinationType) {
|
||||||
case DestinationTypeNativeUri:
|
case DestinationTypeNativeUri:
|
||||||
{
|
{
|
||||||
NSURL* url = [info objectForKey:UIImagePickerControllerReferenceURL];
|
NSURL* url = (NSURL*)[info objectForKey:UIImagePickerControllerReferenceURL];
|
||||||
|
NSString* nativeUri = [[self urlTransformer:url] absoluteString];
|
||||||
|
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nativeUri];
|
||||||
saveToPhotoAlbum = NO;
|
saveToPhotoAlbum = NO;
|
||||||
// If, for example, we use sourceType = Camera, URL might be nil because image is stored in memory.
|
|
||||||
// In this case we must save image to device before obtaining an URI.
|
|
||||||
if (url == nil) {
|
|
||||||
image = [self retrieveImage:info options:options];
|
|
||||||
ALAssetsLibrary* library = [ALAssetsLibrary new];
|
|
||||||
[library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:^(NSURL *assetURL, NSError *error) {
|
|
||||||
CDVPluginResult* resultToReturn = nil;
|
|
||||||
if (error) {
|
|
||||||
resultToReturn = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]];
|
|
||||||
} else {
|
|
||||||
NSString* nativeUri = [[self urlTransformer:assetURL] absoluteString];
|
|
||||||
resultToReturn = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nativeUri];
|
|
||||||
}
|
|
||||||
completion(resultToReturn);
|
|
||||||
}];
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
NSString* nativeUri = [[self urlTransformer:url] absoluteString];
|
|
||||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nativeUri];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DestinationTypeFileUri:
|
case DestinationTypeFileUri:
|
||||||
@ -475,11 +386,11 @@ static NSString* toBase64(NSData* data) {
|
|||||||
image = [self retrieveImage:info options:options];
|
image = [self retrieveImage:info options:options];
|
||||||
NSData* data = [self processImage:image info:info options:options];
|
NSData* data = [self processImage:image info:info options:options];
|
||||||
if (data) {
|
if (data) {
|
||||||
|
|
||||||
NSString* extension = options.encodingType == EncodingTypePNG? @"png" : @"jpg";
|
NSString* extension = options.encodingType == EncodingTypePNG? @"png" : @"jpg";
|
||||||
NSString* filePath = [self tempFilePath:extension];
|
NSString* filePath = [self tempFilePath:extension];
|
||||||
NSError* err = nil;
|
NSError* err = nil;
|
||||||
|
|
||||||
// save file
|
// save file
|
||||||
if (![data writeToFile:filePath options:NSAtomicWrite error:&err]) {
|
if (![data writeToFile:filePath options:NSAtomicWrite error:&err]) {
|
||||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[err localizedDescription]];
|
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[err localizedDescription]];
|
||||||
@ -493,6 +404,7 @@ static NSString* toBase64(NSData* data) {
|
|||||||
{
|
{
|
||||||
image = [self retrieveImage:info options:options];
|
image = [self retrieveImage:info options:options];
|
||||||
NSData* data = [self processImage:image info:info options:options];
|
NSData* data = [self processImage:image info:info options:options];
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(data)];
|
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(data)];
|
||||||
}
|
}
|
||||||
@ -501,60 +413,44 @@ static NSString* toBase64(NSData* data) {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (saveToPhotoAlbum && image) {
|
if (saveToPhotoAlbum && image) {
|
||||||
ALAssetsLibrary* library = [ALAssetsLibrary new];
|
ALAssetsLibrary* library = [ALAssetsLibrary new];
|
||||||
[library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:nil];
|
[library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
completion(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CDVPluginResult*)resultForVideo:(NSDictionary*)info
|
- (CDVPluginResult*)resultForVideo:(NSDictionary*)info
|
||||||
{
|
{
|
||||||
NSString* moviePath = [[info objectForKey:UIImagePickerControllerMediaURL] absoluteString];
|
NSString* moviePath = [[info objectForKey:UIImagePickerControllerMediaURL] absoluteString];
|
||||||
// On iOS 13 the movie path becomes inaccessible, create and return a copy
|
|
||||||
if (IsAtLeastiOSVersion(@"13.0")) {
|
|
||||||
moviePath = [self createTmpVideo:[[info objectForKey:UIImagePickerControllerMediaURL] path]];
|
|
||||||
}
|
|
||||||
return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:moviePath];
|
return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:moviePath];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) createTmpVideo:(NSString *) moviePath {
|
|
||||||
NSString* moviePathExtension = [moviePath pathExtension];
|
|
||||||
NSString* copyMoviePath = [self tempFilePath:moviePathExtension];
|
|
||||||
NSFileManager* fileMgr = [[NSFileManager alloc] init];
|
|
||||||
NSError *error;
|
|
||||||
[fileMgr copyItemAtPath:moviePath toPath:copyMoviePath error:&error];
|
|
||||||
return [[NSURL fileURLWithPath:copyMoviePath] absoluteString];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
|
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
|
||||||
{
|
{
|
||||||
__weak CDVCameraPicker* cameraPicker = (CDVCameraPicker*)picker;
|
__weak CDVCameraPicker* cameraPicker = (CDVCameraPicker*)picker;
|
||||||
__weak CDVCamera* weakSelf = self;
|
__weak CDVCamera* weakSelf = self;
|
||||||
|
|
||||||
dispatch_block_t invoke = ^(void) {
|
dispatch_block_t invoke = ^(void) {
|
||||||
__block CDVPluginResult* result = nil;
|
__block CDVPluginResult* result = nil;
|
||||||
|
|
||||||
NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
|
NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
|
||||||
if ([mediaType isEqualToString:(NSString*)kUTTypeImage]) {
|
if ([mediaType isEqualToString:(NSString*)kUTTypeImage]) {
|
||||||
[weakSelf resultForImage:cameraPicker.pictureOptions info:info completion:^(CDVPluginResult* res) {
|
result = [self resultForImage:cameraPicker.pictureOptions info:info];
|
||||||
if (![self usesGeolocation] || picker.sourceType != UIImagePickerControllerSourceTypeCamera) {
|
|
||||||
[weakSelf.commandDelegate sendPluginResult:res callbackId:cameraPicker.callbackId];
|
|
||||||
weakSelf.hasPendingOperation = NO;
|
|
||||||
weakSelf.pickerController = nil;
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = [weakSelf resultForVideo:info];
|
result = [self resultForVideo:info];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
[weakSelf.commandDelegate sendPluginResult:result callbackId:cameraPicker.callbackId];
|
[weakSelf.commandDelegate sendPluginResult:result callbackId:cameraPicker.callbackId];
|
||||||
weakSelf.hasPendingOperation = NO;
|
weakSelf.hasPendingOperation = NO;
|
||||||
weakSelf.pickerController = nil;
|
weakSelf.pickerController = nil;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (cameraPicker.pictureOptions.popoverSupported && (cameraPicker.pickerPopoverController != nil)) {
|
if (cameraPicker.pictureOptions.popoverSupported && (cameraPicker.pickerPopoverController != nil)) {
|
||||||
[cameraPicker.pickerPopoverController dismissPopoverAnimated:YES];
|
[cameraPicker.pickerPopoverController dismissPopoverAnimated:YES];
|
||||||
cameraPicker.pickerPopoverController.delegate = nil;
|
cameraPicker.pickerPopoverController.delegate = nil;
|
||||||
@ -577,20 +473,17 @@ static NSString* toBase64(NSData* data) {
|
|||||||
{
|
{
|
||||||
__weak CDVCameraPicker* cameraPicker = (CDVCameraPicker*)picker;
|
__weak CDVCameraPicker* cameraPicker = (CDVCameraPicker*)picker;
|
||||||
__weak CDVCamera* weakSelf = self;
|
__weak CDVCamera* weakSelf = self;
|
||||||
|
|
||||||
dispatch_block_t invoke = ^ (void) {
|
dispatch_block_t invoke = ^ (void) {
|
||||||
CDVPluginResult* result;
|
CDVPluginResult* result;
|
||||||
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera && [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo] != ALAuthorizationStatusAuthorized) {
|
if ([ALAssetsLibrary authorizationStatus] == ALAuthorizationStatusAuthorized) {
|
||||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"has no access to camera"];
|
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no image selected"];
|
||||||
} else if (picker.sourceType != UIImagePickerControllerSourceTypeCamera && ! IsAtLeastiOSVersion(@"11.0") && [ALAssetsLibrary authorizationStatus] != ALAuthorizationStatusAuthorized) {
|
|
||||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"has no access to assets"];
|
|
||||||
} else {
|
} else {
|
||||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No Image Selected"];
|
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"has no access to assets"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[weakSelf.commandDelegate sendPluginResult:result callbackId:cameraPicker.callbackId];
|
[weakSelf.commandDelegate sendPluginResult:result callbackId:cameraPicker.callbackId];
|
||||||
|
|
||||||
weakSelf.hasPendingOperation = NO;
|
weakSelf.hasPendingOperation = NO;
|
||||||
weakSelf.pickerController = nil;
|
weakSelf.pickerController = nil;
|
||||||
};
|
};
|
||||||
@ -600,15 +493,15 @@ static NSString* toBase64(NSData* data) {
|
|||||||
|
|
||||||
- (CLLocationManager*)locationManager
|
- (CLLocationManager*)locationManager
|
||||||
{
|
{
|
||||||
if (locationManager != nil) {
|
if (locationManager != nil) {
|
||||||
return locationManager;
|
return locationManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
locationManager = [[CLLocationManager alloc] init];
|
locationManager = [[CLLocationManager alloc] init];
|
||||||
[locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
|
[locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
|
||||||
[locationManager setDelegate:self];
|
[locationManager setDelegate:self];
|
||||||
|
|
||||||
return locationManager;
|
return locationManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation*)oldLocation
|
- (void)locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation*)oldLocation
|
||||||
@ -616,15 +509,15 @@ static NSString* toBase64(NSData* data) {
|
|||||||
if (locationManager == nil) {
|
if (locationManager == nil) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[self.locationManager stopUpdatingLocation];
|
[self.locationManager stopUpdatingLocation];
|
||||||
self.locationManager = nil;
|
self.locationManager = nil;
|
||||||
|
|
||||||
NSMutableDictionary *GPSDictionary = [[NSMutableDictionary dictionary] init];
|
NSMutableDictionary *GPSDictionary = [[NSMutableDictionary dictionary] init];
|
||||||
|
|
||||||
CLLocationDegrees latitude = newLocation.coordinate.latitude;
|
CLLocationDegrees latitude = newLocation.coordinate.latitude;
|
||||||
CLLocationDegrees longitude = newLocation.coordinate.longitude;
|
CLLocationDegrees longitude = newLocation.coordinate.longitude;
|
||||||
|
|
||||||
// latitude
|
// latitude
|
||||||
if (latitude < 0.0) {
|
if (latitude < 0.0) {
|
||||||
latitude = latitude * -1.0f;
|
latitude = latitude * -1.0f;
|
||||||
@ -633,7 +526,7 @@ static NSString* toBase64(NSData* data) {
|
|||||||
[GPSDictionary setObject:@"N" forKey:(NSString*)kCGImagePropertyGPSLatitudeRef];
|
[GPSDictionary setObject:@"N" forKey:(NSString*)kCGImagePropertyGPSLatitudeRef];
|
||||||
}
|
}
|
||||||
[GPSDictionary setObject:[NSNumber numberWithFloat:latitude] forKey:(NSString*)kCGImagePropertyGPSLatitude];
|
[GPSDictionary setObject:[NSNumber numberWithFloat:latitude] forKey:(NSString*)kCGImagePropertyGPSLatitude];
|
||||||
|
|
||||||
// longitude
|
// longitude
|
||||||
if (longitude < 0.0) {
|
if (longitude < 0.0) {
|
||||||
longitude = longitude * -1.0f;
|
longitude = longitude * -1.0f;
|
||||||
@ -643,7 +536,7 @@ static NSString* toBase64(NSData* data) {
|
|||||||
[GPSDictionary setObject:@"E" forKey:(NSString*)kCGImagePropertyGPSLongitudeRef];
|
[GPSDictionary setObject:@"E" forKey:(NSString*)kCGImagePropertyGPSLongitudeRef];
|
||||||
}
|
}
|
||||||
[GPSDictionary setObject:[NSNumber numberWithFloat:longitude] forKey:(NSString*)kCGImagePropertyGPSLongitude];
|
[GPSDictionary setObject:[NSNumber numberWithFloat:longitude] forKey:(NSString*)kCGImagePropertyGPSLongitude];
|
||||||
|
|
||||||
// altitude
|
// altitude
|
||||||
CGFloat altitude = newLocation.altitude;
|
CGFloat altitude = newLocation.altitude;
|
||||||
if (!isnan(altitude)){
|
if (!isnan(altitude)){
|
||||||
@ -655,7 +548,7 @@ static NSString* toBase64(NSData* data) {
|
|||||||
}
|
}
|
||||||
[GPSDictionary setObject:[NSNumber numberWithFloat:altitude] forKey:(NSString *)kCGImagePropertyGPSAltitude];
|
[GPSDictionary setObject:[NSNumber numberWithFloat:altitude] forKey:(NSString *)kCGImagePropertyGPSAltitude];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time and date
|
// Time and date
|
||||||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||||||
[formatter setDateFormat:@"HH:mm:ss.SSSSSS"];
|
[formatter setDateFormat:@"HH:mm:ss.SSSSSS"];
|
||||||
@ -663,7 +556,7 @@ static NSString* toBase64(NSData* data) {
|
|||||||
[GPSDictionary setObject:[formatter stringFromDate:newLocation.timestamp] forKey:(NSString *)kCGImagePropertyGPSTimeStamp];
|
[GPSDictionary setObject:[formatter stringFromDate:newLocation.timestamp] forKey:(NSString *)kCGImagePropertyGPSTimeStamp];
|
||||||
[formatter setDateFormat:@"yyyy:MM:dd"];
|
[formatter setDateFormat:@"yyyy:MM:dd"];
|
||||||
[GPSDictionary setObject:[formatter stringFromDate:newLocation.timestamp] forKey:(NSString *)kCGImagePropertyGPSDateStamp];
|
[GPSDictionary setObject:[formatter stringFromDate:newLocation.timestamp] forKey:(NSString *)kCGImagePropertyGPSDateStamp];
|
||||||
|
|
||||||
[self.metadata setObject:GPSDictionary forKey:(NSString *)kCGImagePropertyGPSDictionary];
|
[self.metadata setObject:GPSDictionary forKey:(NSString *)kCGImagePropertyGPSDictionary];
|
||||||
[self imagePickerControllerReturnImageResult];
|
[self imagePickerControllerReturnImageResult];
|
||||||
}
|
}
|
||||||
@ -676,7 +569,7 @@ static NSString* toBase64(NSData* data) {
|
|||||||
|
|
||||||
[self.locationManager stopUpdatingLocation];
|
[self.locationManager stopUpdatingLocation];
|
||||||
self.locationManager = nil;
|
self.locationManager = nil;
|
||||||
|
|
||||||
[self imagePickerControllerReturnImageResult];
|
[self imagePickerControllerReturnImageResult];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -684,26 +577,26 @@ static NSString* toBase64(NSData* data) {
|
|||||||
{
|
{
|
||||||
CDVPictureOptions* options = self.pickerController.pictureOptions;
|
CDVPictureOptions* options = self.pickerController.pictureOptions;
|
||||||
CDVPluginResult* result = nil;
|
CDVPluginResult* result = nil;
|
||||||
|
|
||||||
if (self.metadata) {
|
if (self.metadata) {
|
||||||
CGImageSourceRef sourceImage = CGImageSourceCreateWithData((__bridge CFDataRef)self.data, NULL);
|
CGImageSourceRef sourceImage = CGImageSourceCreateWithData((__bridge CFDataRef)self.data, NULL);
|
||||||
CFStringRef sourceType = CGImageSourceGetType(sourceImage);
|
CFStringRef sourceType = CGImageSourceGetType(sourceImage);
|
||||||
|
|
||||||
CGImageDestinationRef destinationImage = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)self.data, sourceType, 1, NULL);
|
CGImageDestinationRef destinationImage = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)self.data, sourceType, 1, NULL);
|
||||||
CGImageDestinationAddImageFromSource(destinationImage, sourceImage, 0, (__bridge CFDictionaryRef)self.metadata);
|
CGImageDestinationAddImageFromSource(destinationImage, sourceImage, 0, (__bridge CFDictionaryRef)self.metadata);
|
||||||
CGImageDestinationFinalize(destinationImage);
|
CGImageDestinationFinalize(destinationImage);
|
||||||
|
|
||||||
CFRelease(sourceImage);
|
CFRelease(sourceImage);
|
||||||
CFRelease(destinationImage);
|
CFRelease(destinationImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (options.destinationType) {
|
switch (options.destinationType) {
|
||||||
case DestinationTypeFileUri:
|
case DestinationTypeFileUri:
|
||||||
{
|
{
|
||||||
NSError* err = nil;
|
NSError* err = nil;
|
||||||
NSString* extension = self.pickerController.pictureOptions.encodingType == EncodingTypePNG ? @"png":@"jpg";
|
NSString* extension = self.pickerController.pictureOptions.encodingType == EncodingTypePNG ? @"png":@"jpg";
|
||||||
NSString* filePath = [self tempFilePath:extension];
|
NSString* filePath = [self tempFilePath:extension];
|
||||||
|
|
||||||
// save file
|
// save file
|
||||||
if (![self.data writeToFile:filePath options:NSAtomicWrite error:&err]) {
|
if (![self.data writeToFile:filePath options:NSAtomicWrite error:&err]) {
|
||||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[err localizedDescription]];
|
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[err localizedDescription]];
|
||||||
@ -722,16 +615,16 @@ static NSString* toBase64(NSData* data) {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
[self.commandDelegate sendPluginResult:result callbackId:self.pickerController.callbackId];
|
[self.commandDelegate sendPluginResult:result callbackId:self.pickerController.callbackId];
|
||||||
}
|
}
|
||||||
|
|
||||||
self.hasPendingOperation = NO;
|
self.hasPendingOperation = NO;
|
||||||
self.pickerController = nil;
|
self.pickerController = nil;
|
||||||
self.data = nil;
|
self.data = nil;
|
||||||
self.metadata = nil;
|
self.metadata = nil;
|
||||||
|
|
||||||
if (options.saveToPhotoAlbum) {
|
if (options.saveToPhotoAlbum) {
|
||||||
ALAssetsLibrary *library = [ALAssetsLibrary new];
|
ALAssetsLibrary *library = [ALAssetsLibrary new];
|
||||||
[library writeImageDataToSavedPhotosAlbum:self.data metadata:self.metadata completionBlock:nil];
|
[library writeImageDataToSavedPhotosAlbum:self.data metadata:self.metadata completionBlock:nil];
|
||||||
@ -751,14 +644,14 @@ static NSString* toBase64(NSData* data) {
|
|||||||
{
|
{
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewWillAppear:(BOOL)animated
|
- (void)viewWillAppear:(BOOL)animated
|
||||||
{
|
{
|
||||||
SEL sel = NSSelectorFromString(@"setNeedsStatusBarAppearanceUpdate");
|
SEL sel = NSSelectorFromString(@"setNeedsStatusBarAppearanceUpdate");
|
||||||
if ([self respondsToSelector:sel]) {
|
if ([self respondsToSelector:sel]) {
|
||||||
[self performSelector:sel withObject:nil afterDelay:0];
|
[self performSelector:sel withObject:nil afterDelay:0];
|
||||||
}
|
}
|
||||||
|
|
||||||
[super viewWillAppear:animated];
|
[super viewWillAppear:animated];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -768,7 +661,7 @@ static NSString* toBase64(NSData* data) {
|
|||||||
cameraPicker.pictureOptions = pictureOptions;
|
cameraPicker.pictureOptions = pictureOptions;
|
||||||
cameraPicker.sourceType = pictureOptions.sourceType;
|
cameraPicker.sourceType = pictureOptions.sourceType;
|
||||||
cameraPicker.allowsEditing = pictureOptions.allowsEditing;
|
cameraPicker.allowsEditing = pictureOptions.allowsEditing;
|
||||||
|
|
||||||
if (cameraPicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
|
if (cameraPicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
|
||||||
// We only allow taking pictures (no video) in this API.
|
// We only allow taking pictures (no video) in this API.
|
||||||
cameraPicker.mediaTypes = @[(NSString*)kUTTypeImage];
|
cameraPicker.mediaTypes = @[(NSString*)kUTTypeImage];
|
||||||
@ -780,7 +673,7 @@ static NSString* toBase64(NSData* data) {
|
|||||||
NSArray* mediaArray = @[(NSString*)(pictureOptions.mediaType == MediaTypeVideo ? kUTTypeMovie : kUTTypeImage)];
|
NSArray* mediaArray = @[(NSString*)(pictureOptions.mediaType == MediaTypeVideo ? kUTTypeMovie : kUTTypeImage)];
|
||||||
cameraPicker.mediaTypes = mediaArray;
|
cameraPicker.mediaTypes = mediaArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cameraPicker;
|
return cameraPicker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
#import <UIKit/UIKit.h>
|
|
||||||
|
|
||||||
@class AVCaptureSession;
|
|
||||||
|
|
||||||
@interface AVCamPreviewView : UIView
|
|
||||||
|
|
||||||
@property (nonatomic) AVCaptureSession *session;
|
|
||||||
|
|
||||||
@end
|
|
@ -1,21 +0,0 @@
|
|||||||
#import "AVCamPreviewView.h"
|
|
||||||
#import <AVFoundation/AVFoundation.h>
|
|
||||||
|
|
||||||
@implementation AVCamPreviewView
|
|
||||||
|
|
||||||
+ (Class)layerClass
|
|
||||||
{
|
|
||||||
return [AVCaptureVideoPreviewLayer class];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (AVCaptureSession *)session
|
|
||||||
{
|
|
||||||
return [(AVCaptureVideoPreviewLayer *)[self layer] session];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setSession:(AVCaptureSession *)session
|
|
||||||
{
|
|
||||||
[(AVCaptureVideoPreviewLayer *)[self layer] setSession:session];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
@ -1,35 +0,0 @@
|
|||||||
#import <UIKit/UIKit.h>
|
|
||||||
#import "CameraParameter.h"
|
|
||||||
|
|
||||||
@interface AVCamViewController : UIViewController
|
|
||||||
{
|
|
||||||
NSData *_imageData;
|
|
||||||
void (^_callback)(UIImage *, NSString *, NSString *);
|
|
||||||
|
|
||||||
UIPinchGestureRecognizer *twoFingerPinch;
|
|
||||||
|
|
||||||
CGRect frameBtnThumb;
|
|
||||||
|
|
||||||
UIImage *capturedImage;
|
|
||||||
NSData *capturedImageData;
|
|
||||||
|
|
||||||
BOOL isRotated;
|
|
||||||
|
|
||||||
CGFloat fDist;
|
|
||||||
}
|
|
||||||
|
|
||||||
@property (weak, nonatomic) IBOutlet UIView *saveBgPanel;
|
|
||||||
@property (weak, nonatomic) IBOutlet UIView *topBgPanel;
|
|
||||||
@property (weak, nonatomic) IBOutlet UIImageView *capturedImageView;
|
|
||||||
|
|
||||||
@property (weak, nonatomic) IBOutlet UIButton *btnBigDeletePicture;
|
|
||||||
@property (weak, nonatomic) IBOutlet UIButton *btnDeletePicture;
|
|
||||||
@property (weak, nonatomic) IBOutlet UIButton *btnSaveImage;
|
|
||||||
@property (weak, nonatomic) IBOutlet UIButton *btnBigSaveImage;
|
|
||||||
@property (weak, nonatomic) IBOutlet UISlider *opacitySlider;
|
|
||||||
|
|
||||||
@property (nonatomic, retain) CameraParameter *params;
|
|
||||||
|
|
||||||
- (id)initWithParams:(CameraParameter *)parameter WithCallback:(void (^)(UIImage *, NSString *, NSString *))callback;
|
|
||||||
|
|
||||||
@end
|
|
@ -1,811 +0,0 @@
|
|||||||
#import "AVCamViewController.h"
|
|
||||||
|
|
||||||
#import <AVFoundation/AVFoundation.h>
|
|
||||||
#import <AssetsLibrary/AssetsLibrary.h>
|
|
||||||
|
|
||||||
#import "AVCamPreviewView.h"
|
|
||||||
|
|
||||||
static void *CapturingStillImageContext = &CapturingStillImageContext;
|
|
||||||
static void *RecordingContext = &RecordingContext;
|
|
||||||
static void *SessionRunningAndDeviceAuthorizedContext = &SessionRunningAndDeviceAuthorizedContext;
|
|
||||||
|
|
||||||
@interface AVCamViewController () <AVCaptureFileOutputRecordingDelegate>
|
|
||||||
|
|
||||||
// For use in the storyboards.
|
|
||||||
@property (nonatomic, weak) IBOutlet AVCamPreviewView *previewView;
|
|
||||||
@property (nonatomic, weak) IBOutlet UIButton *recordButton;
|
|
||||||
@property (nonatomic, weak) IBOutlet UIButton *cameraButton;
|
|
||||||
@property (nonatomic, weak) IBOutlet UIButton *stillButton;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@property (weak, nonatomic) IBOutlet UIButton *btnThumb;
|
|
||||||
@property (weak, nonatomic) IBOutlet UIButton *btnFlash;
|
|
||||||
@property (weak, nonatomic) IBOutlet UIButton *btnBack;
|
|
||||||
|
|
||||||
|
|
||||||
@property (nonatomic, weak) IBOutlet UIImageView *imgSmallThumbNail;
|
|
||||||
@property (nonatomic, weak) IBOutlet UIImageView *imgBigThumbNail;
|
|
||||||
|
|
||||||
|
|
||||||
- (IBAction)onTapThumb:(id)sender;
|
|
||||||
- (IBAction)onTapCameraFlash:(id)sender;
|
|
||||||
- (IBAction)onBack:(id)sender;
|
|
||||||
|
|
||||||
- (IBAction)toggleMovieRecording:(id)sender;
|
|
||||||
- (IBAction)changeCamera:(id)sender;
|
|
||||||
- (IBAction)snapStillImage:(id)sender;
|
|
||||||
- (IBAction)focusAndExposeTap:(UIGestureRecognizer *)gestureRecognizer;
|
|
||||||
|
|
||||||
// Session management.
|
|
||||||
@property (nonatomic) dispatch_queue_t sessionQueue; // Communicate with the session and other session objects on this queue.
|
|
||||||
@property (nonatomic) AVCaptureSession *session;
|
|
||||||
@property (nonatomic) AVCaptureDeviceInput *videoDeviceInput;
|
|
||||||
@property (nonatomic) AVCaptureMovieFileOutput *movieFileOutput;
|
|
||||||
@property (nonatomic) AVCaptureStillImageOutput *stillImageOutput;
|
|
||||||
|
|
||||||
// Utilities.
|
|
||||||
@property (nonatomic) UIBackgroundTaskIdentifier backgroundRecordingID;
|
|
||||||
@property (nonatomic, getter = isDeviceAuthorized) BOOL deviceAuthorized;
|
|
||||||
@property (nonatomic, readonly, getter = isSessionRunningAndDeviceAuthorized) BOOL sessionRunningAndDeviceAuthorized;
|
|
||||||
@property (nonatomic) BOOL lockInterfaceRotation;
|
|
||||||
@property (nonatomic) id runtimeErrorHandlingObserver;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation AVCamViewController
|
|
||||||
@synthesize params;
|
|
||||||
|
|
||||||
- (BOOL)isSessionRunningAndDeviceAuthorized {
|
|
||||||
return [[self session] isRunning] && [self isDeviceAuthorized];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (NSSet *)keyPathsForValuesAffectingSessionRunningAndDeviceAuthorized {
|
|
||||||
return [NSSet setWithObjects:@"session.running", @"deviceAuthorized", nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithParams:(CameraParameter *)parameter WithCallback:(void (^)(UIImage *, NSString *, NSString *))callback {
|
|
||||||
self = [super initWithNibName:nil bundle:nil];
|
|
||||||
self.params = parameter;
|
|
||||||
|
|
||||||
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
|
|
||||||
self = [super initWithNibName:@"AVCamViewController_iPad" bundle:nil];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self = [super initWithNibName:@"AVCamViewController_iPhone" bundle:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (self) {
|
|
||||||
_callback = callback;
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)viewDidLoad {
|
|
||||||
[super viewDidLoad];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Create the AVCaptureSession
|
|
||||||
AVCaptureSession *session = [[AVCaptureSession alloc] init];
|
|
||||||
[self setSession:session];
|
|
||||||
|
|
||||||
// Setup the preview view
|
|
||||||
[[self previewView] setSession:session];
|
|
||||||
|
|
||||||
// Check for device authorization
|
|
||||||
[self checkDeviceAuthorizationStatus];
|
|
||||||
|
|
||||||
// In general it is not safe to mutate an AVCaptureSession or any of its inputs, outputs, or connections from multiple threads at the same time.
|
|
||||||
// Why not do all of this on the main queue?
|
|
||||||
// -[AVCaptureSession startRunning] is a blocking call which can take a long time. We dispatch session setup to the sessionQueue so that the main queue isn't blocked (which keeps the UI responsive).
|
|
||||||
|
|
||||||
dispatch_queue_t sessionQueue = dispatch_queue_create("session queue", DISPATCH_QUEUE_SERIAL);
|
|
||||||
[self setSessionQueue:sessionQueue];
|
|
||||||
|
|
||||||
dispatch_async(sessionQueue, ^{
|
|
||||||
[self setBackgroundRecordingID:UIBackgroundTaskInvalid];
|
|
||||||
|
|
||||||
NSError *error = nil;
|
|
||||||
|
|
||||||
AVCaptureDevice *videoDevice;
|
|
||||||
if (params.nDefaultCamera == 0) {
|
|
||||||
videoDevice = [AVCamViewController deviceWithMediaType:AVMediaTypeVideo preferringPosition:AVCaptureDevicePositionBack];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
videoDevice = [AVCamViewController deviceWithMediaType:AVMediaTypeVideo preferringPosition:AVCaptureDevicePositionFront];
|
|
||||||
}
|
|
||||||
AVCaptureDeviceInput *videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
|
|
||||||
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
|
||||||
if (![videoDevice hasTorch]) {
|
|
||||||
self.btnFlash.hidden = YES;
|
|
||||||
// self.cameraButton.center = self.btnThumb.center;
|
|
||||||
// self.btnThumb.center = self.btnFlash.center;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
NSLog(@"%@", error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([session canAddInput:videoDeviceInput]) {
|
|
||||||
[session addInput:videoDeviceInput];
|
|
||||||
[self setVideoDeviceInput:videoDeviceInput];
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
|
||||||
// Why are we dispatching this to the main queue?
|
|
||||||
// Because AVCaptureVideoPreviewLayer is the backing layer for AVCamPreviewView and UIView can only be manipulated on main thread.
|
|
||||||
// Note: As an exception to the above rule, it is not necessary to serialize video orientation changes on the AVCaptureVideoPreviewLayer’s connection with other session manipulation.
|
|
||||||
|
|
||||||
[[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] setVideoOrientation:(AVCaptureVideoOrientation)[[UIApplication sharedApplication] statusBarOrientation]];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
AVCaptureDevice *audioDevice = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject];
|
|
||||||
AVCaptureDeviceInput *audioDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error];
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
NSLog(@"%@", error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([session canAddInput:audioDeviceInput]) {
|
|
||||||
[session addInput:audioDeviceInput];
|
|
||||||
}
|
|
||||||
|
|
||||||
AVCaptureMovieFileOutput *movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
|
|
||||||
if ([session canAddOutput:movieFileOutput]) {
|
|
||||||
[session addOutput:movieFileOutput];
|
|
||||||
AVCaptureConnection *connection = [movieFileOutput connectionWithMediaType:AVMediaTypeVideo];
|
|
||||||
if ([connection isVideoStabilizationSupported])
|
|
||||||
//connection.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeAuto;
|
|
||||||
//[connection setEnablesVideoStabilizationWhenAvailable:YES];
|
|
||||||
[self setMovieFileOutput:movieFileOutput];
|
|
||||||
}
|
|
||||||
|
|
||||||
AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
|
|
||||||
if ([session canAddOutput:stillImageOutput]) {
|
|
||||||
[stillImageOutput setOutputSettings:@{ AVVideoCodecKey : AVVideoCodecJPEG }];
|
|
||||||
[session addOutput:stillImageOutput];
|
|
||||||
[self setStillImageOutput:stillImageOutput];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
[self initialize];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)viewWillAppear:(BOOL)animated {
|
|
||||||
dispatch_async([self sessionQueue], ^{
|
|
||||||
[self addObserver:self forKeyPath:@"sessionRunningAndDeviceAuthorized" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:SessionRunningAndDeviceAuthorizedContext];
|
|
||||||
[self addObserver:self forKeyPath:@"stillImageOutput.capturingStillImage" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:CapturingStillImageContext];
|
|
||||||
[self addObserver:self forKeyPath:@"movieFileOutput.recording" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:RecordingContext];
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(subjectAreaDidChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:[[self videoDeviceInput] device]];
|
|
||||||
|
|
||||||
__weak AVCamViewController *weakSelf = self;
|
|
||||||
[self setRuntimeErrorHandlingObserver:[[NSNotificationCenter defaultCenter] addObserverForName:AVCaptureSessionRuntimeErrorNotification object:[self session] queue:nil usingBlock: ^(NSNotification *note) {
|
|
||||||
AVCamViewController *strongSelf = weakSelf;
|
|
||||||
dispatch_async([strongSelf sessionQueue], ^{
|
|
||||||
// Manually restarting the session since it must have been stopped due to an error.
|
|
||||||
[[strongSelf session] startRunning];
|
|
||||||
[[strongSelf recordButton] setTitle:NSLocalizedString(@"Record", @"Recording button record title") forState:UIControlStateNormal];
|
|
||||||
});
|
|
||||||
}]];
|
|
||||||
[[self session] startRunning];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)viewDidDisappear:(BOOL)animated {
|
|
||||||
dispatch_async([self sessionQueue], ^{
|
|
||||||
[[self session] stopRunning];
|
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:[[self videoDeviceInput] device]];
|
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:[self runtimeErrorHandlingObserver]];
|
|
||||||
|
|
||||||
[self removeObserver:self forKeyPath:@"sessionRunningAndDeviceAuthorized" context:SessionRunningAndDeviceAuthorizedContext];
|
|
||||||
[self removeObserver:self forKeyPath:@"stillImageOutput.capturingStillImage" context:CapturingStillImageContext];
|
|
||||||
[self removeObserver:self forKeyPath:@"movieFileOutput.recording" context:RecordingContext];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)prefersStatusBarHidden {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)shouldAutorotate {
|
|
||||||
// Disable autorotation of the interface when recording is in progress.
|
|
||||||
return ![self lockInterfaceRotation];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSUInteger)supportedInterfaceOrientations {
|
|
||||||
return UIInterfaceOrientationMaskAll;
|
|
||||||
// return UIInterfaceOrientationMaskPortrait;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
|
|
||||||
[[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] setVideoOrientation:(AVCaptureVideoOrientation)toInterfaceOrientation];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
|
|
||||||
if (context == CapturingStillImageContext) {
|
|
||||||
BOOL isCapturingStillImage = [change[NSKeyValueChangeNewKey] boolValue];
|
|
||||||
|
|
||||||
if (isCapturingStillImage) {
|
|
||||||
[self runStillImageCaptureAnimation];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (context == RecordingContext) {
|
|
||||||
BOOL isRecording = [change[NSKeyValueChangeNewKey] boolValue];
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
|
||||||
if (isRecording) {
|
|
||||||
[[self cameraButton] setEnabled:NO];
|
|
||||||
[[self recordButton] setTitle:NSLocalizedString(@"Stop", @"Recording button stop title") forState:UIControlStateNormal];
|
|
||||||
[[self recordButton] setEnabled:YES];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
[[self cameraButton] setEnabled:YES];
|
|
||||||
[[self recordButton] setTitle:NSLocalizedString(@"Record", @"Recording button record title") forState:UIControlStateNormal];
|
|
||||||
[[self recordButton] setEnabled:YES];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (context == SessionRunningAndDeviceAuthorizedContext) {
|
|
||||||
BOOL isRunning = [change[NSKeyValueChangeNewKey] boolValue];
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
|
||||||
if (isRunning) {
|
|
||||||
[[self cameraButton] setEnabled:YES];
|
|
||||||
[[self recordButton] setEnabled:YES];
|
|
||||||
[[self stillButton] setEnabled:YES];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
[[self cameraButton] setEnabled:NO];
|
|
||||||
[[self recordButton] setEnabled:NO];
|
|
||||||
[[self stillButton] setEnabled:NO];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark Actions
|
|
||||||
|
|
||||||
- (IBAction)toggleMovieRecording:(id)sender {
|
|
||||||
[[self recordButton] setEnabled:NO];
|
|
||||||
|
|
||||||
dispatch_async([self sessionQueue], ^{
|
|
||||||
if (![[self movieFileOutput] isRecording]) {
|
|
||||||
[self setLockInterfaceRotation:YES];
|
|
||||||
|
|
||||||
if ([[UIDevice currentDevice] isMultitaskingSupported]) {
|
|
||||||
// Setup background task. This is needed because the captureOutput:didFinishRecordingToOutputFileAtURL: callback is not received until AVCam returns to the foreground unless you request background execution time. This also ensures that there will be time to write the file to the assets library when AVCam is backgrounded. To conclude this background execution, -endBackgroundTask is called in -recorder:recordingDidFinishToOutputFileURL:error: after the recorded file has been saved.
|
|
||||||
[self setBackgroundRecordingID:[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil]];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the orientation on the movie file output video connection before starting recording.
|
|
||||||
[[[self movieFileOutput] connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:[[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] videoOrientation]];
|
|
||||||
|
|
||||||
// Turning OFF flash for video recording
|
|
||||||
[AVCamViewController setFlashMode:AVCaptureFlashModeOff forDevice:[[self videoDeviceInput] device]];
|
|
||||||
|
|
||||||
// Start recording to a temporary file.
|
|
||||||
NSString *outputFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[@"movie" stringByAppendingPathExtension:@"mov"]];
|
|
||||||
[[self movieFileOutput] startRecordingToOutputFileURL:[NSURL fileURLWithPath:outputFilePath] recordingDelegate:self];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
[[self movieFileOutput] stopRecording];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)changeCamera:(id)sender {
|
|
||||||
[[self cameraButton] setEnabled:NO];
|
|
||||||
[[self recordButton] setEnabled:NO];
|
|
||||||
[[self stillButton] setEnabled:NO];
|
|
||||||
|
|
||||||
dispatch_async([self sessionQueue], ^{
|
|
||||||
AVCaptureDevice *currentVideoDevice = [[self videoDeviceInput] device];
|
|
||||||
AVCaptureDevicePosition preferredPosition = AVCaptureDevicePositionUnspecified;
|
|
||||||
AVCaptureDevicePosition currentPosition = [currentVideoDevice position];
|
|
||||||
|
|
||||||
switch (currentPosition) {
|
|
||||||
case AVCaptureDevicePositionUnspecified:
|
|
||||||
preferredPosition = AVCaptureDevicePositionBack;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AVCaptureDevicePositionBack:
|
|
||||||
preferredPosition = AVCaptureDevicePositionFront;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AVCaptureDevicePositionFront:
|
|
||||||
preferredPosition = AVCaptureDevicePositionBack;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
AVCaptureDevice *videoDevice = [AVCamViewController deviceWithMediaType:AVMediaTypeVideo preferringPosition:preferredPosition];
|
|
||||||
AVCaptureDeviceInput *videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:nil];
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
|
||||||
[self.btnFlash setImage:[UIImage imageNamed:@"icon_flash_auto.png"] forState:UIControlStateNormal];
|
|
||||||
self.btnFlash.tag = 0;
|
|
||||||
|
|
||||||
if ([videoDevice hasTorch] && [videoDevice hasFlash]) {
|
|
||||||
[videoDevice lockForConfiguration:nil];
|
|
||||||
[videoDevice setTorchMode:NO];
|
|
||||||
[videoDevice setFlashMode:AVCaptureFlashModeOn];
|
|
||||||
[videoDevice unlockForConfiguration];
|
|
||||||
|
|
||||||
|
|
||||||
[self.btnFlash setImage:[UIImage imageNamed:@"icon_flash_auto.png"] forState:UIControlStateNormal];
|
|
||||||
self.btnFlash.tag = 0;
|
|
||||||
self.btnFlash.hidden = NO;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (![videoDevice hasTorch]) {
|
|
||||||
self.btnFlash.hidden = YES;
|
|
||||||
}
|
|
||||||
else if ([videoDevice hasTorch] && params.bSwitchFlash) {
|
|
||||||
self.btnFlash.hidden = NO;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
[[self session] beginConfiguration];
|
|
||||||
|
|
||||||
[[self session] removeInput:[self videoDeviceInput]];
|
|
||||||
if ([[self session] canAddInput:videoDeviceInput]) {
|
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:currentVideoDevice];
|
|
||||||
|
|
||||||
[AVCamViewController setFlashMode:AVCaptureFlashModeAuto forDevice:videoDevice];
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(subjectAreaDidChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:videoDevice];
|
|
||||||
|
|
||||||
[[self session] addInput:videoDeviceInput];
|
|
||||||
[self setVideoDeviceInput:videoDeviceInput];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
[[self session] addInput:[self videoDeviceInput]];
|
|
||||||
}
|
|
||||||
|
|
||||||
[[self session] commitConfiguration];
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
|
||||||
[[self cameraButton] setEnabled:YES];
|
|
||||||
[[self recordButton] setEnabled:YES];
|
|
||||||
[[self stillButton] setEnabled:YES];
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)snapStillImage:(id)sender {
|
|
||||||
dispatch_async([self sessionQueue], ^{
|
|
||||||
// Update the orientation on the still image output video connection before capturing.
|
|
||||||
[[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:[[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] videoOrientation]];
|
|
||||||
|
|
||||||
// Flash set to Auto for Still Capture
|
|
||||||
[AVCamViewController setFlashMode:AVCaptureFlashModeAuto forDevice:[[self videoDeviceInput] device]];
|
|
||||||
|
|
||||||
// Capture a still image.
|
|
||||||
[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] completionHandler: ^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
|
|
||||||
if (imageDataSampleBuffer) {
|
|
||||||
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
|
|
||||||
capturedImage = [[UIImage alloc] initWithData:imageData];
|
|
||||||
capturedImageData = imageData;
|
|
||||||
|
|
||||||
[self takePicture];
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)focusAndExposeTap:(UIGestureRecognizer *)gestureRecognizer {
|
|
||||||
CGPoint devicePoint = [(AVCaptureVideoPreviewLayer *)[[self previewView] layer] captureDevicePointOfInterestForPoint:[gestureRecognizer locationInView:[gestureRecognizer view]]];
|
|
||||||
[self focusWithMode:AVCaptureFocusModeAutoFocus exposeWithMode:AVCaptureExposureModeAutoExpose atDevicePoint:devicePoint monitorSubjectAreaChange:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)subjectAreaDidChange:(NSNotification *)notification {
|
|
||||||
CGPoint devicePoint = CGPointMake(.5, .5);
|
|
||||||
[self focusWithMode:AVCaptureFocusModeContinuousAutoFocus exposeWithMode:AVCaptureExposureModeContinuousAutoExposure atDevicePoint:devicePoint monitorSubjectAreaChange:NO];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark File Output Delegate
|
|
||||||
|
|
||||||
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error {
|
|
||||||
if (error)
|
|
||||||
NSLog(@"%@", error);
|
|
||||||
|
|
||||||
[self setLockInterfaceRotation:NO];
|
|
||||||
|
|
||||||
// Note the backgroundRecordingID for use in the ALAssetsLibrary completion handler to end the background task associated with this recording. This allows a new recording to be started, associated with a new UIBackgroundTaskIdentifier, once the movie file output's -isRecording is back to NO — which happens sometime after this method returns.
|
|
||||||
UIBackgroundTaskIdentifier backgroundRecordingID = [self backgroundRecordingID];
|
|
||||||
[self setBackgroundRecordingID:UIBackgroundTaskInvalid];
|
|
||||||
|
|
||||||
[[[ALAssetsLibrary alloc] init] writeVideoAtPathToSavedPhotosAlbum:outputFileURL completionBlock: ^(NSURL *assetURL, NSError *error) {
|
|
||||||
if (error)
|
|
||||||
NSLog(@"%@", error);
|
|
||||||
|
|
||||||
[[NSFileManager defaultManager] removeItemAtURL:outputFileURL error:nil];
|
|
||||||
|
|
||||||
if (backgroundRecordingID != UIBackgroundTaskInvalid)
|
|
||||||
[[UIApplication sharedApplication] endBackgroundTask:backgroundRecordingID];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark Device Configuration
|
|
||||||
|
|
||||||
- (void)focusWithMode:(AVCaptureFocusMode)focusMode exposeWithMode:(AVCaptureExposureMode)exposureMode atDevicePoint:(CGPoint)point monitorSubjectAreaChange:(BOOL)monitorSubjectAreaChange {
|
|
||||||
dispatch_async([self sessionQueue], ^{
|
|
||||||
AVCaptureDevice *device = [[self videoDeviceInput] device];
|
|
||||||
NSError *error = nil;
|
|
||||||
if ([device lockForConfiguration:&error]) {
|
|
||||||
if ([device isFocusPointOfInterestSupported] && [device isFocusModeSupported:focusMode]) {
|
|
||||||
[device setFocusMode:focusMode];
|
|
||||||
[device setFocusPointOfInterest:point];
|
|
||||||
}
|
|
||||||
if ([device isExposurePointOfInterestSupported] && [device isExposureModeSupported:exposureMode]) {
|
|
||||||
[device setExposureMode:exposureMode];
|
|
||||||
[device setExposurePointOfInterest:point];
|
|
||||||
}
|
|
||||||
[device setSubjectAreaChangeMonitoringEnabled:monitorSubjectAreaChange];
|
|
||||||
[device unlockForConfiguration];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
NSLog(@"%@", error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)setFlashMode:(AVCaptureFlashMode)flashMode forDevice:(AVCaptureDevice *)device {
|
|
||||||
if ([device hasFlash] && [device isFlashModeSupported:flashMode]) {
|
|
||||||
NSError *error = nil;
|
|
||||||
if ([device lockForConfiguration:&error]) {
|
|
||||||
[device setFlashMode:flashMode];
|
|
||||||
[device unlockForConfiguration];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
NSLog(@"%@", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (AVCaptureDevice *)deviceWithMediaType:(NSString *)mediaType preferringPosition:(AVCaptureDevicePosition)position {
|
|
||||||
NSArray *devices = [AVCaptureDevice devicesWithMediaType:mediaType];
|
|
||||||
AVCaptureDevice *captureDevice = [devices firstObject];
|
|
||||||
|
|
||||||
for (AVCaptureDevice *device in devices) {
|
|
||||||
if ([device position] == position) {
|
|
||||||
captureDevice = device;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return captureDevice;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark UI
|
|
||||||
|
|
||||||
- (void)runStillImageCaptureAnimation {
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
|
||||||
[[[self previewView] layer] setOpacity:0.0];
|
|
||||||
[UIView animateWithDuration:.25 animations: ^{
|
|
||||||
[[[self previewView] layer] setOpacity:1.0];
|
|
||||||
}];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)checkDeviceAuthorizationStatus {
|
|
||||||
NSString *mediaType = AVMediaTypeVideo;
|
|
||||||
|
|
||||||
[AVCaptureDevice requestAccessForMediaType:mediaType completionHandler: ^(BOOL granted) {
|
|
||||||
if (granted) {
|
|
||||||
//Granted access to mediaType
|
|
||||||
[self setDeviceAuthorized:YES];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//Not granted access to mediaType
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
|
||||||
[[[UIAlertView alloc] initWithTitle:@"AVCam!"
|
|
||||||
message:@"AVCam doesn't have permission to use Camera, please change privacy settings"
|
|
||||||
delegate:self
|
|
||||||
cancelButtonTitle:@"OK"
|
|
||||||
otherButtonTitles:nil] show];
|
|
||||||
[self setDeviceAuthorized:NO];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)onTapThumb:(id)sender {
|
|
||||||
UIButton *btnThumb = (UIButton *)sender;
|
|
||||||
self.imgSmallThumbNail.hidden = btnThumb.selected;
|
|
||||||
self.imgBigThumbNail.hidden = !btnThumb.selected;
|
|
||||||
btnThumb.selected = !btnThumb.selected;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)onTapCameraFlash:(id)sender {
|
|
||||||
UIButton *btnCameraFlash = (UIButton *)sender;
|
|
||||||
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
|
|
||||||
if (btnCameraFlash.tag == 0) {
|
|
||||||
[btnCameraFlash setImage:[UIImage imageNamed:@"icon_flash.png"] forState:UIControlStateNormal];
|
|
||||||
btnCameraFlash.tag = 1;
|
|
||||||
if ([device hasTorch] && [device hasFlash]) {
|
|
||||||
[device lockForConfiguration:nil];
|
|
||||||
[device setTorchMode:!device.torchActive];
|
|
||||||
[device setFlashMode:AVCaptureFlashModeOn];
|
|
||||||
[device unlockForConfiguration];
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (btnCameraFlash.tag == 1) {
|
|
||||||
[btnCameraFlash setImage:[UIImage imageNamed:@"icon_flash_auto.png"] forState:UIControlStateNormal];
|
|
||||||
btnCameraFlash.tag = 0;
|
|
||||||
|
|
||||||
if ([device hasTorch] && [device hasFlash]) {
|
|
||||||
[device lockForConfiguration:nil];
|
|
||||||
[device setTorchMode:!device.torchActive];
|
|
||||||
[device setFlashMode:AVCaptureFlashModeOff];
|
|
||||||
[device unlockForConfiguration];
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)onBack:(id)sender {
|
|
||||||
_callback(nil, @"3", @"Camera closed before takin a picture.");
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)addPinchGesture {
|
|
||||||
twoFingerPinch = [[UIPinchGestureRecognizer alloc]
|
|
||||||
initWithTarget:self
|
|
||||||
action:@selector(twoFingerPinch:)];
|
|
||||||
[self.view addGestureRecognizer:twoFingerPinch];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)addOpacitySlider {
|
|
||||||
CGAffineTransform trans = CGAffineTransformMakeRotation(M_PI_2 * (-1));
|
|
||||||
self.opacitySlider.transform = trans;
|
|
||||||
[self.opacitySlider addTarget:self action:@selector(onChangeOpacitySlider) forControlEvents:UIControlEventValueChanged];
|
|
||||||
|
|
||||||
self.opacitySlider.value = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)initialize {
|
|
||||||
fDist = self.btnThumb.center.x - self.cameraButton.center.x;
|
|
||||||
|
|
||||||
capturedImage = [[UIImage alloc] init];
|
|
||||||
capturedImageData = [[NSData alloc] init];
|
|
||||||
[self addOpacitySlider];
|
|
||||||
[self addPinchGesture];
|
|
||||||
|
|
||||||
self.capturedImageView.hidden = YES;
|
|
||||||
self.saveBgPanel.hidden = YES;
|
|
||||||
self.btnBigDeletePicture.hidden = self.btnDeletePicture.hidden = YES;
|
|
||||||
self.btnBigSaveImage.hidden = self.btnSaveImage.hidden = YES;
|
|
||||||
|
|
||||||
CGRect screenBounds = [[UIScreen mainScreen] bounds];
|
|
||||||
CGFloat screenScale = [[UIScreen mainScreen] scale];
|
|
||||||
CGSize screenSize = CGSizeMake(screenBounds.size.width * screenScale, screenBounds.size.height * screenScale);
|
|
||||||
NSInteger max = (screenSize.width > screenSize.height) ? screenSize.width : screenSize.height;
|
|
||||||
UIImage *newImage = [self imageWithImage:[UIImage imageWithData:self.params.bgImageData] scaledToMaxWidth:max maxHeight:max];
|
|
||||||
self.imgBigThumbNail.image = newImage;
|
|
||||||
self.imgSmallThumbNail.image = [UIImage imageWithData:self.params.bgImageData];
|
|
||||||
|
|
||||||
self.btnThumb.hidden = !params.bMiniature;
|
|
||||||
self.btnFlash.hidden = !params.bSwitchFlash;
|
|
||||||
self.cameraButton.hidden = !params.bSwitchCamera;
|
|
||||||
self.opacitySlider.hidden = !params.bOpacity;
|
|
||||||
|
|
||||||
if (!params.bgImageData) {
|
|
||||||
self.imgBigThumbNail.hidden = YES;
|
|
||||||
self.imgSmallThumbNail.hidden = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
|
|
||||||
if (params.nDefaultFlash == 1) {
|
|
||||||
[self.btnFlash setImage:[UIImage imageNamed:@"icon_flash.png"] forState:UIControlStateNormal];
|
|
||||||
self.btnFlash.tag = 1;
|
|
||||||
|
|
||||||
if ([device hasTorch] && [device hasFlash]) {
|
|
||||||
[device lockForConfiguration:nil];
|
|
||||||
[device setTorchMode:YES];
|
|
||||||
[device setFlashMode:AVCaptureFlashModeOn];
|
|
||||||
[device unlockForConfiguration];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
[self.btnFlash setImage:[UIImage imageNamed:@"icon_flash_auto.png"] forState:UIControlStateNormal];
|
|
||||||
self.btnFlash.tag = 0;
|
|
||||||
|
|
||||||
if ([device hasTorch] && [device hasFlash]) {
|
|
||||||
[device lockForConfiguration:nil];
|
|
||||||
[device setTorchMode:NO];
|
|
||||||
[device setFlashMode:AVCaptureFlashModeOn];
|
|
||||||
[device unlockForConfiguration];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
|
|
||||||
if (params.bgImageData1) {
|
|
||||||
isRotated = !isRotated;
|
|
||||||
CGRect screenBounds = [[UIScreen mainScreen] bounds];
|
|
||||||
CGFloat screenScale = [[UIScreen mainScreen] scale];
|
|
||||||
CGSize screenSize = CGSizeMake(screenBounds.size.width * screenScale, screenBounds.size.height * screenScale);
|
|
||||||
NSInteger max = (screenSize.width > screenSize.height) ? screenSize.width : screenSize.height;
|
|
||||||
|
|
||||||
if (isRotated) {
|
|
||||||
UIImage *newImage = [self imageWithImage:[UIImage imageWithData:self.params.bgImageData1] scaledToMaxWidth:max maxHeight:max];
|
|
||||||
self.imgBigThumbNail.image = newImage;
|
|
||||||
self.imgSmallThumbNail.image = [UIImage imageWithData:params.bgImageData1];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
UIImage *newImage = [self imageWithImage:[UIImage imageWithData:self.params.bgImageData] scaledToMaxWidth:max maxHeight:max];
|
|
||||||
self.imgBigThumbNail.image = newImage;
|
|
||||||
self.imgSmallThumbNail.image = [UIImage imageWithData:params.bgImageData];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)takePicture {
|
|
||||||
[self setLockInterfaceRotation:YES];
|
|
||||||
|
|
||||||
self.capturedImageView.image = capturedImage;
|
|
||||||
self.capturedImageView.hidden = NO;
|
|
||||||
self.saveBgPanel.hidden = NO;
|
|
||||||
self.btnBigDeletePicture.hidden = self.btnDeletePicture.hidden = NO;
|
|
||||||
self.btnBigSaveImage.hidden = self.btnSaveImage.hidden = NO;
|
|
||||||
|
|
||||||
self.stillButton.hidden = self.btnFlash.hidden = self.cameraButton.hidden = YES;
|
|
||||||
frameBtnThumb = self.btnThumb.frame;
|
|
||||||
self.btnThumb.frame = self.btnFlash.frame;
|
|
||||||
|
|
||||||
self.imgSmallThumbNail.frame = CGRectOffset(self.imgSmallThumbNail.frame, 0, -self.saveBgPanel.frame.size.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)onDeletePicture:(id)sender {
|
|
||||||
[self setLockInterfaceRotation:NO];
|
|
||||||
capturedImage = nil;
|
|
||||||
self.capturedImageView.image = nil;
|
|
||||||
self.capturedImageView.hidden = YES;
|
|
||||||
self.btnBigDeletePicture.hidden = self.btnDeletePicture.hidden = YES;
|
|
||||||
self.btnBigSaveImage.hidden = self.btnSaveImage.hidden = YES;
|
|
||||||
self.saveBgPanel.hidden = YES;
|
|
||||||
|
|
||||||
|
|
||||||
self.btnThumb.frame = frameBtnThumb;
|
|
||||||
self.stillButton.hidden = self.btnFlash.hidden = NO;
|
|
||||||
|
|
||||||
//control camera button
|
|
||||||
self.cameraButton.hidden = !params.bSwitchCamera;
|
|
||||||
[self.cameraButton setEnabled:params.bSwitchCamera];
|
|
||||||
|
|
||||||
|
|
||||||
//control flash button
|
|
||||||
if (params.bSwitchFlash) {
|
|
||||||
AVCaptureDevice *currentVideoDevice = [[self videoDeviceInput] device];
|
|
||||||
AVCaptureDevicePosition currentPosition = [currentVideoDevice position];
|
|
||||||
AVCaptureDevice *videoDevice = [AVCamViewController deviceWithMediaType:AVMediaTypeVideo preferringPosition:currentPosition];
|
|
||||||
|
|
||||||
switch (currentPosition) {
|
|
||||||
case AVCaptureDevicePositionUnspecified:
|
|
||||||
case AVCaptureDevicePositionBack:
|
|
||||||
{
|
|
||||||
if (self.btnFlash.tag == 0) {
|
|
||||||
[self.btnFlash setImage:[UIImage imageNamed:@"icon_flash_auto.png"] forState:UIControlStateNormal];
|
|
||||||
|
|
||||||
if ([videoDevice hasTorch] && [videoDevice hasFlash]) {
|
|
||||||
[videoDevice lockForConfiguration:nil];
|
|
||||||
[videoDevice setTorchMode:videoDevice.torchActive];
|
|
||||||
[videoDevice setFlashMode:AVCaptureFlashModeOff];
|
|
||||||
[videoDevice unlockForConfiguration];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (self.btnFlash.tag == 1) {
|
|
||||||
[self.btnFlash setImage:[UIImage imageNamed:@"icon_flash.png"] forState:UIControlStateNormal];
|
|
||||||
if ([videoDevice hasTorch] && [videoDevice hasFlash]) {
|
|
||||||
[videoDevice lockForConfiguration:nil];
|
|
||||||
[videoDevice setTorchMode:videoDevice.torchActive];
|
|
||||||
[videoDevice setFlashMode:AVCaptureFlashModeOn];
|
|
||||||
[videoDevice unlockForConfiguration];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case AVCaptureDevicePositionFront:
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (![videoDevice hasTorch] || ![videoDevice hasFlash]) {
|
|
||||||
self.btnFlash.hidden = YES;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.btnFlash.hidden = !params.bSwitchFlash;
|
|
||||||
[self.btnFlash setEnabled:params.bSwitchFlash];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.btnFlash.hidden = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.imgSmallThumbNail.frame = CGRectOffset(self.imgSmallThumbNail.frame, 0, self.saveBgPanel.frame.size.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)onSaveImage:(id)sender {
|
|
||||||
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
|
|
||||||
activityIndicator.center = self.view.center;
|
|
||||||
[self.view addSubview:activityIndicator];
|
|
||||||
[activityIndicator startAnimating];
|
|
||||||
|
|
||||||
if (params.bSaveInGallery) {
|
|
||||||
[[[ALAssetsLibrary alloc] init] writeImageToSavedPhotosAlbum:[capturedImage CGImage] orientation:(ALAssetOrientation)[capturedImage imageOrientation] completionBlock:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[self.view setUserInteractionEnabled:NO];
|
|
||||||
_callback([UIImage imageWithData:capturedImageData], nil, nil);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)onChangeOpacitySlider {
|
|
||||||
self.imgSmallThumbNail.alpha = self.opacitySlider.value;
|
|
||||||
self.imgBigThumbNail.alpha = self.opacitySlider.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)twoFingerPinch:(UIPinchGestureRecognizer *)recognizer {
|
|
||||||
if (self.lockInterfaceRotation) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
|
|
||||||
CGFloat fMaxZoomFactor = device.activeFormat.videoMaxZoomFactor;
|
|
||||||
if (fMaxZoomFactor > 5)
|
|
||||||
fMaxZoomFactor = 5;
|
|
||||||
|
|
||||||
CGFloat fNewScale = recognizer.scale * device.videoZoomFactor;
|
|
||||||
if (fNewScale > 1.0f && fNewScale < fMaxZoomFactor) {
|
|
||||||
[device lockForConfiguration:nil];
|
|
||||||
[device rampToVideoZoomFactor:fNewScale withRate:3];
|
|
||||||
[device unlockForConfiguration];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
|
|
||||||
return UIInterfaceOrientationPortrait;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
|
|
||||||
return orientation == UIDeviceOrientationPortrait;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark -Scale image
|
|
||||||
|
|
||||||
- (UIImage *)imageWithImage:(UIImage *)image scaledToMaxWidth:(CGFloat)width maxHeight:(CGFloat)height {
|
|
||||||
CGFloat oldWidth = image.size.width;
|
|
||||||
CGFloat oldHeight = image.size.height;
|
|
||||||
|
|
||||||
CGFloat scaleFactor = (oldWidth > oldHeight) ? width / oldWidth : height / oldHeight;
|
|
||||||
|
|
||||||
CGFloat newHeight = oldHeight * scaleFactor;
|
|
||||||
CGFloat newWidth = oldWidth * scaleFactor;
|
|
||||||
CGSize newSize = CGSizeMake(newWidth, newHeight);
|
|
||||||
|
|
||||||
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
|
|
||||||
UIGraphicsBeginImageContextWithOptions(newSize, NO, [[UIScreen mainScreen] scale]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
UIGraphicsBeginImageContext(newSize);
|
|
||||||
}
|
|
||||||
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
|
|
||||||
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
||||||
UIGraphicsEndImageContext();
|
|
||||||
|
|
||||||
return newImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
@ -1,181 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="6254" systemVersion="14A389" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none">
|
|
||||||
<dependencies>
|
|
||||||
<deployment identifier="iOS"/>
|
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
|
|
||||||
</dependencies>
|
|
||||||
<objects>
|
|
||||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="AVCamViewController">
|
|
||||||
<connections>
|
|
||||||
<outlet property="btnBigDeletePicture" destination="IqJ-oc-995" id="T1H-10-ESB"/>
|
|
||||||
<outlet property="btnBigSaveImage" destination="EFe-fE-P8a" id="P0Z-Xm-thh"/>
|
|
||||||
<outlet property="btnDeletePicture" destination="S1N-v6-cZw" id="1TW-yQ-2Ul"/>
|
|
||||||
<outlet property="btnFlash" destination="KMs-9J-eHV" id="pdI-VZ-buj"/>
|
|
||||||
<outlet property="btnSaveImage" destination="JJc-KF-LjK" id="att-go-Xq7"/>
|
|
||||||
<outlet property="btnThumb" destination="NW3-H0-02v" id="9az-rc-6zl"/>
|
|
||||||
<outlet property="cameraButton" destination="br3-lo-te3" id="9er-L2-Q49"/>
|
|
||||||
<outlet property="capturedImageView" destination="aNd-OH-3PR" id="FB6-Dl-sSA"/>
|
|
||||||
<outlet property="imgBigThumbNail" destination="hb3-4z-EqI" id="bXK-S1-JY5"/>
|
|
||||||
<outlet property="imgSmallThumbNail" destination="7Tf-kP-S1C" id="yk1-9p-mnP"/>
|
|
||||||
<outlet property="opacitySlider" destination="D3e-gE-Un5" id="Vl5-37-0Gj"/>
|
|
||||||
<outlet property="previewView" destination="vHe-RW-WQc" id="WqV-SM-Xgc"/>
|
|
||||||
<outlet property="saveBgPanel" destination="xaA-dP-8ce" id="FGL-y1-FJb"/>
|
|
||||||
<outlet property="stillButton" destination="cxS-Qn-d9p" id="Joi-8C-0gM"/>
|
|
||||||
<outlet property="topBgPanel" destination="kso-6k-eTa" id="sZi-gu-mzH"/>
|
|
||||||
<outlet property="view" destination="iN0-l3-epB" id="88I-Oa-O0G"/>
|
|
||||||
</connections>
|
|
||||||
</placeholder>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
|
||||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="768" height="1024"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<view contentMode="scaleToFill" id="vHe-RW-WQc" customClass="AVCamPreviewView">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="768" height="1024"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" id="aNd-OH-3PR">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="768" height="1024"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
</imageView>
|
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sample.png" id="hb3-4z-EqI">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="768" height="1024"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
</imageView>
|
|
||||||
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="cxS-Qn-d9p">
|
|
||||||
<rect key="frame" x="344" y="941" width="80" height="76"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<state key="normal" image="icon_capture.png"/>
|
|
||||||
<state key="selected" image="icon_capture_pressed.png"/>
|
|
||||||
<state key="highlighted" image="icon_capture_pressed.png"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="snapStillImage:" destination="-1" eventType="touchUpInside" id="LsD-dw-Fw0"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sample.png" id="7Tf-kP-S1C">
|
|
||||||
<rect key="frame" x="20" y="934" width="90" height="90"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
</imageView>
|
|
||||||
<view alpha="0.5" contentMode="scaleToFill" id="xaA-dP-8ce">
|
|
||||||
<rect key="frame" x="0.0" y="934" width="768" height="90"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="IqJ-oc-995">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="376" height="90"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
|
||||||
<state key="normal">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<connections>
|
|
||||||
<action selector="onDeletePicture:" destination="-1" eventType="touchUpInside" id="XkX-0N-K4g"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="EFe-fE-P8a">
|
|
||||||
<rect key="frame" x="384" y="0.0" width="384" height="90"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<state key="normal">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<connections>
|
|
||||||
<action selector="onSaveImage:" destination="-1" eventType="touchUpInside" id="pMu-f6-poC"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="S1N-v6-cZw">
|
|
||||||
<rect key="frame" x="147" y="20" width="50" height="50"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<state key="normal" image="icon_delete.png">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<connections>
|
|
||||||
<action selector="onDeletePicture:" destination="-1" eventType="touchUpInside" id="7ty-gh-NHC"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="JJc-KF-LjK">
|
|
||||||
<rect key="frame" x="566" y="20" width="50" height="50"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
|
||||||
<state key="normal" image="icon_submit.png">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<connections>
|
|
||||||
<action selector="onSaveImage:" destination="-1" eventType="touchUpInside" id="mry-0F-fqI"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
</subviews>
|
|
||||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</view>
|
|
||||||
<view alpha="0.5" contentMode="scaleToFill" id="kso-6k-eTa">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="768" height="90"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
|
||||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</view>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="7Wz-zM-ysY">
|
|
||||||
<rect key="frame" x="20" y="20" width="50" height="50"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
|
||||||
<state key="normal" image="icon_back.png">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<connections>
|
|
||||||
<action selector="onBack:" destination="-1" eventType="touchUpInside" id="zpX-8h-Pcs"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="br3-lo-te3">
|
|
||||||
<rect key="frame" x="480" y="20" width="50" height="50"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
|
||||||
<state key="normal" image="icon_flip.png">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<connections>
|
|
||||||
<action selector="changeCamera:" destination="-1" eventType="touchUpInside" id="2JV-vM-qU3"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="NW3-H0-02v">
|
|
||||||
<rect key="frame" x="597" y="25" width="40" height="40"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
|
||||||
<state key="normal" image="icon_min.png">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<state key="selected" image="icon_max.png"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="onTapThumb:" destination="-1" eventType="touchUpInside" id="kJr-cv-LaQ"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="KMs-9J-eHV">
|
|
||||||
<rect key="frame" x="690" y="20" width="50" height="50"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
|
||||||
<state key="normal" image="icon_flash_auto.png">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<connections>
|
|
||||||
<action selector="onTapCameraFlash:" destination="-1" eventType="touchUpInside" id="hq4-uE-TO5"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" id="D3e-gE-Un5">
|
|
||||||
<rect key="frame" x="479" y="497" width="512" height="31"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
|
||||||
</slider>
|
|
||||||
</subviews>
|
|
||||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
<gestureRecognizers/>
|
|
||||||
</view>
|
|
||||||
</subviews>
|
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
|
||||||
</view>
|
|
||||||
</objects>
|
|
||||||
<resources>
|
|
||||||
<image name="icon_back.png" width="60" height="60"/>
|
|
||||||
<image name="icon_capture.png" width="128" height="128"/>
|
|
||||||
<image name="icon_capture_pressed.png" width="128" height="128"/>
|
|
||||||
<image name="icon_delete.png" width="60" height="60"/>
|
|
||||||
<image name="icon_flash_auto.png" width="60" height="60"/>
|
|
||||||
<image name="icon_flip.png" width="60" height="60"/>
|
|
||||||
<image name="icon_max.png" width="60" height="60"/>
|
|
||||||
<image name="icon_min.png" width="60" height="60"/>
|
|
||||||
<image name="icon_submit.png" width="60" height="60"/>
|
|
||||||
<image name="sample.png" width="483" height="263"/>
|
|
||||||
</resources>
|
|
||||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
|
||||||
<simulatedStatusBarMetrics key="statusBar"/>
|
|
||||||
<simulatedOrientationMetrics key="orientation"/>
|
|
||||||
<simulatedScreenMetrics key="destination"/>
|
|
||||||
</simulatedMetricsContainer>
|
|
||||||
</document>
|
|
@ -1,187 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6254" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
|
||||||
<dependencies>
|
|
||||||
<deployment identifier="iOS"/>
|
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
|
|
||||||
</dependencies>
|
|
||||||
<objects>
|
|
||||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="AVCamViewController">
|
|
||||||
<connections>
|
|
||||||
<outlet property="btnBack" destination="JSx-s3-uHS" id="gtj-U7-7eS"/>
|
|
||||||
<outlet property="btnBigDeletePicture" destination="9ml-dK-r4P" id="v1z-D4-2aN"/>
|
|
||||||
<outlet property="btnBigSaveImage" destination="P2D-hm-Kcg" id="81p-6x-fIz"/>
|
|
||||||
<outlet property="btnDeletePicture" destination="J6B-b3-9jL" id="Odf-du-kBy"/>
|
|
||||||
<outlet property="btnFlash" destination="BRk-mk-jo0" id="JMg-ha-GzP"/>
|
|
||||||
<outlet property="btnSaveImage" destination="gCj-9O-Lhz" id="Tg2-gh-nlr"/>
|
|
||||||
<outlet property="btnThumb" destination="OWo-yv-W9g" id="0S3-x9-HAa"/>
|
|
||||||
<outlet property="cameraButton" destination="jnK-sC-Roz" id="yhA-LL-bdK"/>
|
|
||||||
<outlet property="capturedImageView" destination="mfI-LM-QPE" id="aXs-aV-ggH"/>
|
|
||||||
<outlet property="imgBigThumbNail" destination="GAn-hK-ROm" id="dc7-tm-wNM"/>
|
|
||||||
<outlet property="imgSmallThumbNail" destination="MJV-kJ-EX5" id="HgP-9H-c4t"/>
|
|
||||||
<outlet property="opacitySlider" destination="gf9-Ju-OcL" id="jn8-NJ-iVO"/>
|
|
||||||
<outlet property="previewView" destination="wgh-5M-pgU" id="03T-sp-Ynl"/>
|
|
||||||
<outlet property="saveBgPanel" destination="AJN-IB-tiU" id="epU-gC-TWb"/>
|
|
||||||
<outlet property="stillButton" destination="usa-GD-lMO" id="hXu-yT-Tuj"/>
|
|
||||||
<outlet property="topBgPanel" destination="qKn-KP-yGM" id="bL1-dO-Na2"/>
|
|
||||||
<outlet property="view" destination="iN0-l3-epB" id="98Z-ee-Lmg"/>
|
|
||||||
</connections>
|
|
||||||
</placeholder>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
|
||||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<view contentMode="scaleToFill" id="wgh-5M-pgU" customClass="AVCamPreviewView">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" id="mfI-LM-QPE">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
</imageView>
|
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sample.png" id="GAn-hK-ROm">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
</imageView>
|
|
||||||
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="usa-GD-lMO">
|
|
||||||
<rect key="frame" x="135" y="463" width="50" height="50"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<state key="normal" image="icon_capture.png"/>
|
|
||||||
<state key="selected" image="icon_capture_pressed.png"/>
|
|
||||||
<state key="highlighted" image="icon_capture_pressed.png"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="snapStillImage:" destination="-1" eventType="touchUpInside" id="l6I-0I-IBm"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sample.png" id="MJV-kJ-EX5">
|
|
||||||
<rect key="frame" x="10" y="508" width="60" height="60"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
</imageView>
|
|
||||||
<view alpha="0.5" contentMode="scaleToFill" id="AJN-IB-tiU">
|
|
||||||
<rect key="frame" x="0.0" y="488" width="320" height="80"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="9ml-dK-r4P">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="160" height="60"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
|
||||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
|
||||||
<state key="normal">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<connections>
|
|
||||||
<action selector="onDeletePicture:" destination="-1" eventType="touchUpInside" id="MyT-W6-Zcm"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="P2D-hm-Kcg">
|
|
||||||
<rect key="frame" x="160" y="0.0" width="160" height="60"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
|
||||||
<state key="normal">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<connections>
|
|
||||||
<action selector="onSaveImage:" destination="-1" eventType="touchUpInside" id="HXF-We-dau"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="gCj-9O-Lhz">
|
|
||||||
<rect key="frame" x="245" y="5" width="30" height="30"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
|
||||||
<state key="normal" image="icon_submit.png">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<connections>
|
|
||||||
<action selector="onSaveImage:" destination="-1" eventType="touchUpInside" id="hLE-rb-Fpv"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="J6B-b3-9jL">
|
|
||||||
<rect key="frame" x="45" y="5" width="30" height="30"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<state key="normal" image="icon_delete.png">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<connections>
|
|
||||||
<action selector="onDeletePicture:" destination="-1" eventType="touchUpInside" id="vby-qq-Okp"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
</subviews>
|
|
||||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</view>
|
|
||||||
<view alpha="0.5" contentMode="scaleToFill" id="qKn-KP-yGM">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="60"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="OWo-yv-W9g">
|
|
||||||
<rect key="frame" x="234" y="17" width="25" height="25"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
|
||||||
<state key="normal" image="icon_min.png">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<state key="selected" image="icon_max.png"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="onTapThumb:" destination="-1" eventType="touchUpInside" id="zSf-cq-fIV"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="jnK-sC-Roz">
|
|
||||||
<rect key="frame" x="230" y="15" width="30" height="30"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
|
||||||
<state key="normal" image="icon_flip.png">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<connections>
|
|
||||||
<action selector="changeCamera:" destination="-1" eventType="touchUpInside" id="UhB-S7-CvX"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
</subviews>
|
|
||||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</view>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="JSx-s3-uHS">
|
|
||||||
<rect key="frame" x="10" y="15" width="30" height="30"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
|
||||||
<state key="normal" image="icon_back.png">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<connections>
|
|
||||||
<action selector="onBack:" destination="-1" eventType="touchUpInside" id="dpX-Bq-HAw"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="BRk-mk-jo0">
|
|
||||||
<rect key="frame" x="280" y="15" width="30" height="30"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
|
||||||
<state key="normal" image="icon_flash_auto.png">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<connections>
|
|
||||||
<action selector="onTapCameraFlash:" destination="-1" eventType="touchUpInside" id="mKZ-w5-NhW"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" id="gf9-Ju-OcL">
|
|
||||||
<rect key="frame" x="199" y="269" width="200" height="31"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
|
||||||
</slider>
|
|
||||||
</subviews>
|
|
||||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
<gestureRecognizers/>
|
|
||||||
</view>
|
|
||||||
</subviews>
|
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
|
||||||
<nil key="simulatedStatusBarMetrics"/>
|
|
||||||
</view>
|
|
||||||
</objects>
|
|
||||||
<resources>
|
|
||||||
<image name="icon_back.png" width="60" height="60"/>
|
|
||||||
<image name="icon_capture.png" width="128" height="128"/>
|
|
||||||
<image name="icon_capture_pressed.png" width="128" height="128"/>
|
|
||||||
<image name="icon_delete.png" width="60" height="60"/>
|
|
||||||
<image name="icon_flash_auto.png" width="60" height="60"/>
|
|
||||||
<image name="icon_flip.png" width="60" height="60"/>
|
|
||||||
<image name="icon_max.png" width="60" height="60"/>
|
|
||||||
<image name="icon_min.png" width="60" height="60"/>
|
|
||||||
<image name="icon_submit.png" width="60" height="60"/>
|
|
||||||
<image name="sample.png" width="483" height="263"/>
|
|
||||||
</resources>
|
|
||||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
|
||||||
<simulatedStatusBarMetrics key="statusBar"/>
|
|
||||||
<simulatedOrientationMetrics key="orientation"/>
|
|
||||||
<simulatedScreenMetrics key="destination" type="retina4"/>
|
|
||||||
</simulatedMetricsContainer>
|
|
||||||
</document>
|
|
@ -1,33 +0,0 @@
|
|||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import <Cordova/CDV.h>
|
|
||||||
|
|
||||||
@interface CameraParameter : NSObject
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@property(nonatomic, retain) NSData *bgImageData;
|
|
||||||
@property(nonatomic, retain) NSData *bgImageData1;
|
|
||||||
@property(nonatomic, assign) BOOL bMiniature;
|
|
||||||
@property(nonatomic, assign) BOOL bSaveInGallery;
|
|
||||||
@property(nonatomic, assign) int nCameraFlashMode;
|
|
||||||
|
|
||||||
|
|
||||||
@property(nonatomic, retain) NSString* strCameraBGColor;
|
|
||||||
@property(nonatomic, retain) NSString* strCameraPressedBG;
|
|
||||||
@property(nonatomic, assign) CGFloat fQuality;
|
|
||||||
@property(nonatomic, assign) BOOL bOpacity;
|
|
||||||
|
|
||||||
@property(nonatomic, assign) int nDefaultFlash;
|
|
||||||
@property(nonatomic, assign) BOOL bSwitchFlash;
|
|
||||||
|
|
||||||
|
|
||||||
@property(nonatomic, assign) int targetWidth;
|
|
||||||
@property(nonatomic, assign) int targetHeight;
|
|
||||||
|
|
||||||
@property(nonatomic, assign) int nDefaultCamera;
|
|
||||||
@property(nonatomic, assign) BOOL bSwitchCamera;
|
|
||||||
|
|
||||||
-(id) initWithCommand :(CDVInvokedUrlCommand *)command;
|
|
||||||
|
|
||||||
@end
|
|
@ -1,66 +0,0 @@
|
|||||||
#import "CameraParameter.h"
|
|
||||||
|
|
||||||
@implementation CameraParameter
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@synthesize bgImageData;
|
|
||||||
@synthesize bgImageData1;
|
|
||||||
@synthesize bMiniature;
|
|
||||||
@synthesize bSaveInGallery;
|
|
||||||
@synthesize nCameraFlashMode;
|
|
||||||
@synthesize strCameraBGColor;
|
|
||||||
@synthesize strCameraPressedBG;
|
|
||||||
@synthesize fQuality;
|
|
||||||
@synthesize targetWidth;
|
|
||||||
@synthesize targetHeight;
|
|
||||||
@synthesize bOpacity;
|
|
||||||
@synthesize nDefaultFlash;
|
|
||||||
@synthesize bSwitchFlash;
|
|
||||||
@synthesize nDefaultCamera;
|
|
||||||
@synthesize bSwitchCamera;
|
|
||||||
|
|
||||||
- (id)initWithCommand:(CDVInvokedUrlCommand *)command {
|
|
||||||
// [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
|
|
||||||
// mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
|
|
||||||
if (self = [super init]) {
|
|
||||||
|
|
||||||
// NSString *strData = [command argumentAtIndex:0];
|
|
||||||
// if (strData) {
|
|
||||||
// bgImageData = [[NSData alloc] initWithBase64EncodedString:strData options:0];
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
bgImageData = nil;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// NSString *strData1 = [command argumentAtIndex:1];
|
|
||||||
// if (strData1) {
|
|
||||||
// bgImageData1 = [[NSData alloc] initWithBase64EncodedString:strData1 options:0];
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
bgImageData1 = nil;
|
|
||||||
// }
|
|
||||||
|
|
||||||
bMiniature = false; //[[command argumentAtIndex:2] boolValue];
|
|
||||||
bSaveInGallery = [[command argumentAtIndex:9] boolValue];
|
|
||||||
strCameraBGColor = @"#e26760"; //[command argumentAtIndex:4];
|
|
||||||
strCameraPressedBG = @"#dc453d"; //[command argumentAtIndex:5];
|
|
||||||
|
|
||||||
|
|
||||||
fQuality = [[command argumentAtIndex:0] intValue];
|
|
||||||
|
|
||||||
targetWidth = [[command argumentAtIndex:3] intValue];
|
|
||||||
targetHeight = [[command argumentAtIndex:4] intValue];
|
|
||||||
|
|
||||||
|
|
||||||
bOpacity = false; //[[command argumentAtIndex:7] boolValue];
|
|
||||||
nDefaultFlash = 2; //[[command argumentAtIndex:8] intValue];
|
|
||||||
bSwitchFlash = true; //[[command argumentAtIndex:9] boolValue];
|
|
||||||
nDefaultCamera = 0; //[[command argumentAtIndex:10] intValue];
|
|
||||||
bSwitchCamera = true; //[[command argumentAtIndex:11] boolValue];
|
|
||||||
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
@ -1,93 +0,0 @@
|
|||||||
#import <Cordova/CDV.h>
|
|
||||||
#import <CoreLocation/CoreLocation.h>
|
|
||||||
#import <CoreLocation/CLLocationManager.h>
|
|
||||||
enum CDVDestinationType {
|
|
||||||
DestinationTypeDataUrl = 0,
|
|
||||||
DestinationTypeFileUri,
|
|
||||||
DestinationTypeNativeUri
|
|
||||||
};
|
|
||||||
typedef NSUInteger CDVDestinationType;
|
|
||||||
|
|
||||||
enum CDVEncodingType {
|
|
||||||
EncodingTypeJPEG = 0,
|
|
||||||
EncodingTypePNG
|
|
||||||
};
|
|
||||||
typedef NSUInteger CDVEncodingType;
|
|
||||||
|
|
||||||
enum CDVMediaType {
|
|
||||||
MediaTypePicture = 0,
|
|
||||||
MediaTypeVideo,
|
|
||||||
MediaTypeAll
|
|
||||||
};
|
|
||||||
typedef NSUInteger CDVMediaType;
|
|
||||||
|
|
||||||
@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 (copy) NSString* callbackId;
|
|
||||||
@property (copy) NSString* postUrl;
|
|
||||||
@property (strong) UIPopoverController* pickerPopoverController;
|
|
||||||
@property (assign) BOOL cropToSize;
|
|
||||||
@property (strong) UIView* webView;
|
|
||||||
|
|
||||||
+ (instancetype) createFromPictureOptions:(CDVPictureOptions*)options;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface CustomCamera : CDVPlugin<UIImagePickerControllerDelegate, UINavigationControllerDelegate>
|
|
||||||
{
|
|
||||||
CDVInvokedUrlCommand *lastCommand;
|
|
||||||
|
|
||||||
int nSourceType;
|
|
||||||
int nDestType;
|
|
||||||
|
|
||||||
NSData *bgImageData;
|
|
||||||
NSData *bgImageData1;
|
|
||||||
BOOL miniature;
|
|
||||||
BOOL saveInGallery;
|
|
||||||
int nCameraFlashMode;
|
|
||||||
|
|
||||||
NSString* clrCameraBG;
|
|
||||||
NSString* clrCameraPressedBG;
|
|
||||||
CGFloat quality;
|
|
||||||
BOOL opacity;
|
|
||||||
|
|
||||||
int defaultFlash;
|
|
||||||
BOOL switchFlash;
|
|
||||||
|
|
||||||
int defaultCamera;
|
|
||||||
BOOL switchCamera;
|
|
||||||
|
|
||||||
NSString *filename;
|
|
||||||
}
|
|
||||||
@property (strong) NSData* data;
|
|
||||||
@property (strong) NSMutableDictionary *metadata;
|
|
||||||
@property (strong, nonatomic) CLLocationManager *locationManager;
|
|
||||||
@property (strong) CDVCameraPicker* pickerController;
|
|
||||||
- (void)startCamera:(CDVInvokedUrlCommand*)command;
|
|
||||||
- (void)takePicture:(CDVInvokedUrlCommand*)command;
|
|
||||||
- (void)showCameraPicker:(NSString*)callbackId withOptions:(CDVPictureOptions *) pictureOptions;
|
|
||||||
@end
|
|
@ -1,584 +0,0 @@
|
|||||||
#import "CustomCamera.h"
|
|
||||||
#import "AVCamViewController.h"
|
|
||||||
#import "CameraParameter.h"
|
|
||||||
#import <MobileCoreServices/UTCoreTypes.h>
|
|
||||||
#import <AssetsLibrary/ALAssetRepresentation.h>
|
|
||||||
#import <AssetsLibrary/AssetsLibrary.h>
|
|
||||||
#import "UIImage+CropScaleOrientation.h"
|
|
||||||
#import <objc/message.h>
|
|
||||||
#import <AVFoundation/AVFoundation.h>
|
|
||||||
|
|
||||||
#ifndef __CORDOVA_4_0_0
|
|
||||||
#import <Cordova/NSData+Base64.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CDV_PHOTO_PREFIX @"cdv_photo_"
|
|
||||||
|
|
||||||
static NSSet* org_apache_cordova_validArrowDirections;
|
|
||||||
static NSString* toBase64(NSData* data) {
|
|
||||||
SEL s1 = NSSelectorFromString(@"cdv_base64EncodedString");
|
|
||||||
SEL s2 = NSSelectorFromString(@"base64EncodedString");
|
|
||||||
SEL s3 = NSSelectorFromString(@"base64EncodedStringWithOptions:");
|
|
||||||
|
|
||||||
if ([data respondsToSelector:s1]) {
|
|
||||||
NSString* (*func)(id, SEL) = (void *)[data methodForSelector:s1];
|
|
||||||
return func(data, s1);
|
|
||||||
} else if ([data respondsToSelector:s2]) {
|
|
||||||
NSString* (*func)(id, SEL) = (void *)[data methodForSelector:s2];
|
|
||||||
return func(data, s2);
|
|
||||||
} else if ([data respondsToSelector:s3]) {
|
|
||||||
NSString* (*func)(id, SEL, NSUInteger) = (void *)[data methodForSelector:s3];
|
|
||||||
return func(data, s3, 0);
|
|
||||||
} else {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@implementation CDVPictureOptions
|
|
||||||
|
|
||||||
+ (instancetype) createFromTakePictureArguments:(CDVInvokedUrlCommand*)command
|
|
||||||
{
|
|
||||||
CDVPictureOptions* pictureOptions = [[CDVPictureOptions alloc] init];
|
|
||||||
|
|
||||||
pictureOptions.quality = [command argumentAtIndex:0 withDefault:@(100)];
|
|
||||||
pictureOptions.destinationType = [[command argumentAtIndex:1 withDefault:@(DestinationTypeFileUri)] unsignedIntegerValue];
|
|
||||||
pictureOptions.sourceType = [[command argumentAtIndex:2 withDefault:@(UIImagePickerControllerSourceTypeCamera)] unsignedIntegerValue];
|
|
||||||
|
|
||||||
NSNumber* targetWidth = [command argumentAtIndex:3 withDefault:nil];
|
|
||||||
NSNumber* targetHeight = [command argumentAtIndex:4 withDefault:nil];
|
|
||||||
pictureOptions.targetSize = CGSizeMake(0, 0);
|
|
||||||
if ((targetWidth != nil) && (targetHeight != nil)) {
|
|
||||||
pictureOptions.targetSize = CGSizeMake([targetWidth floatValue], [targetHeight floatValue]);
|
|
||||||
}
|
|
||||||
|
|
||||||
pictureOptions.encodingType = [[command argumentAtIndex:5 withDefault:@(EncodingTypeJPEG)] unsignedIntegerValue];
|
|
||||||
pictureOptions.mediaType = [[command argumentAtIndex:6 withDefault:@(MediaTypePicture)] unsignedIntegerValue];
|
|
||||||
pictureOptions.allowsEditing = [[command argumentAtIndex:7 withDefault:@(NO)] boolValue];
|
|
||||||
pictureOptions.correctOrientation = [[command argumentAtIndex:8 withDefault:@(NO)] boolValue];
|
|
||||||
pictureOptions.saveToPhotoAlbum = [[command argumentAtIndex:9 withDefault:@(NO)] boolValue];
|
|
||||||
pictureOptions.popoverOptions = [command argumentAtIndex:10 withDefault:nil];
|
|
||||||
pictureOptions.cameraDirection = [[command argumentAtIndex:11 withDefault:@(UIImagePickerControllerCameraDeviceRear)] unsignedIntegerValue];
|
|
||||||
|
|
||||||
pictureOptions.popoverSupported = NO;
|
|
||||||
pictureOptions.usesGeolocation = NO;
|
|
||||||
|
|
||||||
return pictureOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
||||||
@implementation CDVCameraPicker
|
|
||||||
|
|
||||||
- (BOOL)prefersStatusBarHidden
|
|
||||||
{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (UIViewController*)childViewControllerForStatusBarHidden
|
|
||||||
{
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)viewWillAppear:(BOOL)animated
|
|
||||||
{
|
|
||||||
SEL sel = NSSelectorFromString(@"setNeedsStatusBarAppearanceUpdate");
|
|
||||||
if ([self respondsToSelector:sel]) {
|
|
||||||
[self performSelector:sel withObject:nil afterDelay:0];
|
|
||||||
}
|
|
||||||
|
|
||||||
[super viewWillAppear:animated];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (instancetype) createFromPictureOptions:(CDVPictureOptions*)pictureOptions;
|
|
||||||
{
|
|
||||||
CDVCameraPicker* cameraPicker = [[CDVCameraPicker alloc] init];
|
|
||||||
cameraPicker.pictureOptions = pictureOptions;
|
|
||||||
cameraPicker.sourceType = pictureOptions.sourceType;
|
|
||||||
cameraPicker.allowsEditing = pictureOptions.allowsEditing;
|
|
||||||
|
|
||||||
if (cameraPicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
|
|
||||||
// We only allow taking pictures (no video) in this API.
|
|
||||||
cameraPicker.mediaTypes = @[(NSString*)kUTTypeImage];
|
|
||||||
// We can only set the camera device if we're actually using the camera.
|
|
||||||
cameraPicker.cameraDevice = pictureOptions.cameraDirection;
|
|
||||||
} else if (pictureOptions.mediaType == MediaTypeAll) {
|
|
||||||
cameraPicker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:cameraPicker.sourceType];
|
|
||||||
} else {
|
|
||||||
NSArray* mediaArray = @[(NSString*)(pictureOptions.mediaType == MediaTypeVideo ? kUTTypeMovie : kUTTypeImage)];
|
|
||||||
cameraPicker.mediaTypes = mediaArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cameraPicker;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface CustomCamera ()
|
|
||||||
@property (readwrite, assign) BOOL hasPendingOperation;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation CustomCamera
|
|
||||||
+ (void)initialize
|
|
||||||
{
|
|
||||||
org_apache_cordova_validArrowDirections = [[NSSet alloc] initWithObjects:[NSNumber numberWithInt:UIPopoverArrowDirectionUp], [NSNumber numberWithInt:UIPopoverArrowDirectionDown], [NSNumber numberWithInt:UIPopoverArrowDirectionLeft], [NSNumber numberWithInt:UIPopoverArrowDirectionRight], [NSNumber numberWithInt:UIPopoverArrowDirectionAny], nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
@synthesize hasPendingOperation, pickerController;
|
|
||||||
|
|
||||||
- (void)takePicture:(CDVInvokedUrlCommand *)command {
|
|
||||||
self.hasPendingOperation = YES;
|
|
||||||
CDVPictureOptions* pictureOptions = [CDVPictureOptions createFromTakePictureArguments:command];
|
|
||||||
if (pictureOptions.sourceType == 1) {
|
|
||||||
[self startCamera: command];
|
|
||||||
} else {
|
|
||||||
[self showCameraPicker:command.callbackId withOptions:pictureOptions];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- (BOOL)popoverSupported
|
|
||||||
{
|
|
||||||
return (NSClassFromString(@"UIPopoverController") != nil) &&
|
|
||||||
(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSInteger)integerValueForKey:(NSDictionary*)dict key:(NSString*)key defaultValue:(NSInteger)defaultValue
|
|
||||||
{
|
|
||||||
NSInteger value = defaultValue;
|
|
||||||
|
|
||||||
NSNumber* val = [dict valueForKey:key]; // value is an NSNumber
|
|
||||||
|
|
||||||
if (val != nil) {
|
|
||||||
value = [val integerValue];
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)displayPopover:(NSDictionary*)options
|
|
||||||
{
|
|
||||||
NSInteger x = 0;
|
|
||||||
NSInteger y = 32;
|
|
||||||
NSInteger width = 320;
|
|
||||||
NSInteger height = 480;
|
|
||||||
UIPopoverArrowDirection arrowDirection = UIPopoverArrowDirectionAny;
|
|
||||||
|
|
||||||
if (options) {
|
|
||||||
x = [self integerValueForKey:options key:@"x" defaultValue:0];
|
|
||||||
y = [self integerValueForKey:options key:@"y" defaultValue:32];
|
|
||||||
width = [self integerValueForKey:options key:@"width" defaultValue:320];
|
|
||||||
height = [self integerValueForKey:options key:@"height" defaultValue:480];
|
|
||||||
arrowDirection = [self integerValueForKey:options key:@"arrowDir" defaultValue:UIPopoverArrowDirectionAny];
|
|
||||||
if (![org_apache_cordova_validArrowDirections containsObject:[NSNumber numberWithUnsignedInteger:arrowDirection]]) {
|
|
||||||
arrowDirection = UIPopoverArrowDirectionAny;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[[[self pickerController] pickerPopoverController] setDelegate:self];
|
|
||||||
[[[self pickerController] pickerPopoverController] presentPopoverFromRect:CGRectMake(x, y, width, height)
|
|
||||||
inView:[self.webView superview]
|
|
||||||
permittedArrowDirections:arrowDirection
|
|
||||||
animated:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)showCameraPicker:(NSString*)callbackId withOptions:(CDVPictureOptions *) pictureOptions
|
|
||||||
{
|
|
||||||
// Perform UI operations on the main thread
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
|
||||||
CDVCameraPicker* cameraPicker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
|
||||||
self.pickerController = cameraPicker;
|
|
||||||
|
|
||||||
cameraPicker.delegate = self;
|
|
||||||
cameraPicker.callbackId = callbackId;
|
|
||||||
// we need to capture this state for memory warnings that dealloc this object
|
|
||||||
cameraPicker.webView = self.webView;
|
|
||||||
|
|
||||||
// If a popover is already open, close it; we only want one at a time.
|
|
||||||
if (([[self pickerController] pickerPopoverController] != nil) && [[[self pickerController] pickerPopoverController] isPopoverVisible]) {
|
|
||||||
[[[self pickerController] pickerPopoverController] dismissPopoverAnimated:YES];
|
|
||||||
[[[self pickerController] pickerPopoverController] setDelegate:nil];
|
|
||||||
[[self pickerController] setPickerPopoverController:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([self popoverSupported] && (pictureOptions.sourceType != UIImagePickerControllerSourceTypeCamera)) {
|
|
||||||
if (cameraPicker.pickerPopoverController == nil) {
|
|
||||||
cameraPicker.pickerPopoverController = [[NSClassFromString(@"UIPopoverController") alloc] initWithContentViewController:cameraPicker];
|
|
||||||
}
|
|
||||||
[self displayPopover:pictureOptions.popoverOptions];
|
|
||||||
self.hasPendingOperation = NO;
|
|
||||||
} else {
|
|
||||||
cameraPicker.modalPresentationStyle = UIModalPresentationCurrentContext;
|
|
||||||
[self.viewController presentViewController:cameraPicker animated:YES completion:^{
|
|
||||||
self.hasPendingOperation = NO;
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
- (UIImage*)retrieveImage:(NSDictionary*)info options:(CDVPictureOptions*)options
|
|
||||||
{
|
|
||||||
// get the image
|
|
||||||
UIImage* image = nil;
|
|
||||||
if (options.allowsEditing && [info objectForKey:UIImagePickerControllerEditedImage]) {
|
|
||||||
image = [info objectForKey:UIImagePickerControllerEditedImage];
|
|
||||||
} else {
|
|
||||||
image = [info objectForKey:UIImagePickerControllerOriginalImage];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.correctOrientation) {
|
|
||||||
image = [image imageCorrectedForCaptureOrientation];
|
|
||||||
}
|
|
||||||
|
|
||||||
UIImage* scaledImage = nil;
|
|
||||||
|
|
||||||
if ((options.targetSize.width > 0) && (options.targetSize.height > 0)) {
|
|
||||||
// if cropToSize, resize image and crop to target size, otherwise resize to fit target without cropping
|
|
||||||
if (options.cropToSize) {
|
|
||||||
scaledImage = [image imageByScalingAndCroppingForSize:options.targetSize];
|
|
||||||
} else {
|
|
||||||
scaledImage = [image imageByScalingNotCroppingForSize:options.targetSize];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (scaledImage == nil ? image : scaledImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSURL*) urlTransformer:(NSURL*)url
|
|
||||||
{
|
|
||||||
NSURL* urlToTransform = url;
|
|
||||||
|
|
||||||
// for backwards compatibility - we check if this property is there
|
|
||||||
SEL sel = NSSelectorFromString(@"urlTransformer");
|
|
||||||
if ([self.commandDelegate respondsToSelector:sel]) {
|
|
||||||
// grab the block from the commandDelegate
|
|
||||||
NSURL* (^urlTransformer)(NSURL*) = ((id(*)(id, SEL))objc_msgSend)(self.commandDelegate, sel);
|
|
||||||
// if block is not null, we call it
|
|
||||||
if (urlTransformer) {
|
|
||||||
urlToTransform = urlTransformer(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return urlToTransform;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSData*)processImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPictureOptions*)options
|
|
||||||
{
|
|
||||||
NSData* data = nil;
|
|
||||||
|
|
||||||
switch (options.encodingType) {
|
|
||||||
case EncodingTypePNG:
|
|
||||||
data = UIImagePNGRepresentation(image);
|
|
||||||
break;
|
|
||||||
case EncodingTypeJPEG:
|
|
||||||
{
|
|
||||||
if ((options.allowsEditing == NO) && (options.targetSize.width <= 0) && (options.targetSize.height <= 0) && (options.correctOrientation == NO) && (([options.quality integerValue] == 100) || (options.sourceType != UIImagePickerControllerSourceTypeCamera))){
|
|
||||||
// use image unedited as requested , don't resize
|
|
||||||
data = UIImageJPEGRepresentation(image, 1.0);
|
|
||||||
} else {
|
|
||||||
data = UIImageJPEGRepresentation(image, [options.quality floatValue] / 100.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.usesGeolocation) {
|
|
||||||
NSDictionary* controllerMetadata = [info objectForKey:@"UIImagePickerControllerMediaMetadata"];
|
|
||||||
if (controllerMetadata) {
|
|
||||||
self.data = data;
|
|
||||||
self.metadata = [[NSMutableDictionary alloc] init];
|
|
||||||
|
|
||||||
NSMutableDictionary* EXIFDictionary = [[controllerMetadata objectForKey:(NSString*)kCGImagePropertyExifDictionary]mutableCopy];
|
|
||||||
if (EXIFDictionary) {
|
|
||||||
[self.metadata setObject:EXIFDictionary forKey:(NSString*)kCGImagePropertyExifDictionary];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsAtLeastiOSVersion(@"8.0")) {
|
|
||||||
[[self locationManager] performSelector:NSSelectorFromString(@"requestWhenInUseAuthorization") withObject:nil afterDelay:0];
|
|
||||||
}
|
|
||||||
[[self locationManager] startUpdatingLocation];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString*)tempFilePath:(NSString*)extension
|
|
||||||
{
|
|
||||||
NSString* docsPath = [NSTemporaryDirectory()stringByStandardizingPath];
|
|
||||||
NSFileManager* fileMgr = [[NSFileManager alloc] init]; // recommended by Apple (vs [NSFileManager defaultManager]) to be threadsafe
|
|
||||||
NSString* filePath;
|
|
||||||
|
|
||||||
// unique file name
|
|
||||||
NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
|
|
||||||
NSNumber *timeStampObj = [NSNumber numberWithDouble: timeStamp];
|
|
||||||
do {
|
|
||||||
filePath = [NSString stringWithFormat:@"%@/%@%ld.%@", docsPath, CDV_PHOTO_PREFIX, [timeStampObj longValue], extension];
|
|
||||||
} while ([fileMgr fileExistsAtPath:filePath]);
|
|
||||||
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)resultForImage:(CDVPictureOptions*)options info:(NSDictionary*)info completion:(void (^)(CDVPluginResult* res))completion
|
|
||||||
{
|
|
||||||
CDVPluginResult* result = nil;
|
|
||||||
BOOL saveToPhotoAlbum = options.saveToPhotoAlbum;
|
|
||||||
UIImage* image = nil;
|
|
||||||
|
|
||||||
switch (options.destinationType) {
|
|
||||||
case DestinationTypeNativeUri:
|
|
||||||
{
|
|
||||||
NSURL* url = [info objectForKey:UIImagePickerControllerReferenceURL];
|
|
||||||
saveToPhotoAlbum = NO;
|
|
||||||
// If, for example, we use sourceType = Camera, URL might be nil because image is stored in memory.
|
|
||||||
// In this case we must save image to device before obtaining an URI.
|
|
||||||
if (url == nil) {
|
|
||||||
image = [self retrieveImage:info options:options];
|
|
||||||
ALAssetsLibrary* library = [ALAssetsLibrary new];
|
|
||||||
[library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:^(NSURL *assetURL, NSError *error) {
|
|
||||||
CDVPluginResult* resultToReturn = nil;
|
|
||||||
if (error) {
|
|
||||||
resultToReturn = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]];
|
|
||||||
} else {
|
|
||||||
NSString* nativeUri = [[self urlTransformer:assetURL] absoluteString];
|
|
||||||
resultToReturn = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nativeUri];
|
|
||||||
}
|
|
||||||
completion(resultToReturn);
|
|
||||||
}];
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
NSString* nativeUri = [[self urlTransformer:url] absoluteString];
|
|
||||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nativeUri];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DestinationTypeFileUri:
|
|
||||||
{
|
|
||||||
image = [self retrieveImage:info options:options];
|
|
||||||
NSData* data = [self processImage:image info:info options:options];
|
|
||||||
if (data) {
|
|
||||||
|
|
||||||
NSString* extension = options.encodingType == EncodingTypePNG? @"png" : @"jpg";
|
|
||||||
NSString* filePath = [self tempFilePath:extension];
|
|
||||||
NSError* err = nil;
|
|
||||||
|
|
||||||
// save file
|
|
||||||
if (![data writeToFile:filePath options:NSAtomicWrite error:&err]) {
|
|
||||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[err localizedDescription]];
|
|
||||||
} else {
|
|
||||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:[[self urlTransformer:[NSURL fileURLWithPath:filePath]] absoluteString]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DestinationTypeDataUrl:
|
|
||||||
{
|
|
||||||
image = [self retrieveImage:info options:options];
|
|
||||||
NSData* data = [self processImage:image info:info options:options];
|
|
||||||
if (data) {
|
|
||||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(data)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (saveToPhotoAlbum && image) {
|
|
||||||
ALAssetsLibrary* library = [ALAssetsLibrary new];
|
|
||||||
[library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
completion(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *) createTmpVideo:(NSString *) moviePath {
|
|
||||||
NSString* moviePathExtension = [moviePath pathExtension];
|
|
||||||
NSString* copyMoviePath = [self tempFilePath:moviePathExtension];
|
|
||||||
NSFileManager* fileMgr = [[NSFileManager alloc] init];
|
|
||||||
NSError *error;
|
|
||||||
[fileMgr copyItemAtPath:moviePath toPath:copyMoviePath error:&error];
|
|
||||||
return [[NSURL fileURLWithPath:copyMoviePath] absoluteString];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CDVPluginResult*)resultForVideo:(NSDictionary*)info
|
|
||||||
{
|
|
||||||
NSString* moviePath = [[info objectForKey:UIImagePickerControllerMediaURL] absoluteString];
|
|
||||||
// On iOS 13 the movie path becomes inaccessible, create and return a copy
|
|
||||||
if (IsAtLeastiOSVersion(@"13.0")) {
|
|
||||||
moviePath = [self createTmpVideo:[[info objectForKey:UIImagePickerControllerMediaURL] path]];
|
|
||||||
}
|
|
||||||
return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:moviePath];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)usesGeolocation
|
|
||||||
{
|
|
||||||
id useGeo = [self.commandDelegate.settings objectForKey:[@"CameraUsesGeolocation" lowercaseString]];
|
|
||||||
return [(NSNumber*)useGeo boolValue];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
|
|
||||||
{
|
|
||||||
__weak CDVCameraPicker* cameraPicker = (CDVCameraPicker*)picker;
|
|
||||||
__weak CustomCamera* weakSelf = self;
|
|
||||||
|
|
||||||
dispatch_block_t invoke = ^(void) {
|
|
||||||
__block CDVPluginResult* result = nil;
|
|
||||||
|
|
||||||
NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
|
|
||||||
if ([mediaType isEqualToString:(NSString*)kUTTypeImage]) {
|
|
||||||
[weakSelf resultForImage:cameraPicker.pictureOptions info:info completion:^(CDVPluginResult* res) {
|
|
||||||
if (![self usesGeolocation] || picker.sourceType != UIImagePickerControllerSourceTypeCamera) {
|
|
||||||
[weakSelf.commandDelegate sendPluginResult:res callbackId:cameraPicker.callbackId];
|
|
||||||
weakSelf.hasPendingOperation = NO;
|
|
||||||
weakSelf.pickerController = nil;
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = [weakSelf resultForVideo:info];
|
|
||||||
[weakSelf.commandDelegate sendPluginResult:result callbackId:cameraPicker.callbackId];
|
|
||||||
weakSelf.hasPendingOperation = NO;
|
|
||||||
weakSelf.pickerController = nil;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (cameraPicker.pictureOptions.popoverSupported && (cameraPicker.pickerPopoverController != nil)) {
|
|
||||||
[cameraPicker.pickerPopoverController dismissPopoverAnimated:YES];
|
|
||||||
cameraPicker.pickerPopoverController.delegate = nil;
|
|
||||||
cameraPicker.pickerPopoverController = nil;
|
|
||||||
invoke();
|
|
||||||
} else {
|
|
||||||
[[cameraPicker presentingViewController] dismissViewControllerAnimated:YES completion:invoke];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// older api calls newer didFinishPickingMediaWithInfo
|
|
||||||
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingImage:(UIImage*)image editingInfo:(NSDictionary*)editingInfo
|
|
||||||
{
|
|
||||||
NSDictionary* imageInfo = [NSDictionary dictionaryWithObject:image forKey:UIImagePickerControllerOriginalImage];
|
|
||||||
|
|
||||||
[self imagePickerController:picker didFinishPickingMediaWithInfo:imageInfo];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker
|
|
||||||
{
|
|
||||||
__weak CDVCameraPicker* cameraPicker = (CDVCameraPicker*)picker;
|
|
||||||
__weak CustomCamera* weakSelf = self;
|
|
||||||
|
|
||||||
dispatch_block_t invoke = ^ (void) {
|
|
||||||
CDVPluginResult* result;
|
|
||||||
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera && [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo] != ALAuthorizationStatusAuthorized) {
|
|
||||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"has no access to camera"];
|
|
||||||
} else if (picker.sourceType != UIImagePickerControllerSourceTypeCamera && ! IsAtLeastiOSVersion(@"11.0") && [ALAssetsLibrary authorizationStatus] != ALAuthorizationStatusAuthorized) {
|
|
||||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"has no access to assets"];
|
|
||||||
} else {
|
|
||||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No Image Selected"];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[weakSelf.commandDelegate sendPluginResult:result callbackId:cameraPicker.callbackId];
|
|
||||||
|
|
||||||
weakSelf.hasPendingOperation = NO;
|
|
||||||
weakSelf.pickerController = nil;
|
|
||||||
};
|
|
||||||
|
|
||||||
[[cameraPicker presentingViewController] dismissViewControllerAnimated:YES completion:invoke];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)startCamera:(CDVInvokedUrlCommand *)command {
|
|
||||||
lastCommand = command;
|
|
||||||
|
|
||||||
NSString *guid = [[NSUUID new] UUIDString];
|
|
||||||
NSString *uniqueFileName = [NSString stringWithFormat:@"%@.jpg", guid];
|
|
||||||
|
|
||||||
filename = uniqueFileName;
|
|
||||||
nSourceType = 1;
|
|
||||||
nDestType = 0;
|
|
||||||
|
|
||||||
CameraParameter *param = [[CameraParameter alloc] initWithCommand:lastCommand];
|
|
||||||
if (nSourceType == 0) {
|
|
||||||
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
|
|
||||||
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
|
|
||||||
imagePickerController.delegate = self;
|
|
||||||
[self.viewController presentViewController:imagePickerController animated:YES completion:nil];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (![UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear]) {
|
|
||||||
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No rear camera detected"];
|
|
||||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
|
||||||
}
|
|
||||||
else if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
|
|
||||||
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Camera is not accessible"];
|
|
||||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
AVCamViewController *cameraViewController = [[AVCamViewController alloc] initWithParams:param WithCallback: ^(UIImage *image, NSString *errorCode, NSString *message) {
|
|
||||||
@autoreleasepool {
|
|
||||||
if (image) {
|
|
||||||
if (nDestType == 0) {
|
|
||||||
CDVPictureOptions* options = [CDVPictureOptions createFromTakePictureArguments:command];
|
|
||||||
UIImage* scaledImage = nil;
|
|
||||||
|
|
||||||
if ((options.targetSize.width > 0) && (options.targetSize.height > 0)) {
|
|
||||||
// if cropToSize, resize image and crop to target size, otherwise resize to fit target without cropping
|
|
||||||
if (options.cropToSize) {
|
|
||||||
scaledImage = [image imageByScalingAndCroppingForSize:options.targetSize];
|
|
||||||
} else {
|
|
||||||
scaledImage = [image imageByScalingNotCroppingForSize:options.targetSize];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
image= (scaledImage == nil ? image : scaledImage);
|
|
||||||
NSData *imageData = UIImageJPEGRepresentation(image, quality / 100);
|
|
||||||
|
|
||||||
NSString *strEncodeData = [imageData base64EncodedStringWithOptions:0];
|
|
||||||
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
|
|
||||||
messageAsString:strEncodeData];
|
|
||||||
[self.viewController dismissViewControllerAnimated:YES completion:nil];
|
|
||||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
|
|
||||||
NSString *imagePath = [documentsDirectory stringByAppendingPathComponent:filename];
|
|
||||||
NSData *imageData = UIImageJPEGRepresentation(image, quality / 100);
|
|
||||||
[imageData writeToFile:imagePath atomically:YES];
|
|
||||||
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
|
|
||||||
messageAsString:[[NSURL fileURLWithPath:imagePath] absoluteString]];
|
|
||||||
[self.viewController dismissViewControllerAnimated:YES completion:nil];
|
|
||||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//error
|
|
||||||
NSDictionary *error = @{ @"code":errorCode, @"message":message };
|
|
||||||
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:error];
|
|
||||||
[self.viewController dismissViewControllerAnimated:YES completion:nil];
|
|
||||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
if (@available(iOS 13.0, *)){
|
|
||||||
cameraViewController.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
||||||
}
|
|
||||||
[self.viewController presentViewController:cameraViewController animated:YES completion:nil];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)deleteFileWithName:(NSString *)fileName {
|
|
||||||
NSFileManager *manager = [NSFileManager defaultManager];
|
|
||||||
// Need to check if the to be deleted file exists.
|
|
||||||
if ([manager fileExistsAtPath:fileName]) {
|
|
||||||
NSError *error = nil;
|
|
||||||
// This function also returnsYES if the item was removed successfully or if path was nil.
|
|
||||||
// Returns NO if an error occurred.
|
|
||||||
[manager removeItemAtPath:fileName error:&error];
|
|
||||||
if (error) {
|
|
||||||
NSLog(@"There is an Error: %@", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
NSLog(@"File %@ doesn't exists", fileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 256 KiB |
@ -1,81 +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.
|
|
||||||
*/
|
|
||||||
#import <Quartz/Quartz.h>
|
|
||||||
#import <AppKit/AppKit.h>
|
|
||||||
#import <Cordova/CDVPlugin.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum CDVDestinationType {
|
|
||||||
DestinationTypeDataUrl = 0,
|
|
||||||
DestinationTypeFileUri,
|
|
||||||
DestinationTypeNativeUri
|
|
||||||
};
|
|
||||||
typedef NSUInteger CDVDestinationType;
|
|
||||||
|
|
||||||
enum CDVSourceType {
|
|
||||||
SourceTypePhotoLibrary = 0,
|
|
||||||
SourceTypeCamera,
|
|
||||||
SourceTypePhotoAlbum
|
|
||||||
};
|
|
||||||
typedef NSUInteger CDVSourceType;
|
|
||||||
|
|
||||||
enum CDVEncodingType {
|
|
||||||
EncodingTypeJPEG = 0,
|
|
||||||
EncodingTypePNG
|
|
||||||
};
|
|
||||||
typedef NSUInteger CDVEncodingType;
|
|
||||||
|
|
||||||
enum CDVMediaType {
|
|
||||||
MediaTypePicture = 0,
|
|
||||||
MediaTypeVideo,
|
|
||||||
MediaTypeAll
|
|
||||||
};
|
|
||||||
typedef NSUInteger CDVMediaType;
|
|
||||||
|
|
||||||
|
|
||||||
// ======================================================================= //
|
|
||||||
|
|
||||||
|
|
||||||
@interface CDVPictureOptions : NSObject
|
|
||||||
|
|
||||||
@property (strong) NSNumber *quality;
|
|
||||||
@property (assign) CDVDestinationType destinationType;
|
|
||||||
@property (assign) CDVSourceType 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;
|
|
||||||
|
|
||||||
+ (instancetype) createFromTakePictureArguments:(CDVInvokedUrlCommand *)command;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
||||||
// ======================================================================= //
|
|
||||||
|
|
||||||
|
|
||||||
@interface CDVCamera : CDVPlugin
|
|
||||||
|
|
||||||
- (void)takePicture:(CDVInvokedUrlCommand *)command;
|
|
||||||
- (void)cleanup:(CDVInvokedUrlCommand *)command;
|
|
||||||
|
|
||||||
@end
|
|
@ -1,258 +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.
|
|
||||||
*/
|
|
||||||
#import "CDVCamera.h"
|
|
||||||
|
|
||||||
|
|
||||||
@implementation CDVPictureOptions
|
|
||||||
|
|
||||||
+ (instancetype) createFromTakePictureArguments:(CDVInvokedUrlCommand*)command {
|
|
||||||
CDVPictureOptions *pictureOptions = [[CDVPictureOptions alloc] init];
|
|
||||||
|
|
||||||
pictureOptions.quality = [command argumentAtIndex:0 withDefault:@(50)];
|
|
||||||
pictureOptions.destinationType = [[command argumentAtIndex:1 withDefault:@(DestinationTypeFileUri)] unsignedIntegerValue];
|
|
||||||
pictureOptions.sourceType = [[command argumentAtIndex:2 withDefault:@(SourceTypeCamera)] unsignedIntegerValue];
|
|
||||||
|
|
||||||
NSNumber *targetWidth = [command argumentAtIndex:3 withDefault:nil];
|
|
||||||
NSNumber *targetHeight = [command argumentAtIndex:4 withDefault:nil];
|
|
||||||
pictureOptions.targetSize = CGSizeMake(0, 0);
|
|
||||||
if ((targetWidth != nil) && (targetHeight != nil)) {
|
|
||||||
pictureOptions.targetSize = CGSizeMake([targetWidth floatValue], [targetHeight floatValue]);
|
|
||||||
}
|
|
||||||
|
|
||||||
pictureOptions.encodingType = [[command argumentAtIndex:5 withDefault:@(EncodingTypeJPEG)] unsignedIntegerValue];
|
|
||||||
pictureOptions.mediaType = [[command argumentAtIndex:6 withDefault:@(MediaTypePicture)] unsignedIntegerValue];
|
|
||||||
pictureOptions.allowsEditing = [[command argumentAtIndex:7 withDefault:@(NO)] boolValue];
|
|
||||||
pictureOptions.correctOrientation = [[command argumentAtIndex:8 withDefault:@(NO)] boolValue];
|
|
||||||
pictureOptions.saveToPhotoAlbum = [[command argumentAtIndex:9 withDefault:@(NO)] boolValue];
|
|
||||||
|
|
||||||
return pictureOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
||||||
// ======================================================================= //
|
|
||||||
|
|
||||||
|
|
||||||
@implementation CDVCamera
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Static array that stores the temporary created files allowing to delete them when calling navigator.camera.cleanup(...)
|
|
||||||
*/
|
|
||||||
static NSMutableArray *cleanUpFiles;
|
|
||||||
|
|
||||||
+ (void)initialize {
|
|
||||||
cleanUpFiles = [NSMutableArray array];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)takePicture:(CDVInvokedUrlCommand *)command {
|
|
||||||
CDVPictureOptions *pictureOptions = [CDVPictureOptions createFromTakePictureArguments:command];
|
|
||||||
if (pictureOptions.sourceType == SourceTypeCamera) {
|
|
||||||
[self takePictureFromCamera:command withOptions:pictureOptions];
|
|
||||||
} else {
|
|
||||||
[self takePictureFromFile:command withOptions:pictureOptions];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)cleanup:(CDVInvokedUrlCommand*)command {
|
|
||||||
[self.commandDelegate runInBackground:^{
|
|
||||||
if (cleanUpFiles.count > 0) {
|
|
||||||
for (int i=0; i<cleanUpFiles.count; i++) {
|
|
||||||
NSString *path = [cleanUpFiles objectAtIndex:i];
|
|
||||||
[[NSFileManager defaultManager] removeItemAtPath:path error:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
[cleanUpFiles removeAllObjects];
|
|
||||||
|
|
||||||
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
|
|
||||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - Camera
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Takes a picture from the iSight camera using the default OS dialog.
|
|
||||||
@see https://developer.apple.com/documentation/quartz/ikpicturetaker
|
|
||||||
*/
|
|
||||||
- (void)takePictureFromCamera:(CDVInvokedUrlCommand *)command withOptions:(CDVPictureOptions *)pictureOptions {
|
|
||||||
IKPictureTaker *pictureTaker = [IKPictureTaker pictureTaker];
|
|
||||||
[pictureTaker setValue:[NSNumber numberWithBool:YES] forKey:IKPictureTakerAllowsVideoCaptureKey];
|
|
||||||
[pictureTaker setValue:[NSNumber numberWithBool:NO] forKey:IKPictureTakerAllowsFileChoosingKey];
|
|
||||||
[pictureTaker setValue:[NSNumber numberWithBool:pictureOptions.allowsEditing] forKey:IKPictureTakerShowEffectsKey];
|
|
||||||
[pictureTaker setValue:[NSNumber numberWithBool:pictureOptions.allowsEditing] forKey:IKPictureTakerAllowsEditingKey];
|
|
||||||
|
|
||||||
NSDictionary *contextInfo = @{ @"command": command, @"pictureOptions" : pictureOptions};
|
|
||||||
[pictureTaker beginPictureTakerSheetForWindow:self.viewController.contentView.window withDelegate:self didEndSelector:@selector(pictureTakerDidEnd:returnCode:contextInfo:) contextInfo:(void *)CFBridgingRetain(contextInfo)];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)pictureTakerDidEnd:(IKPictureTaker *)pictureTaker returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
|
|
||||||
if (returnCode == NSOKButton) {
|
|
||||||
NSDictionary *contextInfoDictionary = (NSDictionary *)CFBridgingRelease(contextInfo);
|
|
||||||
CDVInvokedUrlCommand *command = [contextInfoDictionary valueForKey:@"command"];
|
|
||||||
CDVPictureOptions *pictureOptions = [contextInfoDictionary valueForKey:@"pictureOptions"];
|
|
||||||
|
|
||||||
[self returnImage:pictureTaker.outputImage command:command options:pictureOptions];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - File
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Allows to select an image or video using the system native dialog.
|
|
||||||
*/
|
|
||||||
- (void)takePictureFromFile:(CDVInvokedUrlCommand *)command withOptions:(CDVPictureOptions *)pictureOptions {
|
|
||||||
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
|
|
||||||
openPanel.canChooseFiles = YES;
|
|
||||||
openPanel.canChooseDirectories = NO;
|
|
||||||
openPanel.canCreateDirectories = YES;
|
|
||||||
openPanel.allowsMultipleSelection = NO;
|
|
||||||
|
|
||||||
NSMutableArray *allowedTypes = [NSMutableArray array];
|
|
||||||
if (pictureOptions.mediaType == MediaTypePicture || pictureOptions.mediaType == MediaTypeAll) {
|
|
||||||
[allowedTypes addObjectsFromArray:[NSImage imageTypes]];
|
|
||||||
}
|
|
||||||
if (pictureOptions.mediaType == MediaTypeVideo || pictureOptions.mediaType == MediaTypeAll) {
|
|
||||||
[allowedTypes addObjectsFromArray:@[(NSString *)kUTTypeMovie]];
|
|
||||||
}
|
|
||||||
[openPanel setAllowedFileTypes:allowedTypes];
|
|
||||||
|
|
||||||
[openPanel beginSheetModalForWindow:self.viewController.contentView.window completionHandler:^(NSInteger result) {
|
|
||||||
if (result == NSOKButton) {
|
|
||||||
NSURL *fileURL = [openPanel.URLs objectAtIndex:0];
|
|
||||||
|
|
||||||
if ([self fileIsImage:fileURL]) {
|
|
||||||
NSImage *image = [[NSImage alloc] initWithContentsOfFile:fileURL.path];
|
|
||||||
[self returnImage:image command:command options:pictureOptions];
|
|
||||||
} else {
|
|
||||||
if (pictureOptions.destinationType == DestinationTypeDataUrl) {
|
|
||||||
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Camera.DestinationType.DATA_URL is only available with image files"];
|
|
||||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
|
||||||
} else {
|
|
||||||
[self returnUri:fileURL.path command:command options:pictureOptions];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - Common
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns to JavaScript a URI.
|
|
||||||
Called when Camera.DestinationType.FILE_URI or Camera.DestinationType.NATIVE_URI.
|
|
||||||
*/
|
|
||||||
- (void)returnUri:(NSString *)path command:(CDVInvokedUrlCommand *)command options:(CDVPictureOptions *)pictureOptions {
|
|
||||||
NSString *protocol = (pictureOptions.destinationType == DestinationTypeFileUri) ? @"file://" : @"";
|
|
||||||
NSString *uri = [NSString stringWithFormat:@"%@%@", protocol, path];
|
|
||||||
|
|
||||||
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:uri];
|
|
||||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns to JavaScript a base64 encoded image.
|
|
||||||
Called when Camera.DestinationType.DATA_URL.
|
|
||||||
*/
|
|
||||||
- (void)returnImage:(NSImage *)image command:(CDVInvokedUrlCommand *)command options:(CDVPictureOptions *)pictureOptions {
|
|
||||||
[self.commandDelegate runInBackground:^{
|
|
||||||
NSData *processedImageData = [self processImage:image options:pictureOptions];
|
|
||||||
|
|
||||||
if (pictureOptions.destinationType == DestinationTypeDataUrl) {
|
|
||||||
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:[processedImageData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]];
|
|
||||||
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
|
||||||
} else {
|
|
||||||
NSString *tempFilePath = [self uniqueImageName:pictureOptions];
|
|
||||||
[processedImageData writeToFile:tempFilePath atomically:YES];
|
|
||||||
[cleanUpFiles addObject:tempFilePath];
|
|
||||||
[self returnUri:tempFilePath command:command options:pictureOptions];
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Top level method to apply the size and quality required changes to an image.
|
|
||||||
*/
|
|
||||||
- (NSData *)processImage:(NSImage *)image options:(CDVPictureOptions *)pictureOptions {
|
|
||||||
NSImage *sourceImage = image;
|
|
||||||
if (pictureOptions.targetSize.width > 0 && pictureOptions.targetSize.height > 0) {
|
|
||||||
sourceImage = [self resizeImage:sourceImage toSize:pictureOptions.targetSize];
|
|
||||||
}
|
|
||||||
|
|
||||||
CGImageRef cgRef = [sourceImage CGImageForProposedRect:NULL context:nil hints:nil];
|
|
||||||
NSBitmapImageRep *imageRepresentation = [[NSBitmapImageRep alloc] initWithCGImage:cgRef];
|
|
||||||
|
|
||||||
NSData *data = (pictureOptions.encodingType == EncodingTypeJPEG)
|
|
||||||
? [imageRepresentation representationUsingType:NSJPEGFileType properties:@{NSImageCompressionFactor: [NSNumber numberWithFloat:pictureOptions.quality.floatValue/100.f]}]
|
|
||||||
: [imageRepresentation representationUsingType:NSPNGFileType properties:@{NSImageCompressionFactor: @1.0}];
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Auxiliar method to resize an image.
|
|
||||||
*/
|
|
||||||
- (NSImage *)resizeImage:(NSImage *)image toSize:(CGSize)newSize {
|
|
||||||
CGFloat aspectWidth = newSize.width / image.size.width;
|
|
||||||
CGFloat aspectHeight = newSize.height / image.size.height;
|
|
||||||
CGFloat aspectRatio = MIN(aspectWidth, aspectHeight);
|
|
||||||
|
|
||||||
CGSize scaledSize = NSMakeSize(image.size.width*aspectRatio, image.size.height*aspectRatio);
|
|
||||||
|
|
||||||
NSImage *smallImage = [[NSImage alloc] initWithSize: scaledSize];
|
|
||||||
[smallImage lockFocus];
|
|
||||||
[image setSize: scaledSize];
|
|
||||||
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
|
|
||||||
[image drawAtPoint:NSZeroPoint fromRect:CGRectMake(0, 0, scaledSize.width, scaledSize.height) operation:NSCompositeCopy fraction:1.0];
|
|
||||||
[smallImage unlockFocus];
|
|
||||||
return smallImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Auxiliar method to know if a given file is an image or not.
|
|
||||||
*/
|
|
||||||
- (BOOL)fileIsImage:(NSURL *)fileURL {
|
|
||||||
NSString *type;
|
|
||||||
BOOL isImage = NO;
|
|
||||||
|
|
||||||
if ([fileURL getResourceValue:&type forKey:NSURLTypeIdentifierKey error:nil]) {
|
|
||||||
isImage = [[NSImage imageTypes] containsObject:type];
|
|
||||||
}
|
|
||||||
|
|
||||||
return isImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Auxiliar method that generates an unique filename for an image in the temporary directory.
|
|
||||||
*/
|
|
||||||
- (NSString *)uniqueImageName:(CDVPictureOptions *)pictureOptions {
|
|
||||||
NSString *tempDir = NSTemporaryDirectory();
|
|
||||||
NSString *guid = [[NSProcessInfo processInfo] globallyUniqueString] ;
|
|
||||||
NSString *extension = (pictureOptions.encodingType == EncodingTypeJPEG) ? @"jpeg" : @"png";
|
|
||||||
NSString *uniqueFileName = [NSString stringWithFormat:@"%@%@.%@", tempDir, guid, extension];
|
|
||||||
return uniqueFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
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
After Width: | Height: | Size: 12 KiB |
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
@ -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
After Width: | Height: | Size: 14 KiB |
BIN
src/ubuntu/toolbar-left.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/ubuntu/toolbar-middle.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
src/ubuntu/toolbar-right.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
516
src/wp/Camera.cs
Normal file
@ -0,0 +1,516 @@
|
|||||||
|
/*
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Ink;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Animation;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Phone.Tasks;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.IsolatedStorage;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using Microsoft.Phone;
|
||||||
|
using Microsoft.Xna.Framework.Media;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace WPCordovaClassLib.Cordova.Commands
|
||||||
|
{
|
||||||
|
public class Camera : BaseCommand
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return base64 encoded string
|
||||||
|
/// </summary>
|
||||||
|
private const int DATA_URL = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return file uri
|
||||||
|
/// </summary>
|
||||||
|
private const int FILE_URI = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Choose image from picture library
|
||||||
|
/// </summary>
|
||||||
|
private const int PHOTOLIBRARY = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Take picture from camera
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
private const int CAMERA = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Choose image from picture library
|
||||||
|
/// </summary>
|
||||||
|
private const int SAVEDPHOTOALBUM = 2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Take a picture of type JPEG
|
||||||
|
/// </summary>
|
||||||
|
private const int JPEG = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Take a picture of type PNG
|
||||||
|
/// </summary>
|
||||||
|
private const int PNG = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Folder to store captured images
|
||||||
|
/// </summary>
|
||||||
|
private const string isoFolder = "CapturedImagesCache";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents captureImage action options.
|
||||||
|
/// </summary>
|
||||||
|
[DataContract]
|
||||||
|
public class CameraOptions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Source to getPicture from.
|
||||||
|
/// </summary>
|
||||||
|
[DataMember(IsRequired = false, Name = "sourceType")]
|
||||||
|
public int PictureSourceType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Format of image that returned from getPicture.
|
||||||
|
/// </summary>
|
||||||
|
[DataMember(IsRequired = false, Name = "destinationType")]
|
||||||
|
public int DestinationType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Quality of saved image
|
||||||
|
/// </summary>
|
||||||
|
[DataMember(IsRequired = false, Name = "quality")]
|
||||||
|
public int Quality { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Controls whether or not the image is also added to the device photo album.
|
||||||
|
/// </summary>
|
||||||
|
[DataMember(IsRequired = false, Name = "saveToPhotoAlbum")]
|
||||||
|
public bool SaveToPhotoAlbum { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ignored
|
||||||
|
/// </summary>
|
||||||
|
[DataMember(IsRequired = false, Name = "correctOrientation")]
|
||||||
|
public bool CorrectOrientation { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ignored
|
||||||
|
/// </summary>
|
||||||
|
[DataMember(IsRequired = false, Name = "allowEdit")]
|
||||||
|
public bool AllowEdit { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Height in pixels to scale image
|
||||||
|
/// </summary>
|
||||||
|
[DataMember(IsRequired = false, Name = "encodingType")]
|
||||||
|
public int EncodingType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Height in pixels to scale image
|
||||||
|
/// </summary>
|
||||||
|
[DataMember(IsRequired = false, Name = "mediaType")]
|
||||||
|
public int MediaType { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Height in pixels to scale image
|
||||||
|
/// </summary>
|
||||||
|
[DataMember(IsRequired = false, Name = "targetHeight")]
|
||||||
|
public int TargetHeight { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Width in pixels to scale image
|
||||||
|
/// </summary>
|
||||||
|
[DataMember(IsRequired = false, Name = "targetWidth")]
|
||||||
|
public int TargetWidth { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates options object with default parameters
|
||||||
|
/// </summary>
|
||||||
|
public CameraOptions()
|
||||||
|
{
|
||||||
|
this.SetDefaultValues(new StreamingContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes default values for class fields.
|
||||||
|
/// Implemented in separate method because default constructor is not invoked during deserialization.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
[OnDeserializing()]
|
||||||
|
public void SetDefaultValues(StreamingContext context)
|
||||||
|
{
|
||||||
|
PictureSourceType = CAMERA;
|
||||||
|
DestinationType = FILE_URI;
|
||||||
|
Quality = 80;
|
||||||
|
TargetHeight = -1;
|
||||||
|
TargetWidth = -1;
|
||||||
|
SaveToPhotoAlbum = false;
|
||||||
|
CorrectOrientation = true;
|
||||||
|
AllowEdit = false;
|
||||||
|
MediaType = -1;
|
||||||
|
EncodingType = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Camera options
|
||||||
|
/// </summary>
|
||||||
|
CameraOptions cameraOptions;
|
||||||
|
|
||||||
|
public void takePicture(string options)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
|
||||||
|
// ["quality", "destinationType", "sourceType", "targetWidth", "targetHeight", "encodingType",
|
||||||
|
// "mediaType", "allowEdit", "correctOrientation", "saveToPhotoAlbum" ]
|
||||||
|
cameraOptions = new CameraOptions();
|
||||||
|
cameraOptions.Quality = int.Parse(args[0]);
|
||||||
|
cameraOptions.DestinationType = int.Parse(args[1]);
|
||||||
|
cameraOptions.PictureSourceType = int.Parse(args[2]);
|
||||||
|
cameraOptions.TargetWidth = int.Parse(args[3]);
|
||||||
|
cameraOptions.TargetHeight = int.Parse(args[4]);
|
||||||
|
cameraOptions.EncodingType = int.Parse(args[5]);
|
||||||
|
cameraOptions.MediaType = int.Parse(args[6]);
|
||||||
|
cameraOptions.AllowEdit = bool.Parse(args[7]);
|
||||||
|
cameraOptions.CorrectOrientation = bool.Parse(args[8]);
|
||||||
|
cameraOptions.SaveToPhotoAlbum = bool.Parse(args[9]);
|
||||||
|
|
||||||
|
// a very large number will force the other value to be the bound
|
||||||
|
if (cameraOptions.TargetWidth > -1 && cameraOptions.TargetHeight == -1)
|
||||||
|
{
|
||||||
|
cameraOptions.TargetHeight = 100000;
|
||||||
|
}
|
||||||
|
else if (cameraOptions.TargetHeight > -1 && cameraOptions.TargetWidth == -1)
|
||||||
|
{
|
||||||
|
cameraOptions.TargetWidth = 100000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
chooserTask = new CameraCaptureTask();
|
||||||
|
}
|
||||||
|
else if ((cameraOptions.PictureSourceType == PHOTOLIBRARY) || (cameraOptions.PictureSourceType == SAVEDPHOTOALBUM))
|
||||||
|
{
|
||||||
|
chooserTask = new PhotoChooserTask();
|
||||||
|
}
|
||||||
|
// if chooserTask is still null, then PictureSourceType was invalid
|
||||||
|
if (chooserTask != null)
|
||||||
|
{
|
||||||
|
chooserTask.Completed += onTaskCompleted;
|
||||||
|
chooserTask.Show();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.WriteLine("Unrecognized PictureSourceType :: " + cameraOptions.PictureSourceType.ToString());
|
||||||
|
DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onTaskCompleted(object sender, PhotoResult e)
|
||||||
|
{
|
||||||
|
var task = sender as ChooserBase<PhotoResult>;
|
||||||
|
if (task != null)
|
||||||
|
{
|
||||||
|
task.Completed -= onTaskCompleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Error != null)
|
||||||
|
{
|
||||||
|
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (e.TaskResult)
|
||||||
|
{
|
||||||
|
case TaskResult.OK:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string imagePathOrContent = string.Empty;
|
||||||
|
|
||||||
|
// Save image back to media library
|
||||||
|
// only save to photoalbum if it didn't come from there ...
|
||||||
|
if (cameraOptions.PictureSourceType == CAMERA && cameraOptions.SaveToPhotoAlbum)
|
||||||
|
{
|
||||||
|
MediaLibrary library = new MediaLibrary();
|
||||||
|
Picture pict = library.SavePicture(e.OriginalFileName, e.ChosenPhoto); // to save to photo-roll ...
|
||||||
|
}
|
||||||
|
|
||||||
|
int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto);
|
||||||
|
int newAngle = 0;
|
||||||
|
switch (orient)
|
||||||
|
{
|
||||||
|
case ImageExifOrientation.LandscapeLeft:
|
||||||
|
newAngle = 90;
|
||||||
|
break;
|
||||||
|
case ImageExifOrientation.PortraitUpsideDown:
|
||||||
|
newAngle = 180;
|
||||||
|
break;
|
||||||
|
case ImageExifOrientation.LandscapeRight:
|
||||||
|
newAngle = 270;
|
||||||
|
break;
|
||||||
|
case ImageExifOrientation.Portrait:
|
||||||
|
default: break; // 0 default already set
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newAngle != 0)
|
||||||
|
{
|
||||||
|
using (Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle))
|
||||||
|
{
|
||||||
|
// we should reset stream position after saving stream to media library
|
||||||
|
rotImageStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
if (cameraOptions.DestinationType == DATA_URL)
|
||||||
|
{
|
||||||
|
imagePathOrContent = GetImageContent(rotImageStream);
|
||||||
|
}
|
||||||
|
else // FILE_URL
|
||||||
|
{
|
||||||
|
imagePathOrContent = SaveImageToLocalStorage(rotImageStream, Path.GetFileName(e.OriginalFileName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // no need to reorient
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns image content in a form of base64 string
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">Image stream</param>
|
||||||
|
/// <returns>Base64 representation of the image</returns>
|
||||||
|
private string GetImageContent(Stream stream)
|
||||||
|
{
|
||||||
|
byte[] imageContent = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Resize photo and convert to JPEG
|
||||||
|
imageContent = ResizePhoto(stream);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
stream.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Convert.ToBase64String(imageContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resize image
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">Image stream</param>
|
||||||
|
/// <returns>resized image</returns>
|
||||||
|
private byte[] ResizePhoto(Stream stream)
|
||||||
|
{
|
||||||
|
//output
|
||||||
|
byte[] resizedFile;
|
||||||
|
|
||||||
|
BitmapImage objBitmap = new BitmapImage();
|
||||||
|
objBitmap.SetSource(stream);
|
||||||
|
objBitmap.CreateOptions = BitmapCreateOptions.None;
|
||||||
|
|
||||||
|
WriteableBitmap objWB = new WriteableBitmap(objBitmap);
|
||||||
|
objBitmap.UriSource = null;
|
||||||
|
|
||||||
|
// Calculate resultant image size
|
||||||
|
int width, height;
|
||||||
|
if (cameraOptions.TargetWidth >= 0 && cameraOptions.TargetHeight >= 0)
|
||||||
|
{
|
||||||
|
// Keep proportionally
|
||||||
|
double ratio = Math.Min(
|
||||||
|
(double)cameraOptions.TargetWidth / objWB.PixelWidth,
|
||||||
|
(double)cameraOptions.TargetHeight / objWB.PixelHeight);
|
||||||
|
width = Convert.ToInt32(ratio * objWB.PixelWidth);
|
||||||
|
height = Convert.ToInt32(ratio * objWB.PixelHeight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
width = objWB.PixelWidth;
|
||||||
|
height = objWB.PixelHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Hold the result stream
|
||||||
|
using (MemoryStream objBitmapStreamResized = new MemoryStream())
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// resize the photo with user defined TargetWidth & TargetHeight
|
||||||
|
Extensions.SaveJpeg(objWB, objBitmapStreamResized, width, height, 0, cameraOptions.Quality);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
//Dispose bitmaps immediately, they are memory expensive
|
||||||
|
DisposeImage(objBitmap);
|
||||||
|
DisposeImage(objWB);
|
||||||
|
GC.Collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Convert the resized stream to a byte array.
|
||||||
|
int streamLength = (int)objBitmapStreamResized.Length;
|
||||||
|
resizedFile = new Byte[streamLength]; //-1
|
||||||
|
objBitmapStreamResized.Position = 0;
|
||||||
|
|
||||||
|
//for some reason we have to set Position to zero, but we don't have to earlier when we get the bytes from the chosen photo...
|
||||||
|
objBitmapStreamResized.Read(resizedFile, 0, streamLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resizedFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Util: Dispose a bitmap resource
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image">BitmapSource subclass to dispose</param>
|
||||||
|
private void DisposeImage(BitmapSource image)
|
||||||
|
{
|
||||||
|
if (image != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var ms = new MemoryStream(new byte[] { 0x0 }))
|
||||||
|
{
|
||||||
|
image.SetSource(ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves captured image in isolated storage
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="imageFileName">image file name</param>
|
||||||
|
/// <returns>Image path</returns>
|
||||||
|
private string SaveImageToLocalStorage(Stream stream, string imageFileName)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (stream == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("imageBytes");
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
|
||||||
|
|
||||||
|
if (!isoFile.DirectoryExists(isoFolder))
|
||||||
|
{
|
||||||
|
isoFile.CreateDirectory(isoFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
string filePath = System.IO.Path.Combine("///" + isoFolder + "/", imageFileName);
|
||||||
|
|
||||||
|
using (IsolatedStorageFileStream outputStream = isoFile.CreateFile(filePath))
|
||||||
|
{
|
||||||
|
BitmapImage objBitmap = new BitmapImage();
|
||||||
|
objBitmap.SetSource(stream);
|
||||||
|
objBitmap.CreateOptions = BitmapCreateOptions.None;
|
||||||
|
|
||||||
|
WriteableBitmap objWB = new WriteableBitmap(objBitmap);
|
||||||
|
objBitmap.UriSource = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
//use photo's actual width & height if user doesn't provide width & height
|
||||||
|
if (cameraOptions.TargetWidth < 0 && cameraOptions.TargetHeight < 0)
|
||||||
|
{
|
||||||
|
objWB.SaveJpeg(outputStream, objWB.PixelWidth, objWB.PixelHeight, 0, cameraOptions.Quality);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Resize
|
||||||
|
//Keep proportionally
|
||||||
|
double ratio = Math.Min((double)cameraOptions.TargetWidth / objWB.PixelWidth, (double)cameraOptions.TargetHeight / objWB.PixelHeight);
|
||||||
|
int width = Convert.ToInt32(ratio * objWB.PixelWidth);
|
||||||
|
int height = Convert.ToInt32(ratio * objWB.PixelHeight);
|
||||||
|
|
||||||
|
// resize the photo with user defined TargetWidth & TargetHeight
|
||||||
|
objWB.SaveJpeg(outputStream, width, height, 0, cameraOptions.Quality);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
//Dispose bitmaps immediately, they are memory expensive
|
||||||
|
DisposeImage(objBitmap);
|
||||||
|
DisposeImage(objWB);
|
||||||
|
GC.Collect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Uri(filePath, UriKind.Relative).ToString();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
//TODO: log or do something else
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
stream.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,9 @@
|
|||||||
#import <XCTest/XCTest.h>
|
#import <XCTest/XCTest.h>
|
||||||
#import "CDVCamera.h"
|
#import "CDVCamera.h"
|
||||||
#import "UIImage+CropScaleOrientation.h"
|
#import "UIImage+CropScaleOrientation.h"
|
||||||
|
#import <Cordova/NSArray+Comparisons.h>
|
||||||
|
#import <Cordova/NSData+Base64.h>
|
||||||
|
#import <Cordova/NSDictionary+Extensions.h>
|
||||||
#import <MobileCoreServices/UTCoreTypes.h>
|
#import <MobileCoreServices/UTCoreTypes.h>
|
||||||
|
|
||||||
|
|
||||||
@ -62,9 +65,7 @@
|
|||||||
|
|
||||||
// No arguments, check whether the defaults are set
|
// No arguments, check whether the defaults are set
|
||||||
args = @[];
|
args = @[];
|
||||||
CDVInvokedUrlCommand* command = [[CDVInvokedUrlCommand alloc] initWithArguments:args callbackId:@"dummy" className:@"myclassname" methodName:@"mymethodname"];
|
options = [CDVPictureOptions createFromTakePictureArguments:args];
|
||||||
|
|
||||||
options = [CDVPictureOptions createFromTakePictureArguments:command];
|
|
||||||
|
|
||||||
XCTAssertEqual([options.quality intValue], 50);
|
XCTAssertEqual([options.quality intValue], 50);
|
||||||
XCTAssertEqual(options.destinationType, (int)DestinationTypeFileUri);
|
XCTAssertEqual(options.destinationType, (int)DestinationTypeFileUri);
|
||||||
@ -82,7 +83,7 @@
|
|||||||
XCTAssertEqual(options.usesGeolocation, NO);
|
XCTAssertEqual(options.usesGeolocation, NO);
|
||||||
|
|
||||||
// Set each argument, check whether they are set. different from defaults
|
// Set each argument, check whether they are set. different from defaults
|
||||||
popoverOptions = @{ @"x" : @1, @"y" : @2, @"width" : @3, @"height" : @4, @"popoverWidth": @200, @"popoverHeight": @300 };
|
popoverOptions = @{ @"x" : @1, @"y" : @2, @"width" : @3, @"height" : @4 };
|
||||||
|
|
||||||
args = @[
|
args = @[
|
||||||
@(49),
|
@(49),
|
||||||
@ -98,9 +99,7 @@
|
|||||||
popoverOptions,
|
popoverOptions,
|
||||||
@(UIImagePickerControllerCameraDeviceFront),
|
@(UIImagePickerControllerCameraDeviceFront),
|
||||||
];
|
];
|
||||||
|
options = [CDVPictureOptions createFromTakePictureArguments:args];
|
||||||
command = [[CDVInvokedUrlCommand alloc] initWithArguments:args callbackId:@"dummy" className:@"myclassname" methodName:@"mymethodname"];
|
|
||||||
options = [CDVPictureOptions createFromTakePictureArguments:command];
|
|
||||||
|
|
||||||
XCTAssertEqual([options.quality intValue], 49);
|
XCTAssertEqual([options.quality intValue], 49);
|
||||||
XCTAssertEqual(options.destinationType, (int)DestinationTypeDataUrl);
|
XCTAssertEqual(options.destinationType, (int)DestinationTypeDataUrl);
|
||||||
@ -127,7 +126,7 @@
|
|||||||
|
|
||||||
// Souce is Camera, and image type
|
// Souce is Camera, and image type
|
||||||
|
|
||||||
popoverOptions = @{ @"x" : @1, @"y" : @2, @"width" : @3, @"height" : @4, @"popoverWidth": @200, @"popoverHeight": @300 };
|
popoverOptions = @{ @"x" : @1, @"y" : @2, @"width" : @3, @"height" : @4 };
|
||||||
args = @[
|
args = @[
|
||||||
@(49),
|
@(49),
|
||||||
@(DestinationTypeDataUrl),
|
@(DestinationTypeDataUrl),
|
||||||
@ -142,9 +141,7 @@
|
|||||||
popoverOptions,
|
popoverOptions,
|
||||||
@(UIImagePickerControllerCameraDeviceFront),
|
@(UIImagePickerControllerCameraDeviceFront),
|
||||||
];
|
];
|
||||||
|
pictureOptions = [CDVPictureOptions createFromTakePictureArguments:args];
|
||||||
CDVInvokedUrlCommand* command = [[CDVInvokedUrlCommand alloc] initWithArguments:args callbackId:@"dummy" className:@"myclassname" methodName:@"mymethodname"];
|
|
||||||
pictureOptions = [CDVPictureOptions createFromTakePictureArguments:command];
|
|
||||||
|
|
||||||
if ([UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType]) {
|
if ([UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType]) {
|
||||||
picker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
picker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
||||||
@ -173,9 +170,7 @@
|
|||||||
popoverOptions,
|
popoverOptions,
|
||||||
@(UIImagePickerControllerCameraDeviceFront),
|
@(UIImagePickerControllerCameraDeviceFront),
|
||||||
];
|
];
|
||||||
|
pictureOptions = [CDVPictureOptions createFromTakePictureArguments:args];
|
||||||
command = [[CDVInvokedUrlCommand alloc] initWithArguments:args callbackId:@"dummy" className:@"myclassname" methodName:@"mymethodname"];
|
|
||||||
pictureOptions = [CDVPictureOptions createFromTakePictureArguments:command];
|
|
||||||
|
|
||||||
if ([UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType]) {
|
if ([UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType]) {
|
||||||
picker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
picker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
||||||
@ -203,9 +198,7 @@
|
|||||||
popoverOptions,
|
popoverOptions,
|
||||||
@(UIImagePickerControllerCameraDeviceFront),
|
@(UIImagePickerControllerCameraDeviceFront),
|
||||||
];
|
];
|
||||||
|
pictureOptions = [CDVPictureOptions createFromTakePictureArguments:args];
|
||||||
command = [[CDVInvokedUrlCommand alloc] initWithArguments:args callbackId:@"dummy" className:@"myclassname" methodName:@"mymethodname"];
|
|
||||||
pictureOptions = [CDVPictureOptions createFromTakePictureArguments:command];
|
|
||||||
|
|
||||||
if ([UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType]) {
|
if ([UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType]) {
|
||||||
picker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
picker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
||||||
@ -288,14 +281,12 @@
|
|||||||
|
|
||||||
// test 640x480
|
// test 640x480
|
||||||
|
|
||||||
targetSize = CGSizeMake(480, 640);
|
targetSize = CGSizeMake(640, 480);
|
||||||
|
|
||||||
targetImage = [sourceImagePortrait imageByScalingNotCroppingForSize:targetSize];
|
targetImage = [sourceImagePortrait imageByScalingNotCroppingForSize:targetSize];
|
||||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||||
|
|
||||||
targetSize = CGSizeMake(640, 480);
|
|
||||||
|
|
||||||
targetImage = [sourceImageLandscape imageByScalingNotCroppingForSize:targetSize];
|
targetImage = [sourceImageLandscape imageByScalingNotCroppingForSize:targetSize];
|
||||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||||
@ -303,28 +294,24 @@
|
|||||||
|
|
||||||
// test 800x600
|
// test 800x600
|
||||||
|
|
||||||
targetSize = CGSizeMake(600, 800);
|
targetSize = CGSizeMake(800, 600);
|
||||||
|
|
||||||
targetImage = [sourceImagePortrait imageByScalingNotCroppingForSize:targetSize];
|
targetImage = [sourceImagePortrait imageByScalingNotCroppingForSize:targetSize];
|
||||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||||
|
|
||||||
targetSize = CGSizeMake(800, 600);
|
|
||||||
|
|
||||||
targetImage = [sourceImageLandscape imageByScalingNotCroppingForSize:targetSize];
|
targetImage = [sourceImageLandscape imageByScalingNotCroppingForSize:targetSize];
|
||||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||||
|
|
||||||
// test 1024x768
|
// test 1024x768
|
||||||
|
|
||||||
targetSize = CGSizeMake(768, 1024);
|
targetSize = CGSizeMake(1024, 768);
|
||||||
|
|
||||||
targetImage = [sourceImagePortrait imageByScalingNotCroppingForSize:targetSize];
|
targetImage = [sourceImagePortrait imageByScalingNotCroppingForSize:targetSize];
|
||||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||||
|
|
||||||
targetSize = CGSizeMake(1024, 768);
|
|
||||||
|
|
||||||
targetImage = [sourceImageLandscape imageByScalingNotCroppingForSize:targetSize];
|
targetImage = [sourceImageLandscape imageByScalingNotCroppingForSize:targetSize];
|
||||||
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
XCTAssertEqual(targetImage.size.width, targetSize.width);
|
||||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||||
@ -479,7 +466,7 @@
|
|||||||
pictureOptions.encodingType = EncodingTypePNG;
|
pictureOptions.encodingType = EncodingTypePNG;
|
||||||
|
|
||||||
resultData = [self.plugin processImage:originalImage info:@{} options:pictureOptions];
|
resultData = [self.plugin processImage:originalImage info:@{} options:pictureOptions];
|
||||||
XCTAssertEqualObjects([resultData base64EncodedStringWithOptions:0], [originalImageDataPNG base64EncodedStringWithOptions:0]);
|
XCTAssertEqualObjects([resultData base64EncodedString], [originalImageDataPNG base64EncodedString]);
|
||||||
|
|
||||||
// Original, JPEG, full quality
|
// Original, JPEG, full quality
|
||||||
|
|
||||||
@ -490,7 +477,7 @@
|
|||||||
pictureOptions.encodingType = EncodingTypeJPEG;
|
pictureOptions.encodingType = EncodingTypeJPEG;
|
||||||
|
|
||||||
resultData = [self.plugin processImage:originalImage info:@{} options:pictureOptions];
|
resultData = [self.plugin processImage:originalImage info:@{} options:pictureOptions];
|
||||||
XCTAssertEqualObjects([resultData base64EncodedStringWithOptions:0], [originalImageDataJPEG base64EncodedStringWithOptions:0]);
|
XCTAssertEqualObjects([resultData base64EncodedString], [originalImageDataJPEG base64EncodedString]);
|
||||||
|
|
||||||
// Original, JPEG, with quality value
|
// Original, JPEG, with quality value
|
||||||
|
|
||||||
@ -503,7 +490,7 @@
|
|||||||
|
|
||||||
NSData* originalImageDataJPEGWithQuality = UIImageJPEGRepresentation(originalImage, [pictureOptions.quality floatValue]/ 100.f);
|
NSData* originalImageDataJPEGWithQuality = UIImageJPEGRepresentation(originalImage, [pictureOptions.quality floatValue]/ 100.f);
|
||||||
resultData = [self.plugin processImage:originalImage info:@{} options:pictureOptions];
|
resultData = [self.plugin processImage:originalImage info:@{} options:pictureOptions];
|
||||||
XCTAssertEqualObjects([resultData base64EncodedStringWithOptions:0], [originalImageDataJPEGWithQuality base64EncodedStringWithOptions:0]);
|
XCTAssertEqualObjects([resultData base64EncodedString], [originalImageDataJPEGWithQuality base64EncodedString]);
|
||||||
|
|
||||||
// TODO: usesGeolocation is not tested
|
// TODO: usesGeolocation is not tested
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<!--
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
-->
|
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
@ -1,22 +1,3 @@
|
|||||||
<!---
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
# iOS Tests for CDVCamera
|
# iOS Tests for CDVCamera
|
||||||
|
|
||||||
You need to install `node.js` to pull in `cordova-ios`.
|
You need to install `node.js` to pull in `cordova-ios`.
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
"author": "Apache Software Foundation",
|
"author": "Apache Software Foundation",
|
||||||
"license": "Apache Version 2.0",
|
"license": "Apache Version 2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cordova-ios": "*"
|
"cordova-ios": "^3.7.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "xcodebuild -scheme CordovaLib && xcodebuild test -scheme CDVCameraLibTests -destination 'platform=iOS Simulator,name=iPhone 5s'"
|
"test": "xcodebuild -scheme CordovaLib && xcodebuild test -scheme CDVCameraLibTests -destination 'platform=iOS Simulator,name=iPhone 5'"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "cordova-plugin-camera-tests",
|
|
||||||
"version": "4.2.0-dev",
|
|
||||||
"description": "",
|
|
||||||
"cordova": {
|
|
||||||
"id": "cordova-plugin-camera-tests",
|
|
||||||
"platforms": []
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"ecosystem:cordova"
|
|
||||||
],
|
|
||||||
"author": "",
|
|
||||||
"license": "Apache-2.0"
|
|
||||||
}
|
|
@ -21,12 +21,12 @@
|
|||||||
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:rim="http://www.blackberry.com/ns/widgets"
|
xmlns:rim="http://www.blackberry.com/ns/widgets"
|
||||||
id="cordova-plugin-camera-tests"
|
id="org.apache.cordova.camera.tests"
|
||||||
version="4.2.0-dev">
|
version="0.3.6-dev">
|
||||||
<name>Cordova Camera Plugin Tests</name>
|
<name>Cordova Camera Plugin Tests</name>
|
||||||
<license>Apache 2.0</license>
|
<license>Apache 2.0</license>
|
||||||
|
|
||||||
<dependency id="cordova-plugin-file-transfer" />
|
<dependency id="org.apache.cordova.file" version=">=1.0.1" />
|
||||||
|
|
||||||
<js-module src="tests.js" name="tests">
|
<js-module src="tests.js" name="tests">
|
||||||
</js-module>
|
</js-module>
|
||||||
|
196
tests/tests.js
@ -19,27 +19,24 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* globals Camera, resolveLocalFileSystemURL, FileEntry, CameraPopoverOptions, FileTransfer, FileUploadOptions, LocalFileSystem, MSApp */
|
|
||||||
/* eslint-env jasmine */
|
|
||||||
|
|
||||||
exports.defineAutoTests = function () {
|
exports.defineAutoTests = function () {
|
||||||
describe('Camera (navigator.camera)', function () {
|
describe('Camera (navigator.camera)', function () {
|
||||||
it('should exist', function () {
|
it("should exist", function () {
|
||||||
expect(navigator.camera).toBeDefined();
|
expect(navigator.camera).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should contain a getPicture function', function () {
|
it("should contain a getPicture function", function () {
|
||||||
expect(navigator.camera.getPicture).toBeDefined();
|
expect(navigator.camera.getPicture).toBeDefined();
|
||||||
expect(typeof navigator.camera.getPicture === 'function').toBe(true);
|
expect(typeof navigator.camera.getPicture == 'function').toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Camera Constants (window.Camera + navigator.camera)', function () {
|
describe('Camera Constants (window.Camera + navigator.camera)', function () {
|
||||||
it('camera.spec.1 window.Camera should exist', function () {
|
it("camera.spec.1 window.Camera should exist", function () {
|
||||||
expect(window.Camera).toBeDefined();
|
expect(window.Camera).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('camera.spec.2 should contain three DestinationType constants', function () {
|
it("camera.spec.2 should contain three DestinationType constants", function () {
|
||||||
expect(Camera.DestinationType.DATA_URL).toBe(0);
|
expect(Camera.DestinationType.DATA_URL).toBe(0);
|
||||||
expect(Camera.DestinationType.FILE_URI).toBe(1);
|
expect(Camera.DestinationType.FILE_URI).toBe(1);
|
||||||
expect(Camera.DestinationType.NATIVE_URI).toBe(2);
|
expect(Camera.DestinationType.NATIVE_URI).toBe(2);
|
||||||
@ -48,14 +45,14 @@ exports.defineAutoTests = function () {
|
|||||||
expect(navigator.camera.DestinationType.NATIVE_URI).toBe(2);
|
expect(navigator.camera.DestinationType.NATIVE_URI).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('camera.spec.3 should contain two EncodingType constants', function () {
|
it("camera.spec.3 should contain two EncodingType constants", function () {
|
||||||
expect(Camera.EncodingType.JPEG).toBe(0);
|
expect(Camera.EncodingType.JPEG).toBe(0);
|
||||||
expect(Camera.EncodingType.PNG).toBe(1);
|
expect(Camera.EncodingType.PNG).toBe(1);
|
||||||
expect(navigator.camera.EncodingType.JPEG).toBe(0);
|
expect(navigator.camera.EncodingType.JPEG).toBe(0);
|
||||||
expect(navigator.camera.EncodingType.PNG).toBe(1);
|
expect(navigator.camera.EncodingType.PNG).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('camera.spec.4 should contain three MediaType constants', function () {
|
it("camera.spec.4 should contain three MediaType constants", function () {
|
||||||
expect(Camera.MediaType.PICTURE).toBe(0);
|
expect(Camera.MediaType.PICTURE).toBe(0);
|
||||||
expect(Camera.MediaType.VIDEO).toBe(1);
|
expect(Camera.MediaType.VIDEO).toBe(1);
|
||||||
expect(Camera.MediaType.ALLMEDIA).toBe(2);
|
expect(Camera.MediaType.ALLMEDIA).toBe(2);
|
||||||
@ -64,7 +61,7 @@ exports.defineAutoTests = function () {
|
|||||||
expect(navigator.camera.MediaType.ALLMEDIA).toBe(2);
|
expect(navigator.camera.MediaType.ALLMEDIA).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('camera.spec.5 should contain three PictureSourceType constants', function () {
|
it("camera.spec.5 should contain three PictureSourceType constants", function () {
|
||||||
expect(Camera.PictureSourceType.PHOTOLIBRARY).toBe(0);
|
expect(Camera.PictureSourceType.PHOTOLIBRARY).toBe(0);
|
||||||
expect(Camera.PictureSourceType.CAMERA).toBe(1);
|
expect(Camera.PictureSourceType.CAMERA).toBe(1);
|
||||||
expect(Camera.PictureSourceType.SAVEDPHOTOALBUM).toBe(2);
|
expect(Camera.PictureSourceType.SAVEDPHOTOALBUM).toBe(2);
|
||||||
@ -75,17 +72,19 @@ exports.defineAutoTests = function () {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
exports.defineManualTests = function (contentEl, createActionButton) {
|
exports.defineManualTests = function (contentEl, createActionButton) {
|
||||||
|
var platformId = cordova.require('cordova/platform').id;
|
||||||
var pictureUrl = null;
|
var pictureUrl = null;
|
||||||
var fileObj = null;
|
var fileObj = null;
|
||||||
var fileEntry = null;
|
var fileEntry = null;
|
||||||
var pageStartTime = +new Date();
|
var pageStartTime = +new Date();
|
||||||
|
|
||||||
// default camera options
|
//default camera options
|
||||||
var camQualityDefault = ['50', 50];
|
var camQualityDefault = ['50', 50];
|
||||||
var camDestinationTypeDefault = ['FILE_URI', 1];
|
var camDestinationTypeDefault = ['FILE_URI', 1];
|
||||||
var camPictureSourceTypeDefault = ['CAMERA', 1];
|
var camPictureSourceTypeDefault = ['CAMERA', 1];
|
||||||
@ -95,12 +94,17 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
var camCorrectOrientationDefault = ['correctOrientation', false];
|
var camCorrectOrientationDefault = ['correctOrientation', false];
|
||||||
var camSaveToPhotoAlbumDefault = ['saveToPhotoAlbum', true];
|
var camSaveToPhotoAlbumDefault = ['saveToPhotoAlbum', true];
|
||||||
|
|
||||||
function log (value) {
|
var clearLog = function () {
|
||||||
|
var log = document.getElementById('info');
|
||||||
|
log.innerHTML = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function log(value) {
|
||||||
console.log(value);
|
console.log(value);
|
||||||
document.getElementById('camera_status').textContent += (new Date() - pageStartTime) / 1000 + ': ' + value + '\n';
|
document.getElementById('camera_status').textContent += (new Date() - pageStartTime) / 1000 + ': ' + value + '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearStatus () {
|
function clearStatus() {
|
||||||
document.getElementById('camera_status').innerHTML = '';
|
document.getElementById('camera_status').innerHTML = '';
|
||||||
document.getElementById('camera_image').src = 'about:blank';
|
document.getElementById('camera_image').src = 'about:blank';
|
||||||
var canvas = document.getElementById('canvas');
|
var canvas = document.getElementById('canvas');
|
||||||
@ -110,43 +114,39 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
fileEntry = null;
|
fileEntry = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPicture (url, callback) {
|
function setPicture(url, callback) {
|
||||||
try {
|
try {
|
||||||
window.atob(url);
|
window.atob(url);
|
||||||
// if we got here it is a base64 string (DATA_URL)
|
// if we got here it is a base64 string (DATA_URL)
|
||||||
url = 'data:image/jpeg;base64,' + url;
|
url = "data:image/jpeg;base64," + url;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// not DATA_URL
|
// not DATA_URL
|
||||||
|
log('URL: ' + url.slice(0, 100));
|
||||||
}
|
}
|
||||||
log('URL: "' + url.slice(0, 90) + '"');
|
|
||||||
|
|
||||||
pictureUrl = url;
|
pictureUrl = url;
|
||||||
var img = document.getElementById('camera_image');
|
var img = document.getElementById('camera_image');
|
||||||
var startTime = new Date();
|
var startTime = new Date();
|
||||||
img.src = url;
|
img.src = url;
|
||||||
img.onload = function () {
|
img.onloadend = function () {
|
||||||
log('Img size: ' + img.naturalWidth + 'x' + img.naturalHeight);
|
|
||||||
log('Image tag load time: ' + (new Date() - startTime));
|
log('Image tag load time: ' + (new Date() - startTime));
|
||||||
if (callback) {
|
callback && callback();
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function onGetPictureError (e) {
|
function onGetPictureError(e) {
|
||||||
log('Error getting picture: ' + (e.code || e));
|
log('Error getting picture: ' + (e.code || e));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPictureWin (data) {
|
function getPictureWin(data) {
|
||||||
setPicture(data);
|
setPicture(data);
|
||||||
// TODO: Fix resolveLocalFileSystemURI to work with native-uri.
|
// TODO: Fix resolveLocalFileSystemURI to work with native-uri.
|
||||||
if (pictureUrl.indexOf('file:') === 0 || pictureUrl.indexOf('content:') === 0 || pictureUrl.indexOf('ms-appdata:') === 0 || pictureUrl.indexOf('assets-library:') === 0) {
|
if (pictureUrl.indexOf('file:') == 0 || pictureUrl.indexOf('content:') == 0 || pictureUrl.indexOf('ms-appdata:') === 0) {
|
||||||
resolveLocalFileSystemURL(data, function (e) {
|
resolveLocalFileSystemURI(data, function (e) {
|
||||||
fileEntry = e;
|
fileEntry = e;
|
||||||
logCallback('resolveLocalFileSystemURL()', true)(e.toURL());
|
logCallback('resolveLocalFileSystemURI()', true)(e.toURL());
|
||||||
readFile();
|
}, logCallback('resolveLocalFileSystemURI()', false));
|
||||||
}, logCallback('resolveLocalFileSystemURL()', false));
|
} else if (pictureUrl.indexOf('data:image/jpeg;base64') == 0) {
|
||||||
} else if (pictureUrl.indexOf('data:image/jpeg;base64') === 0) {
|
|
||||||
// do nothing
|
// do nothing
|
||||||
} else {
|
} else {
|
||||||
var path = pictureUrl.replace(/^file:\/\/(localhost)?/, '').replace(/%20/g, ' ');
|
var path = pictureUrl.replace(/^file:\/\/(localhost)?/, '').replace(/%20/g, ' ');
|
||||||
@ -154,7 +154,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPicture () {
|
function getPicture() {
|
||||||
clearStatus();
|
clearStatus();
|
||||||
var options = extractOptions();
|
var options = extractOptions();
|
||||||
log('Getting picture with options: ' + JSON.stringify(options));
|
log('Getting picture with options: ' + JSON.stringify(options));
|
||||||
@ -162,32 +162,34 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
|
|
||||||
// Reposition the popover if the orientation changes.
|
// Reposition the popover if the orientation changes.
|
||||||
window.onorientationchange = function () {
|
window.onorientationchange = function () {
|
||||||
var newPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, 0, 300, 400);
|
var newPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, 0);
|
||||||
popoverHandle.setPosition(newPopoverOptions);
|
popoverHandle.setPosition(newPopoverOptions);
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function uploadImage () {
|
function uploadImage() {
|
||||||
var ft = new FileTransfer();
|
var ft = new FileTransfer(),
|
||||||
var options = new FileUploadOptions();
|
uploadcomplete = 0,
|
||||||
options.fileKey = 'photo';
|
progress = 0,
|
||||||
|
options = new FileUploadOptions();
|
||||||
|
options.fileKey = "photo";
|
||||||
options.fileName = 'test.jpg';
|
options.fileName = 'test.jpg';
|
||||||
options.mimeType = 'image/jpeg';
|
options.mimeType = "image/jpeg";
|
||||||
ft.onprogress = function (progressEvent) {
|
ft.onprogress = function (progressEvent) {
|
||||||
console.log('progress: ' + progressEvent.loaded + ' of ' + progressEvent.total);
|
console.log('progress: ' + progressEvent.loaded + ' of ' + progressEvent.total);
|
||||||
};
|
};
|
||||||
var server = 'http://sheltered-retreat-43956.herokuapp.com';
|
var server = "http://cordova-filetransfer.jitsu.com";
|
||||||
|
|
||||||
ft.upload(pictureUrl, server + '/upload', win, fail, options);
|
ft.upload(pictureUrl, server + '/upload', win, fail, options);
|
||||||
function win (information_back) {
|
function win(information_back) {
|
||||||
log('upload complete');
|
log('upload complete');
|
||||||
}
|
}
|
||||||
function fail (message) {
|
function fail(message) {
|
||||||
log('upload failed: ' + JSON.stringify(message));
|
log('upload failed: ' + JSON.stringify(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function logCallback (apiName, success) {
|
function logCallback(apiName, success) {
|
||||||
return function () {
|
return function () {
|
||||||
log('Call to ' + apiName + (success ? ' success: ' : ' failed: ') + JSON.stringify([].slice.call(arguments)));
|
log('Call to ' + apiName + (success ? ' success: ' : ' failed: ') + JSON.stringify([].slice.call(arguments)));
|
||||||
};
|
};
|
||||||
@ -197,29 +199,26 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
* Select image from library using a NATIVE_URI destination type
|
* Select image from library using a NATIVE_URI destination type
|
||||||
* This calls FileEntry.getMetadata, FileEntry.setMetadata, FileEntry.getParent, FileEntry.file, and FileReader.readAsDataURL.
|
* This calls FileEntry.getMetadata, FileEntry.setMetadata, FileEntry.getParent, FileEntry.file, and FileReader.readAsDataURL.
|
||||||
*/
|
*/
|
||||||
function readFile () {
|
function readFile() {
|
||||||
function onFileReadAsDataURL (evt) {
|
function onFileReadAsDataURL(evt) {
|
||||||
var img = document.getElementById('camera_image');
|
var img = document.getElementById('camera_image');
|
||||||
img.style.visibility = 'visible';
|
img.style.visibility = "visible";
|
||||||
img.style.display = 'block';
|
img.style.display = "block";
|
||||||
img.src = evt.target.result;
|
img.src = evt.target.result;
|
||||||
log('FileReader.readAsDataURL success');
|
log("FileReader.readAsDataURL success");
|
||||||
}
|
};
|
||||||
|
|
||||||
function onFileReceived (file) {
|
function onFileReceived(file) {
|
||||||
log('Got file: ' + JSON.stringify(file));
|
log('Got file: ' + JSON.stringify(file));
|
||||||
fileObj = file;
|
fileObj = file;
|
||||||
/* eslint-disable no-undef */
|
|
||||||
var reader = new FileReader();
|
var reader = new FileReader();
|
||||||
/* eslint-enable no-undef */
|
|
||||||
reader.onload = function () {
|
reader.onload = function () {
|
||||||
log('FileReader.readAsDataURL() - length = ' + reader.result.length);
|
log('FileReader.readAsDataURL() - length = ' + reader.result.length);
|
||||||
};
|
};
|
||||||
reader.onerror = logCallback('FileReader.readAsDataURL', false);
|
reader.onerror = logCallback('FileReader.readAsDataURL', false);
|
||||||
reader.onloadend = onFileReadAsDataURL;
|
|
||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
}
|
};
|
||||||
|
|
||||||
// Test out onFileReceived when the file object was set via a native <input> elements.
|
// Test out onFileReceived when the file object was set via a native <input> elements.
|
||||||
if (fileObj) {
|
if (fileObj) {
|
||||||
onFileReceived(fileObj);
|
onFileReceived(fileObj);
|
||||||
@ -227,20 +226,19 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
fileEntry.file(onFileReceived, logCallback('FileEntry.file', false));
|
fileEntry.file(onFileReceived, logCallback('FileEntry.file', false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function getFileInfo() {
|
||||||
function getFileInfo () {
|
|
||||||
// Test FileEntry API here.
|
// Test FileEntry API here.
|
||||||
fileEntry.getMetadata(logCallback('FileEntry.getMetadata', true), logCallback('FileEntry.getMetadata', false));
|
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.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));
|
||||||
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
|
* Copy image from library using a NATIVE_URI destination type
|
||||||
* This calls FileEntry.copyTo and FileEntry.moveTo.
|
* This calls FileEntry.copyTo and FileEntry.moveTo.
|
||||||
*/
|
*/
|
||||||
function copyImage () {
|
function copyImage() {
|
||||||
var onFileSystemReceived = function (fileSystem) {
|
var onFileSystemReceived = function (fileSystem) {
|
||||||
var destDirEntry = fileSystem.root;
|
var destDirEntry = fileSystem.root;
|
||||||
var origName = fileEntry.name;
|
var origName = fileEntry.name;
|
||||||
@ -249,17 +247,17 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
fileEntry.copyTo(destDirEntry, 'copied_file.png', logCallback('FileEntry.copyTo', true), logCallback('FileEntry.copyTo', false));
|
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));
|
fileEntry.moveTo(destDirEntry, 'moved_file.png', logCallback('FileEntry.moveTo', true), logCallback('FileEntry.moveTo', false));
|
||||||
|
|
||||||
// cleanup
|
//cleanup
|
||||||
// rename moved file back to original name so other tests can reference image
|
//rename moved file back to original name so other tests can reference image
|
||||||
resolveLocalFileSystemURL(destDirEntry.nativeURL + 'moved_file.png', function (fileEntry) {
|
resolveLocalFileSystemURI(destDirEntry.nativeURL+'moved_file.png', function(fileEntry) {
|
||||||
fileEntry.moveTo(destDirEntry, origName, logCallback('FileEntry.moveTo', true), logCallback('FileEntry.moveTo', false));
|
fileEntry.moveTo(destDirEntry, origName, logCallback('FileEntry.moveTo', true), logCallback('FileEntry.moveTo', false));
|
||||||
console.log('Cleanup: successfully renamed file back to original name');
|
console.log('Cleanup: successfully renamed file back to original name');
|
||||||
}, function () {
|
}, function () {
|
||||||
console.log('Cleanup: failed to rename file back to original name');
|
console.log('Cleanup: failed to rename file back to original name');
|
||||||
});
|
});
|
||||||
|
|
||||||
// remove copied file
|
//remove copied file
|
||||||
resolveLocalFileSystemURL(destDirEntry.nativeURL + 'copied_file.png', function (fileEntry) {
|
resolveLocalFileSystemURI(destDirEntry.nativeURL+'copied_file.png', function(fileEntry) {
|
||||||
fileEntry.remove(logCallback('FileEntry.remove', true), logCallback('FileEntry.remove', false));
|
fileEntry.remove(logCallback('FileEntry.remove', true), logCallback('FileEntry.remove', false));
|
||||||
console.log('Cleanup: successfully removed copied file');
|
console.log('Cleanup: successfully removed copied file');
|
||||||
}, function () {
|
}, function () {
|
||||||
@ -268,17 +266,17 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, onFileSystemReceived, null);
|
window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, onFileSystemReceived, null);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write image to library using a NATIVE_URI destination type
|
* Write image to library using a NATIVE_URI destination type
|
||||||
* This calls FileEntry.createWriter, FileWriter.write, and FileWriter.truncate.
|
* This calls FileEntry.createWriter, FileWriter.write, and FileWriter.truncate.
|
||||||
*/
|
*/
|
||||||
function writeImage () {
|
function writeImage() {
|
||||||
var onFileWriterReceived = function (fileWriter) {
|
var onFileWriterReceived = function (fileWriter) {
|
||||||
fileWriter.onwrite = logCallback('FileWriter.write', true);
|
fileWriter.onwrite = logCallback('FileWriter.write', true);
|
||||||
fileWriter.onerror = logCallback('FileWriter.write', false);
|
fileWriter.onerror = logCallback('FileWriter.write', false);
|
||||||
fileWriter.write('some text!');
|
fileWriter.write("some text!");
|
||||||
};
|
};
|
||||||
|
|
||||||
var onFileTruncateWriterReceived = function (fileWriter) {
|
var onFileTruncateWriterReceived = function (fileWriter) {
|
||||||
@ -289,9 +287,9 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
|
|
||||||
fileEntry.createWriter(onFileWriterReceived, logCallback('FileEntry.createWriter', false));
|
fileEntry.createWriter(onFileWriterReceived, logCallback('FileEntry.createWriter', false));
|
||||||
fileEntry.createWriter(onFileTruncateWriterReceived, null);
|
fileEntry.createWriter(onFileTruncateWriterReceived, null);
|
||||||
}
|
};
|
||||||
|
|
||||||
function displayImageUsingCanvas () {
|
function displayImageUsingCanvas() {
|
||||||
var canvas = document.getElementById('canvas');
|
var canvas = document.getElementById('canvas');
|
||||||
var img = document.getElementById('camera_image');
|
var img = document.getElementById('camera_image');
|
||||||
var w = img.width;
|
var w = img.width;
|
||||||
@ -302,27 +300,26 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
canvas.height = h;
|
canvas.height = h;
|
||||||
var context = canvas.getContext('2d');
|
var context = canvas.getContext('2d');
|
||||||
context.drawImage(img, 0, 0, w, h);
|
context.drawImage(img, 0, 0, w, h);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove image from library using a NATIVE_URI destination type
|
* Remove image from library using a NATIVE_URI destination type
|
||||||
* This calls FileEntry.remove.
|
* This calls FileEntry.remove.
|
||||||
*/
|
*/
|
||||||
function removeImage () {
|
function removeImage() {
|
||||||
fileEntry.remove(logCallback('FileEntry.remove', true), logCallback('FileEntry.remove', false));
|
fileEntry.remove(logCallback('FileEntry.remove', true), logCallback('FileEntry.remove', false));
|
||||||
}
|
};
|
||||||
|
|
||||||
function testInputTag (inputEl) {
|
function testInputTag(inputEl) {
|
||||||
clearStatus();
|
clearStatus();
|
||||||
// iOS 6 likes to dead-lock in the onchange context if you
|
// iOS 6 likes to dead-lock in the onchange context if you
|
||||||
// do any alerts or try to remote-debug.
|
// do any alerts or try to remote-debug.
|
||||||
window.setTimeout(function () {
|
window.setTimeout(function () {
|
||||||
testNativeFile2(inputEl);
|
testNativeFile2(inputEl);
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
};
|
||||||
|
|
||||||
function testNativeFile2 (inputEl) {
|
function testNativeFile2(inputEl) {
|
||||||
/* eslint-disable no-undef */
|
|
||||||
if (!inputEl.value) {
|
if (!inputEl.value) {
|
||||||
alert('No file selected.');
|
alert('No file selected.');
|
||||||
return;
|
return;
|
||||||
@ -332,7 +329,6 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
alert('Got value but no file.');
|
alert('Got value but no file.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* eslint-enable no-undef */
|
|
||||||
var URLApi = window.URL || window.webkitURL;
|
var URLApi = window.URL || window.webkitURL;
|
||||||
if (URLApi) {
|
if (URLApi) {
|
||||||
var blobURL = URLApi.createObjectURL(fileObj);
|
var blobURL = URLApi.createObjectURL(fileObj);
|
||||||
@ -348,42 +344,38 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractOptions () {
|
function extractOptions() {
|
||||||
var els = document.querySelectorAll('#image-options select');
|
var els = document.querySelectorAll('#image-options select');
|
||||||
var ret = {};
|
var ret = {};
|
||||||
/* eslint-disable no-cond-assign */
|
|
||||||
for (var i = 0, el; el = els[i]; ++i) {
|
for (var i = 0, el; el = els[i]; ++i) {
|
||||||
var value = el.value;
|
var value = el.value;
|
||||||
if (value === '') continue;
|
if (value === '') continue;
|
||||||
value = +value;
|
|
||||||
|
|
||||||
if (el.isBool) {
|
if (el.isBool) {
|
||||||
ret[el.getAttribute('name')] = !!value;
|
ret[el.getAttribute("name")] = !!+value;
|
||||||
} else {
|
} else {
|
||||||
ret[el.getAttribute('name')] = value;
|
ret[el.getAttribute("name")] = +value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* eslint-enable no-cond-assign */
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createOptionsEl (name, values, selectionDefault) {
|
function createOptionsEl(name, values, selectionDefault) {
|
||||||
var openDiv = '<div style="display: inline-block">' + name + ': ';
|
var openDiv = '<div style="display: inline-block">' + name + ': ';
|
||||||
var select = '<select name=' + name + ' id="' + name + '">';
|
var select = '<select name=' + name + '>';
|
||||||
|
|
||||||
var defaultOption = '';
|
var defaultOption = '';
|
||||||
if (selectionDefault === undefined) {
|
if (selectionDefault == undefined) {
|
||||||
defaultOption = '<option value="">default</option>';
|
defaultOption = '<option value="">default</option>';
|
||||||
}
|
}
|
||||||
|
|
||||||
var options = '';
|
var options = '';
|
||||||
if (typeof values === 'boolean') {
|
if (typeof values == 'boolean') {
|
||||||
values = { 'true': 1, 'false': 0 };
|
values = { 'true': 1, 'false': 0 };
|
||||||
}
|
}
|
||||||
for (var k in values) {
|
for (var k in values) {
|
||||||
var isSelected = '';
|
var isSelected = '';
|
||||||
if (selectionDefault) {
|
if (selectionDefault) {
|
||||||
if (selectionDefault[0] === k) {
|
if (selectionDefault[0] == k) {
|
||||||
isSelected = 'selected';
|
isSelected = 'selected';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -402,8 +394,8 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
'<b>Status:</b> <div id="camera_status"></div>' +
|
'<b>Status:</b> <div id="camera_status"></div>' +
|
||||||
'img: <img width="100" id="camera_image">' +
|
'img: <img width="100" id="camera_image">' +
|
||||||
'canvas: <canvas id="canvas" width="1" height="1"></canvas>' +
|
'canvas: <canvas id="canvas" width="1" height="1"></canvas>' +
|
||||||
'</div>';
|
'</div>',
|
||||||
var options_div = '<h2>Cordova Camera API Options</h2>' +
|
options_div = '<h2>Cordova Camera API Options</h2>' +
|
||||||
'<div id="image-options">' +
|
'<div id="image-options">' +
|
||||||
createOptionsEl('sourceType', Camera.PictureSourceType, camPictureSourceTypeDefault) +
|
createOptionsEl('sourceType', Camera.PictureSourceType, camPictureSourceTypeDefault) +
|
||||||
createOptionsEl('destinationType', Camera.DestinationType, camDestinationTypeDefault) +
|
createOptionsEl('destinationType', Camera.DestinationType, camDestinationTypeDefault) +
|
||||||
@ -416,9 +408,9 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
createOptionsEl('correctOrientation', true, camCorrectOrientationDefault) +
|
createOptionsEl('correctOrientation', true, camCorrectOrientationDefault) +
|
||||||
createOptionsEl('saveToPhotoAlbum', true, camSaveToPhotoAlbumDefault) +
|
createOptionsEl('saveToPhotoAlbum', true, camSaveToPhotoAlbumDefault) +
|
||||||
createOptionsEl('cameraDirection', Camera.Direction) +
|
createOptionsEl('cameraDirection', Camera.Direction) +
|
||||||
'</div>';
|
'</div>',
|
||||||
var getpicture_div = '<div id="getpicture"></div>';
|
getpicture_div = '<div id="getpicture"></div>',
|
||||||
var test_procedure = '<h4>Recommended Test Procedure</h4>' +
|
test_procedure = '<h4>Recommended Test Procedure</h4>' +
|
||||||
'Options not specified should be the default value' +
|
'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' +
|
'<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">' +
|
'</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">' +
|
||||||
@ -431,14 +423,14 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
'</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=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>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>' +
|
'</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>';
|
'</ol></div>',
|
||||||
var inputs_div = '<h2>Native File Inputs</h2>' +
|
inputs_div = '<h2>Native File Inputs</h2>' +
|
||||||
'For the following tests, status box should update with file selected' +
|
'For the following tests, status box should update with file selected' +
|
||||||
'</p><div>input type=file <input type="file" class="testInputTag"></div>' +
|
'</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=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=camcorder <input type="file" accept="video/*;capture=camcorder" class="testInputTag"></div>' +
|
||||||
'<div>capture=microphone <input type="file" accept="audio/*;capture=microphone" class="testInputTag"></div>';
|
'<div>capture=microphone <input type="file" accept="audio/*;capture=microphone" class="testInputTag"></div>',
|
||||||
var actions_div = '<h2>Actions</h2>' +
|
actions_div = '<h2>Actions</h2>' +
|
||||||
'For the following tests, ensure that an image is set in status box' +
|
'For the following tests, ensure that an image is set in status box' +
|
||||||
'</p><div id="metadata"></div>' +
|
'</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"' +
|
'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"' +
|
||||||
@ -458,20 +450,20 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
// We need to wrap this code due to Windows security restrictions
|
// 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
|
// see http://msdn.microsoft.com/en-us/library/windows/apps/hh465380.aspx#differences for details
|
||||||
if (window.MSApp && window.MSApp.execUnsafeLocalFunction) {
|
if (window.MSApp && window.MSApp.execUnsafeLocalFunction) {
|
||||||
MSApp.execUnsafeLocalFunction(function () {
|
MSApp.execUnsafeLocalFunction(function() {
|
||||||
contentEl.innerHTML = info_div + options_div + getpicture_div + test_procedure + inputs_div + actions_div;
|
contentEl.innerHTML = info_div + options_div + getpicture_div + test_procedure + inputs_div + actions_div;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
contentEl.innerHTML = info_div + options_div + getpicture_div + test_procedure + inputs_div + actions_div;
|
contentEl.innerHTML = info_div + options_div + getpicture_div + test_procedure + inputs_div + actions_div;
|
||||||
}
|
}
|
||||||
|
|
||||||
var elements = document.getElementsByClassName('testInputTag');
|
var elements = document.getElementsByClassName("testInputTag");
|
||||||
var listener = function (e) {
|
var listener = function (e) {
|
||||||
testInputTag(e.target);
|
testInputTag(e.target);
|
||||||
};
|
}
|
||||||
for (var i = 0; i < elements.length; ++i) {
|
for (var i = 0; i < elements.length; ++i) {
|
||||||
var item = elements[i];
|
var item = elements[i];
|
||||||
item.addEventListener('change', listener, false);
|
item.addEventListener("change", listener, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
createActionButton('Get picture', function () {
|
createActionButton('Get picture', function () {
|
||||||
|
180
types/index.d.ts
vendored
@ -1,180 +0,0 @@
|
|||||||
// Type definitions for Apache Cordova Camera plugin
|
|
||||||
// Project: https://github.com/apache/cordova-plugin-camera
|
|
||||||
// Definitions by: Microsoft Open Technologies Inc <http://msopentech.com>
|
|
||||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
|
||||||
//
|
|
||||||
// Copyright (c) Microsoft Open Technologies Inc
|
|
||||||
// Licensed under the MIT license.
|
|
||||||
|
|
||||||
interface Navigator {
|
|
||||||
/**
|
|
||||||
* This plugin provides an API for taking pictures and for choosing images from the system's image library.
|
|
||||||
*/
|
|
||||||
camera: Camera;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This plugin provides an API for taking pictures and for choosing images from the system's image library.
|
|
||||||
*/
|
|
||||||
interface Camera {
|
|
||||||
/**
|
|
||||||
* Removes intermediate photos taken by the camera from temporary storage.
|
|
||||||
* @param onSuccess Success callback, that called when cleanup succeeds.
|
|
||||||
* @param onError Error callback, that get an error message.
|
|
||||||
*/
|
|
||||||
cleanup(
|
|
||||||
onSuccess: () => void,
|
|
||||||
onError: (message: string) => void): void;
|
|
||||||
/**
|
|
||||||
* Takes a photo using the camera, or retrieves a photo from the device's image gallery.
|
|
||||||
* @param cameraSuccess Success callback, that get the image
|
|
||||||
* as a base64-encoded String, or as the URI for the image file.
|
|
||||||
* @param cameraError Error callback, that get an error message.
|
|
||||||
* @param cameraOptions Optional parameters to customize the camera settings.
|
|
||||||
*/
|
|
||||||
getPicture(
|
|
||||||
cameraSuccess: (data: string) => void,
|
|
||||||
cameraError: (message: string) => void,
|
|
||||||
cameraOptions?: CameraOptions): void;
|
|
||||||
// Next will work only on iOS
|
|
||||||
//getPicture(
|
|
||||||
// cameraSuccess: (data: string) => void,
|
|
||||||
// cameraError: (message: string) => void,
|
|
||||||
// cameraOptions?: CameraOptions): CameraPopoverHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CameraOptions {
|
|
||||||
/** Picture quality in range 0-100. Default is 50 */
|
|
||||||
quality?: number;
|
|
||||||
/**
|
|
||||||
* Choose the format of the return value.
|
|
||||||
* Defined in navigator.camera.DestinationType. Default is FILE_URI.
|
|
||||||
* 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)
|
|
||||||
*/
|
|
||||||
destinationType?: number;
|
|
||||||
/**
|
|
||||||
* Set the source of the picture.
|
|
||||||
* Defined in navigator.camera.PictureSourceType. Default is CAMERA.
|
|
||||||
* PHOTOLIBRARY : 0,
|
|
||||||
* CAMERA : 1,
|
|
||||||
* SAVEDPHOTOALBUM : 2
|
|
||||||
*/
|
|
||||||
sourceType?: number;
|
|
||||||
/** Allow simple editing of image before selection. */
|
|
||||||
allowEdit?: boolean;
|
|
||||||
/**
|
|
||||||
* Choose the returned image file's encoding.
|
|
||||||
* Defined in navigator.camera.EncodingType. Default is JPEG
|
|
||||||
* JPEG : 0 Return JPEG encoded image
|
|
||||||
* PNG : 1 Return PNG encoded image
|
|
||||||
*/
|
|
||||||
encodingType?: number;
|
|
||||||
/**
|
|
||||||
* Width in pixels to scale image. Must be used with targetHeight.
|
|
||||||
* Aspect ratio remains constant.
|
|
||||||
*/
|
|
||||||
targetWidth?: number;
|
|
||||||
/**
|
|
||||||
* Height in pixels to scale image. Must be used with targetWidth.
|
|
||||||
* Aspect ratio remains constant.
|
|
||||||
*/
|
|
||||||
targetHeight?: number;
|
|
||||||
/**
|
|
||||||
* Set the type of media to select from. Only works when PictureSourceType
|
|
||||||
* is PHOTOLIBRARY or SAVEDPHOTOALBUM. Defined in nagivator.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
|
|
||||||
*/
|
|
||||||
mediaType?: number;
|
|
||||||
/** Rotate the image to correct for the orientation of the device during capture. */
|
|
||||||
correctOrientation?: boolean;
|
|
||||||
/** Save the image to the photo album on the device after capture. */
|
|
||||||
saveToPhotoAlbum?: boolean;
|
|
||||||
/**
|
|
||||||
* Choose the camera to use (front- or back-facing).
|
|
||||||
* Defined in navigator.camera.Direction. Default is BACK.
|
|
||||||
* FRONT: 0
|
|
||||||
* BACK: 1
|
|
||||||
*/
|
|
||||||
cameraDirection?: number;
|
|
||||||
/** iOS-only options that specify popover location in iPad. Defined in CameraPopoverOptions. */
|
|
||||||
popoverOptions?: CameraPopoverOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A handle to the popover dialog created by navigator.camera.getPicture. Used on iOS only.
|
|
||||||
*/
|
|
||||||
interface CameraPopoverHandle {
|
|
||||||
/**
|
|
||||||
* Set the position of the popover.
|
|
||||||
* @param popoverOptions the CameraPopoverOptions that specify the new position.
|
|
||||||
*/
|
|
||||||
setPosition(popoverOptions: CameraPopoverOptions): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
interface CameraPopoverOptions {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
/**
|
|
||||||
* Direction the arrow on the popover should point. Defined in Camera.PopoverArrowDirection
|
|
||||||
* Matches iOS UIPopoverArrowDirection constants.
|
|
||||||
* ARROW_UP : 1,
|
|
||||||
* ARROW_DOWN : 2,
|
|
||||||
* ARROW_LEFT : 4,
|
|
||||||
* ARROW_RIGHT : 8,
|
|
||||||
* ARROW_ANY : 15
|
|
||||||
*/
|
|
||||||
arrowDir : number;
|
|
||||||
popoverWidth: number;
|
|
||||||
popoverHeight: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare class CameraPopoverOptions implements CameraPopoverOptions {
|
|
||||||
constructor(x?: number, y?: number, width?: number, height?: number, arrowDir?: number);
|
|
||||||
}
|
|
||||||
|
|
||||||
declare var Camera: {
|
|
||||||
// Camera constants, defined in Camera plugin
|
|
||||||
DestinationType: {
|
|
||||||
DATA_URL: number;
|
|
||||||
FILE_URI: number;
|
|
||||||
NATIVE_URI: number
|
|
||||||
}
|
|
||||||
Direction: {
|
|
||||||
BACK: number;
|
|
||||||
FRONT: number;
|
|
||||||
}
|
|
||||||
EncodingType: {
|
|
||||||
JPEG: number;
|
|
||||||
PNG: number;
|
|
||||||
}
|
|
||||||
MediaType: {
|
|
||||||
PICTURE: number;
|
|
||||||
VIDEO: number;
|
|
||||||
ALLMEDIA: number;
|
|
||||||
}
|
|
||||||
PictureSourceType: {
|
|
||||||
PHOTOLIBRARY: number;
|
|
||||||
CAMERA: number;
|
|
||||||
SAVEDPHOTOALBUM: number;
|
|
||||||
}
|
|
||||||
// Used only on iOS
|
|
||||||
PopoverArrowDirection: {
|
|
||||||
ARROW_UP: number;
|
|
||||||
ARROW_DOWN: number;
|
|
||||||
ARROW_LEFT: number;
|
|
||||||
ARROW_RIGHT: number;
|
|
||||||
ARROW_ANY: number;
|
|
||||||
}
|
|
||||||
};
|
|
148
www/Camera.js
@ -19,19 +19,12 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var argscheck = require('cordova/argscheck');
|
var argscheck = require('cordova/argscheck'),
|
||||||
var exec = require('cordova/exec');
|
exec = require('cordova/exec'),
|
||||||
var Camera = require('./Camera');
|
Camera = require('./Camera');
|
||||||
// XXX: commented out
|
// XXX: commented out
|
||||||
// CameraPopoverHandle = require('./CameraPopoverHandle');
|
//CameraPopoverHandle = require('./CameraPopoverHandle');
|
||||||
|
|
||||||
/**
|
|
||||||
* @namespace navigator
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @exports camera
|
|
||||||
*/
|
|
||||||
var cameraExport = {};
|
var cameraExport = {};
|
||||||
|
|
||||||
// Tack on the Camera Constants to the base camera plugin.
|
// Tack on the Camera Constants to the base camera plugin.
|
||||||
@ -40,103 +33,21 @@ for (var key in Camera) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback function that provides an error message.
|
* Gets a picture from source defined by "options.sourceType", and returns the
|
||||||
* @callback module:camera.onError
|
* image as defined by the "options.destinationType" option.
|
||||||
* @param {string} message - The message is provided by the device's native code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
* The defaults are sourceType=CAMERA and destinationType=FILE_URI.
|
||||||
* Callback function that provides the image data.
|
*
|
||||||
* @callback module:camera.onSuccess
|
* @param {Function} successCallback
|
||||||
* @param {string} imageData - Base64 encoding of the image data, _or_ the image file URI, depending on [`cameraOptions`]{@link module:camera.CameraOptions} in effect.
|
* @param {Function} errorCallback
|
||||||
* @example
|
* @param {Object} options
|
||||||
* // Show image
|
|
||||||
* //
|
|
||||||
* function cameraCallback(imageData) {
|
|
||||||
* var image = document.getElementById('myImage');
|
|
||||||
* image.src = "data:image/jpeg;base64," + imageData;
|
|
||||||
* }
|
|
||||||
*/
|
*/
|
||||||
|
cameraExport.getPicture = function(successCallback, errorCallback, options) {
|
||||||
/**
|
|
||||||
* Optional parameters to customize the camera settings.
|
|
||||||
* * [Quirks](#CameraOptions-quirks)
|
|
||||||
* @typedef module:camera.CameraOptions
|
|
||||||
* @type {Object}
|
|
||||||
* @property {number} [quality=50] - Quality of the saved image, expressed as a range of 0-100, where 100 is typically full resolution with no loss from file compression. (Note that information about the camera's resolution is unavailable.)
|
|
||||||
* @property {module:Camera.DestinationType} [destinationType=FILE_URI] - Choose the format of the return value.
|
|
||||||
* @property {module:Camera.PictureSourceType} [sourceType=CAMERA] - Set the source of the picture.
|
|
||||||
* @property {Boolean} [allowEdit=false] - Allow simple editing of image before selection.
|
|
||||||
* @property {module:Camera.EncodingType} [encodingType=JPEG] - Choose the returned image file's encoding.
|
|
||||||
* @property {number} [targetWidth] - Width in pixels to scale image. Must be used with `targetHeight`. Aspect ratio remains constant.
|
|
||||||
* @property {number} [targetHeight] - Height in pixels to scale image. Must be used with `targetWidth`. Aspect ratio remains constant.
|
|
||||||
* @property {module:Camera.MediaType} [mediaType=PICTURE] - Set the type of media to select from. Only works when `PictureSourceType` is `PHOTOLIBRARY` or `SAVEDPHOTOALBUM`.
|
|
||||||
* @property {Boolean} [correctOrientation] - Rotate the image to correct for the orientation of the device during capture.
|
|
||||||
* @property {Boolean} [saveToPhotoAlbum] - Save the image to the photo album on the device after capture.
|
|
||||||
* @property {module:CameraPopoverOptions} [popoverOptions] - iOS-only options that specify popover location in iPad.
|
|
||||||
* @property {module:Camera.Direction} [cameraDirection=BACK] - Choose the camera to use (front- or back-facing).
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 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 `camera.getPicture` function opens the device's default camera
|
|
||||||
* application that allows users to snap pictures by default - this behavior occurs,
|
|
||||||
* when `Camera.sourceType` equals [`Camera.PictureSourceType.CAMERA`]{@link module:Camera.PictureSourceType}.
|
|
||||||
* 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 return value is sent to the [`cameraSuccess`]{@link module:camera.onSuccess} 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__
|
|
||||||
*
|
|
||||||
* - Android
|
|
||||||
* - BlackBerry
|
|
||||||
* - Browser
|
|
||||||
* - Firefox
|
|
||||||
* - FireOS
|
|
||||||
* - iOS
|
|
||||||
* - Windows
|
|
||||||
* - WP8
|
|
||||||
* - Ubuntu
|
|
||||||
*
|
|
||||||
* More examples [here](#camera-getPicture-examples). Quirks [here](#camera-getPicture-quirks).
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* navigator.camera.getPicture(cameraSuccess, cameraError, cameraOptions);
|
|
||||||
* @param {module:camera.onSuccess} successCallback
|
|
||||||
* @param {module:camera.onError} errorCallback
|
|
||||||
* @param {module:camera.CameraOptions} options CameraOptions
|
|
||||||
*/
|
|
||||||
cameraExport.getPicture = function (successCallback, errorCallback, options) {
|
|
||||||
argscheck.checkArgs('fFO', 'Camera.getPicture', arguments);
|
argscheck.checkArgs('fFO', 'Camera.getPicture', arguments);
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var getValue = argscheck.getValue;
|
var getValue = argscheck.getValue;
|
||||||
|
|
||||||
var quality = getValue(options.quality, 100);
|
var quality = getValue(options.quality, 50);
|
||||||
var destinationType = getValue(options.destinationType, Camera.DestinationType.FILE_URI);
|
var destinationType = getValue(options.destinationType, Camera.DestinationType.FILE_URI);
|
||||||
var sourceType = getValue(options.sourceType, Camera.PictureSourceType.CAMERA);
|
var sourceType = getValue(options.sourceType, Camera.PictureSourceType.CAMERA);
|
||||||
var targetWidth = getValue(options.targetWidth, -1);
|
var targetWidth = getValue(options.targetWidth, -1);
|
||||||
@ -150,36 +61,15 @@ cameraExport.getPicture = function (successCallback, errorCallback, options) {
|
|||||||
var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
|
var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
|
||||||
|
|
||||||
var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
|
var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
|
||||||
mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
|
mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
|
||||||
|
|
||||||
exec(successCallback, errorCallback, 'Camera', 'takePicture', args);
|
exec(successCallback, errorCallback, "Camera", "takePicture", args);
|
||||||
// XXX: commented out
|
// XXX: commented out
|
||||||
// return new CameraPopoverHandle();
|
//return new CameraPopoverHandle();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
cameraExport.cleanup = function(successCallback, errorCallback) {
|
||||||
* Removes intermediate image files that are kept in temporary storage
|
exec(successCallback, errorCallback, "Camera", "cleanup", []);
|
||||||
* after calling [`camera.getPicture`]{@link module: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);
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
cameraExport.cleanup = function (successCallback, errorCallback) {
|
|
||||||
exec(successCallback, errorCallback, 'Camera', 'cleanup', []);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = cameraExport;
|
module.exports = cameraExport;
|
||||||
|
@ -19,83 +19,35 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @module Camera
|
|
||||||
*/
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
/**
|
DestinationType:{
|
||||||
* @description
|
DATA_URL: 0, // Return base64 encoded string
|
||||||
* Defines the output format of `Camera.getPicture` call.
|
FILE_URI: 1, // Return file uri (content://media/external/images/media/2 for Android)
|
||||||
* _Note:_ On iOS passing `DestinationType.NATIVE_URI` along with
|
NATIVE_URI: 2 // Return native uri (eg. asset-library://... for iOS)
|
||||||
* `PictureSourceType.PHOTOLIBRARY` or `PictureSourceType.SAVEDPHOTOALBUM` will
|
},
|
||||||
* disable any image modifications (resize, quality change, cropping, etc.) due
|
EncodingType:{
|
||||||
* to implementation specific.
|
JPEG: 0, // Return JPEG encoded image
|
||||||
*
|
PNG: 1 // Return PNG encoded image
|
||||||
* @enum {number}
|
},
|
||||||
*/
|
MediaType:{
|
||||||
DestinationType: {
|
PICTURE: 0, // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
|
||||||
/** Return base64 encoded string. DATA_URL can be very memory intensive and cause app crashes or out of memory errors. Use FILE_URI or NATIVE_URI if possible */
|
VIDEO: 1, // allow selection of video only, ONLY RETURNS URL
|
||||||
DATA_URL: 0,
|
ALLMEDIA : 2 // allow selection from all media types
|
||||||
/** Return file uri (content://media/external/images/media/2 for Android) */
|
},
|
||||||
FILE_URI: 1,
|
PictureSourceType:{
|
||||||
/** Return native uri (eg. asset-library://... for iOS) */
|
PHOTOLIBRARY : 0, // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
|
||||||
NATIVE_URI: 2
|
CAMERA : 1, // Take picture from camera
|
||||||
},
|
SAVEDPHOTOALBUM : 2 // Choose image from picture library (same as PHOTOLIBRARY for Android)
|
||||||
/**
|
},
|
||||||
* @enum {number}
|
PopoverArrowDirection:{
|
||||||
*/
|
ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover
|
||||||
EncodingType: {
|
ARROW_DOWN : 2,
|
||||||
/** Return JPEG encoded image */
|
ARROW_LEFT : 4,
|
||||||
JPEG: 0,
|
ARROW_RIGHT : 8,
|
||||||
/** Return PNG encoded image */
|
ARROW_ANY : 15
|
||||||
PNG: 1
|
},
|
||||||
},
|
Direction:{
|
||||||
/**
|
BACK: 0,
|
||||||
* @enum {number}
|
FRONT: 1
|
||||||
*/
|
}
|
||||||
MediaType: {
|
|
||||||
/** Allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType */
|
|
||||||
PICTURE: 0,
|
|
||||||
/** Allow selection of video only, ONLY RETURNS URL */
|
|
||||||
VIDEO: 1,
|
|
||||||
/** Allow selection from all media types */
|
|
||||||
ALLMEDIA: 2
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @description
|
|
||||||
* Defines the output format of `Camera.getPicture` call.
|
|
||||||
* _Note:_ On iOS passing `PictureSourceType.PHOTOLIBRARY` or `PictureSourceType.SAVEDPHOTOALBUM`
|
|
||||||
* along with `DestinationType.NATIVE_URI` will disable any image modifications (resize, quality
|
|
||||||
* change, cropping, etc.) due to implementation specific.
|
|
||||||
*
|
|
||||||
* @enum {number}
|
|
||||||
*/
|
|
||||||
PictureSourceType: {
|
|
||||||
/** Choose image from the device's photo library (same as SAVEDPHOTOALBUM for Android) */
|
|
||||||
PHOTOLIBRARY: 0,
|
|
||||||
/** Take picture from camera */
|
|
||||||
CAMERA: 1,
|
|
||||||
/** Choose image only from the device's Camera Roll album (same as PHOTOLIBRARY for Android) */
|
|
||||||
SAVEDPHOTOALBUM: 2
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Matches iOS UIPopoverArrowDirection constants to specify arrow location on popover.
|
|
||||||
* @enum {number}
|
|
||||||
*/
|
|
||||||
PopoverArrowDirection: {
|
|
||||||
ARROW_UP: 1,
|
|
||||||
ARROW_DOWN: 2,
|
|
||||||
ARROW_LEFT: 4,
|
|
||||||
ARROW_RIGHT: 8,
|
|
||||||
ARROW_ANY: 15
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @enum {number}
|
|
||||||
*/
|
|
||||||
Direction: {
|
|
||||||
/** Use the back-facing camera */
|
|
||||||
BACK: 0,
|
|
||||||
/** Use the front-facing camera */
|
|
||||||
FRONT: 1
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
@ -19,12 +19,13 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var exec = require('cordova/exec');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ignore in favour of iOS' one
|
|
||||||
* A handle to an image picker popover.
|
* A handle to an image picker popover.
|
||||||
*/
|
*/
|
||||||
var CameraPopoverHandle = function () {
|
var CameraPopoverHandle = function() {
|
||||||
this.setPosition = function (popoverOptions) {
|
this.setPosition = function(popoverOptions) {
|
||||||
console.log('CameraPopoverHandle.setPosition is only supported on iOS.');
|
console.log('CameraPopoverHandle.setPosition is only supported on iOS.');
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -22,35 +22,16 @@
|
|||||||
var Camera = require('./Camera');
|
var Camera = require('./Camera');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @namespace navigator
|
* Encapsulates options for iOS Popover image picker
|
||||||
*/
|
*/
|
||||||
|
var CameraPopoverOptions = function(x,y,width,height,arrowDir){
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
* 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.
|
|
||||||
* @module CameraPopoverOptions
|
|
||||||
* @param {Number} [x=0] - x pixel coordinate of screen element onto which to anchor the popover.
|
|
||||||
* @param {Number} [y=32] - y pixel coordinate of screen element onto which to anchor the popover.
|
|
||||||
* @param {Number} [width=320] - width, in pixels, of the screen element onto which to anchor the popover.
|
|
||||||
* @param {Number} [height=480] - height, in pixels, of the screen element onto which to anchor the popover.
|
|
||||||
* @param {module:Camera.PopoverArrowDirection} [arrowDir=ARROW_ANY] - Direction the arrow on the popover should point.
|
|
||||||
* @param {Number} [popoverWidth=0] - width of the popover (0 or not specified will use apple's default width).
|
|
||||||
* @param {Number} [popoverHeight=0] - height of the popover (0 or not specified will use apple's default height).
|
|
||||||
*/
|
|
||||||
var CameraPopoverOptions = function (x, y, width, height, arrowDir, popoverWidth, popoverHeight) {
|
|
||||||
// information of rectangle that popover should be anchored to
|
// information of rectangle that popover should be anchored to
|
||||||
this.x = x || 0;
|
this.x = x || 0;
|
||||||
this.y = y || 32;
|
this.y = y || 32;
|
||||||
this.width = width || 320;
|
this.width = width || 320;
|
||||||
this.height = height || 480;
|
this.height = height || 480;
|
||||||
|
// The direction of the popover arrow
|
||||||
this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;
|
this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;
|
||||||
this.popoverWidth = popoverWidth || 0;
|
|
||||||
this.popoverHeight = popoverHeight || 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = CameraPopoverOptions;
|
module.exports = CameraPopoverOptions;
|
||||||
|
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
@ -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('org.apache.cordova.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('org.apache.cordova.camera', canvas.toDataURL('img/png'));
|
||||||
|
};
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
window.qnx.callExtensionMethod('org.apache.cordova.camera', 'error', 'getUserMedia failed');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
@ -21,45 +21,13 @@
|
|||||||
|
|
||||||
var exec = require('cordova/exec');
|
var exec = require('cordova/exec');
|
||||||
|
|
||||||
/**
|
|
||||||
* @namespace navigator
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A handle to an image picker popover.
|
* A handle to an image picker popover.
|
||||||
*
|
|
||||||
* __Supported Platforms__
|
|
||||||
*
|
|
||||||
* - iOS
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* 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, 300, 600)
|
|
||||||
* });
|
|
||||||
*
|
|
||||||
* // Reposition the popover if the orientation changes.
|
|
||||||
* window.onorientationchange = function() {
|
|
||||||
* var cameraPopoverHandle = new CameraPopoverHandle();
|
|
||||||
* var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY, 400, 500);
|
|
||||||
* cameraPopoverHandle.setPosition(cameraPopoverOptions);
|
|
||||||
* }
|
|
||||||
* @module CameraPopoverHandle
|
|
||||||
*/
|
*/
|
||||||
var CameraPopoverHandle = function () {
|
var CameraPopoverHandle = function() {
|
||||||
/**
|
this.setPosition = function(popoverOptions) {
|
||||||
* Can be used to reposition the image selection dialog,
|
|
||||||
* for example, when the device orientation changes.
|
|
||||||
* @memberof CameraPopoverHandle
|
|
||||||
* @instance
|
|
||||||
* @method setPosition
|
|
||||||
* @param {module:CameraPopoverOptions} popoverOptions
|
|
||||||
*/
|
|
||||||
this.setPosition = function (popoverOptions) {
|
|
||||||
var args = [ popoverOptions ];
|
var args = [ popoverOptions ];
|
||||||
exec(null, null, 'Camera', 'repositionPopover', args);
|
exec(null, null, "Camera", "repositionPopover", args);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|