Commit bd802492 by golton_gao

update: 移除cordova依赖, 优化构建流程

parent 1e69d795
Showing with 9 additions and 2273 deletions
......@@ -10,18 +10,6 @@ var webpack = require('webpack')
var config = require('../config')
var webpackConfig = require('./webpack.prod.conf')
// 设置package.json的name与version跟随config.xml里配置 @add by evanxu 2017-06-29
// 改变package版本号
var fs = require('fs')
var xml2js = require('xml2js')
var parser = new xml2js.Parser({explicitArray: false})
var versiony = require('versiony')
var xml = fs.readFileSync(process.cwd() + '/config.xml', {encoding: 'utf-8'}).toString()
parser.parseString(xml, (err, result) => {
if (err) throw err
versiony.version(result.widget.$.version).major().to('package.json')
})
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
......
......@@ -10,18 +10,6 @@ var webpack = require('webpack')
var config = require('../config')
var webpackConfig = require('./webpack.prov.conf')
// 设置package.json的name与version跟随config.xml里配置 @add by evanxu 2017-06-29
// 改变package版本号
var fs = require('fs')
var xml2js = require('xml2js')
var parser = new xml2js.Parser({explicitArray: false})
var versiony = require('versiony')
var xml = fs.readFileSync(process.cwd() + '/config.xml', {encoding: 'utf-8'}).toString()
parser.parseString(xml, (err, result) => {
if (err) throw err
versiony.version(result.widget.$.version).major().to('package.json')
})
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
......
......@@ -6,23 +6,6 @@ var baseWebpackConfig = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
// 设置package.json的name与version跟随config.xml里配置 @add by evanxu 2017-06-29
// 设置版本号、时间
var exdate = require('exdate')
var fs = require('fs')
var xml2js = require('xml2js')
var parser = new xml2js.Parser({explicitArray: false})
var xml = fs.readFileSync(process.cwd() + '/config.xml', {encoding: 'utf-8'}).toString()
var versions;
parser.parseString(xml, (err, result) => {
if (err) {
throw err
}
versions = result.widget.$.version
})
var ds = new Date()
var dates = exdate.format(ds, 'yyyy-MM-dd HH:mm')
// add hot-reload related code to entry chunks
Object.keys(baseWebpackConfig.entry).forEach(function (name) {
baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
......@@ -36,9 +19,7 @@ module.exports = merge(baseWebpackConfig, {
devtool: '#cheap-module-eval-source-map',
plugins: [
new webpack.DefinePlugin({
'process.env': config.dev.env,
'process.vers': JSON.stringify(versions),
'process.dates': JSON.stringify(dates)
'process.env': config.dev.env
}),
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.HotModuleReplacementPlugin(),
......
......@@ -9,23 +9,6 @@ var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
// 设置package.json的name与version跟随config.xml里配置 @add by evanxu 2017-06-29
// 设置版本号、时间
var exdate = require('exdate')
var fs = require('fs')
var xml2js = require('xml2js')
var parser = new xml2js.Parser({explicitArray: false})
var xml = fs.readFileSync(process.cwd() + '/config.xml', {encoding: 'utf-8'}).toString()
var versions;
parser.parseString(xml, (err, result) => {
if (err) {
throw err
}
versions = result.widget.$.version
})
var ds = new Date()
var dates = exdate.format(ds, 'yyyy-MM-dd HH:mm')
var env = config.build.env
var webpackConfig = merge(baseWebpackConfig, {
......@@ -45,8 +28,7 @@ var webpackConfig = merge(baseWebpackConfig, {
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env,
'process.vers': JSON.stringify(versions),
'process.dates': JSON.stringify(dates)
'process.env.PACK_ENV': JSON.stringify(process.env.PACK_ENV)
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
......
......@@ -10,22 +10,6 @@ var ExtractTextPlugin = require('extract-text-webpack-plugin')
var ZipPlugin = require('zip-webpack-plugin')
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
// 设置版本号、时间
var exdate = require('exdate')
var fs = require('fs')
var xml2js = require('xml2js')
var parser = new xml2js.Parser({explicitArray: false})
var xml = fs.readFileSync(process.cwd() + '/config.xml', {encoding: 'utf-8'}).toString()
var versions;
parser.parseString(xml, (err, result) => {
if (err) {
throw err
}
versions = result.widget.$.version
})
var ds = new Date()
var dates = exdate.format(ds, 'yyyy-MM-dd HH:mm')
var env = config.prov.env
var webpackConfig = merge(baseWebpackConfig, {
......@@ -45,8 +29,7 @@ var webpackConfig = merge(baseWebpackConfig, {
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env,
'process.vers': JSON.stringify(versions),
'process.dates': JSON.stringify(dates)
'process.env.PACK_ENV': JSON.stringify(process.env.PACK_ENV)
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
......
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.jffc.supplier" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name></name>
<description>
建发供方系统流程审批
</description>
<author email="chenwc@ppress.cn">
Ppress Team
</author>
<author email="caihg@ppress.cn">
Ppress Team
</author>
<author email="yuanxl@ppress.cn">
Ppress Team
</author>
<content src="index.html" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
<preference name="DisallowOverscroll" value="true" />
<preference name="BackupWebStorage" value="local" />
</platform>
<preference name="StatusBarBackgroundColor" value="#2c3e50" />
<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="FadeSplashScreen" value="false" />
<preference name="SplashScreenDelay" value="1000" />
<preference name="ShowSplashScreenSpinner" value="false" />
<engine name="android" />
<engine name="browser" />
<engine name="ios" />
<plugin name="cordova-plugin-camera">
<variable name="CAMERA_USAGE_DESCRIPTION" value=" " />
<variable name="PHOTOLIBRARY_USAGE_DESCRIPTION" value=" " />
</plugin>
<plugin name="cordova-plugin-console" />
<plugin name="cordova-plugin-device" />
<plugin name="cordova-plugin-dialogs" />
<plugin name="cordova-plugin-file" />
<plugin name="cordova-plugin-splashscreen" />
<plugin name="cordova-plugin-statusbar" />
<plugin name="cordova-plugin-whitelist" spec="1" />
<plugin name="cordova-sqlite-storage" />
</widget>
......@@ -7,7 +7,7 @@ module.exports = {
index: path.resolve(__dirname, '../www/index.html'),
assetsRoot: path.resolve(__dirname, '../www'),
assetsSubDirectory: 'static',
assetsPublicPath: '',
assetsPublicPath: '/',
productionSourceMap: true,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
......@@ -41,7 +41,7 @@ module.exports = {
index: path.resolve(__dirname, '../dist/index.html'),
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '',
assetsPublicPath: '/',
productionSourceMap: false,
appConfFile: 'CubeModule.json',
eslint: true,
......
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
-->
# Cordova Hooks
Cordova Hooks represent special scripts which could be added by application and plugin developers or even by your own build system to customize cordova commands. See Hooks Guide for more details: http://cordova.apache.org/docs/en/edge/guide_appdev_hooks_index.md.html#Hooks%20Guide.
{
"name": "cnd-plugin",
"version": "0.0.1",
"description": "Cordova C&D Plugin",
"cordova": {
"id": "cnd-plugin",
"platforms": [
"android",
"ios"
]
}
}
\ No newline at end of file
<?xml version='1.0' encoding='utf-8'?>
<plugin id="cnd-plugin" version="0.0.1" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>cnd-plugin</name>
<js-module name="YFPlugin" src="www/YFPlugin.js">
<clobbers target="cordova.plugins.YFPlugin" />
</js-module>
<platform name="android">
<config-file parent="/*" target="res/xml/config.xml">
<feature name="YFPlugin">
<param name="android-package" value="com.jffc.vcd.plugin.YFPlugin" />
</feature>
</config-file>
<config-file parent="/*" target="AndroidManifest.xml" />
<source-file src="src/android/YFPlugin.java" target-dir="src/com/jffc/vcd/plugin" />
</platform>
<platform name="ios">
<config-file parent="/*" target="config.xml">
<feature name="YFPlugin">
<param name="ios-package" value="YFPlugin" />
</feature>
</config-file>
<header-file src="src/ios/YFPlugin.h" />
<source-file src="src/ios/YFPlugin.m" />
</platform>
</plugin>
\ No newline at end of file
package com.jffc.vcd.plugin;
import android.util.Base64;
import android.util.Log;
import com.jffc.vcd.util.RouterHelper;
import com.jffc.vcd.util.SPHelper;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
/**
* 获取登录用户信息插件
*/
public class YFPlugin extends CordovaPlugin {
private static final String TAG = YFPlugin.class.getSimpleName();
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
Log.d(TAG,"YFPlugin Plugin execute: " + action);
if (action.equals("getUserInfo")){
this.getUserInfo(callbackContext);
return true;
}else if (action.equals("getHttpHeadValue")){
this.getHttpHeadValue(callbackContext);
return true;
}else if (action.equals("logoutSuccess")){
this.logoutSuccess();
return true;
}else if (action.equals("getHttpHost")){
this.getHttpHost(callbackContext);
return true;
}else if (action.equals("needLoadAllData")){
this.needLoadAllData(callbackContext);
return true;
}
return false;
}
/**
* 获取用户信息
* @param callbackContext
*/
private void getUserInfo(CallbackContext callbackContext){
callbackContext.success(SPHelper.getUserInfo());
}
/**
* 获取头部auth
* @param callbackContext
*/
private void getHttpHeadValue(CallbackContext callbackContext){
String userId = SPHelper.getUserId();
String password = SPHelper.getUserPassword();
StringBuilder sb = new StringBuilder();
sb.append("Basic ");
sb.append(new String(Base64.encode((userId + ":" + password).getBytes(),Base64.NO_WRAP)));
Log.d(TAG,"Authorization: " + sb.toString());
callbackContext.success(sb.toString());
}
/**
* 退出成功
*/
private void logoutSuccess(){
cordova.getActivity().finish();
SPHelper.setUserId("");
RouterHelper.gotoLogin();
}
/**
* 获取host:正式或测试
* @param callbackContext
*/
private void getHttpHost(CallbackContext callbackContext){
callbackContext.success(SPHelper.getHostApi());
}
/**
* 是否需要全量下载
* @param callbackContext
*/
private void needLoadAllData(CallbackContext callbackContext){
callbackContext.success(String.valueOf(SPHelper.isNewUser()));
}
}
//
// YFPlugin.h
// roomCheck
//
// Created by DevenChen on 2017/3/31.
//
//
#import <Foundation/Foundation.h>
#import <Cordova/CDVPlugin.h>
@interface YFPlugin : CDVPlugin
-(void)sayHello:(CDVInvokedUrlCommand *)command;
/**获取用户信息 */
- (void)getUserInfo:(CDVInvokedUrlCommand *)command;
/**是否需要全量下载 */
- (void)needLoadAllData:(CDVInvokedUrlCommand *)command;
/**退出成功 */
- (void)logoutSuccess:(CDVInvokedUrlCommand *)command;
/**获取host */
- (void)getHttpHost:(CDVInvokedUrlCommand *)command;
/**获取请求头 */
- (void)getHttpHeadValue:(CDVInvokedUrlCommand *)command;
@end
//
// YFPlugin.m
// roomCheck
//
// Created by DevenChen on 2017/3/31.
//
//
#import "YFPlugin.h"
#import "GVUserDefaults+YFProperty.h"
#import "AppDelegate.h"
#import "LoginVC.h"
@implementation YFPlugin
-(void)sayHello:(CDVInvokedUrlCommand *)command
{
//接收JS传过来的值
NSDictionary *options=[command argumentAtIndex:0 withDefault:nil];
//对应键名
NSString *curValue=options[@"quality"];
UIAlertView *myAlertView=[[UIAlertView alloc]initWithTitle:@"我是小实例" message:[NSString stringWithFormat:@"当前的内容从JS传过来的值为:%@",curValue] delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
[myAlertView show];
//数据回调
if ([curValue isEqualToString:@"200"]) {
curValue=@"201";
}
NSDictionary *userInfoDic = @{@"username":YFDefault.username,
@"userID":YFDefault.userID,
@"fid":YFDefault.fid,
@"cell":YFDefault.cell};
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:userInfoDic];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
/**获取用户信息 */
- (void)getUserInfo:(CDVInvokedUrlCommand *)command{
//数据回调
NSDictionary *userInfoDic = @{@"username":YFDefault.username,
@"userID":YFDefault.userID,
@"fid":YFDefault.fid,
@"cell":YFDefault.cell};
NSError *parseError = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:userInfoDic options:NSJSONWritingPrettyPrinted error:&parseError];
NSString *userInfoStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:userInfoStr];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
/**是否需要下载数据 */
- (void)needLoadAllData:(CDVInvokedUrlCommand *)command{
//数据回调
BOOL needLoadData = YFDefault.needLoadData;
CDVPluginResult *pluginResult=[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:needLoadData];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
if (YFDefault.needLoadData) {
YFDefault.needLoadData = NO;
}
}
/**退出成功 */
- (void)logoutSuccess:(CDVInvokedUrlCommand *)command{
//数据回调
CDVPluginResult *pluginResult=[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:YES];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
YFDefault.fid = nil;
YFDefault.userID = nil;
YFDefault.username = nil;
YFDefault.cell = nil;
YFDefault.needLoadData = YES;
// NSArray *cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies;
// for (int i = 0; i < [cookies count]; i++) {
// NSHTTPCookie *cookie = (NSHTTPCookie *)[cookies objectAtIndex:i];
// [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
// }
AppDelegate *delegate = [UIApplication sharedApplication].delegate;
delegate.window.rootViewController = [[UINavigationController alloc]initWithRootViewController:LoginVC.new];
}
/**获取host */
- (void)getHttpHost:(CDVInvokedUrlCommand *)command
{
//数据回调
CDVPluginResult *pluginResult=[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:YFDefault.default_host];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
/**获取请求头 */
- (void)getHttpHeadValue:(CDVInvokedUrlCommand *)command
{
//数据回调
CDVPluginResult *pluginResult=[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:YFDefault.basicAuthCode];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
@end
var exec = require('cordova/exec');
var YFPlugin = {
getUserInfo:function(success, error){
exec(success, error, "YFPlugin", "getUserInfo", []);
},
getHttpHeadValue:function(success, error){
exec(success, error, "YFPlugin", "getHttpHeadValue", []);
},
logoutSuccess:function(success, error){
exec(success, error, "YFPlugin", "logoutSuccess", []);
},
getHttpHost:function(success, error){
exec(success, error, "YFPlugin", "getHttpHost", []);
},
needLoadAllData:function(success, error){
exec(success, error, "YFPlugin", "needLoadAllData", []);
}
};
module.exports = YFPlugin;
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "Default-812h@3x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "Default-812h@3x-1.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "Default-568h@2x~iphone.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "Default-568h@2x~iphone-1.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "iphone",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "Default-667h.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
"filename" : "Default-667h-1.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "Default-736h.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "Default-736h-1.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
This diff could not be displayed because it is too large.
......@@ -7,33 +7,13 @@
"scripts": {
"dev": "node build/dev-server.js",
"start": "node build/dev-server.js",
"build": "node build/build.js",
"lint": "eslint --ext .js,.vue src",
"jffc-check": "cordova requirements",
"jffc-build": "node build/build.js",
"jffc-ios": "cordova build ios",
"jffc-android": "cordova build android",
"jffc-browser": "cordova prepare browser && cross-env PORT=3004 node build/dev-server.js",
"jffc-vbuild": "node build/vt-build.js",
"jffc-save": "cordova plugin save",
"jffc-add-ios": "cordova platforms add ios@4.4.0",
"jffc-add-android": "cordova platforms add android@6.2.3",
"jffc-add-browser": "cordova platforms add browser",
"jffc-add-camera": "cordova plugin add cordova-plugin-camera",
"jffc-add-console": "cordova plugin add cordova-plugin-console",
"jffc-add-device": "cordova plugin add cordova-plugin-device",
"jffc-add-sqlite": "cordova plugin add cordova-sqlite-storage",
"jffc-add-file": "cordova plugin add cordova-plugin-file",
"jffc-add-dialogs": "cordova plugin add cordova-plugin-dialogs",
"jffc-add-splashscreen": "cordova plugin add cordova-plugin-splashscreen",
"jffc-add-statusbar": "cordova plugin add cordova-plugin-statusbar"
"build": "npm run build:test",
"build:test": "cross-env PACK_ENV=test && node build/vt-build.js",
"build:prod": "cross-env PACK_ENV=prod && node build/vt-build.js"
},
"dependencies": {
"axios": "^0.19.0",
"babel-polyfill": "^6.23.0",
"cordova-plugin-whitelist": "1",
"exdate": "0.0.4",
"mockjs": "^1.0.1-beta3",
"vant": "^2.0.3",
"vue": "^2.3.3",
"vue-router": "^2.3.1",
......@@ -78,7 +58,6 @@
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"url-loader": "^0.5.8",
"versiony": "^2.0.1",
"vue-loader": "^12.1.0",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.3.3",
......@@ -87,7 +66,6 @@
"webpack-dev-middleware": "^1.10.0",
"webpack-hot-middleware": "^2.18.0",
"webpack-merge": "^4.1.0",
"xml2js": "^0.4.19",
"zip-webpack-plugin": "^1.1.0"
},
"engines": {
......@@ -98,26 +76,5 @@
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"cordova": {
"platforms": [
"android",
"browser",
"ios"
],
"plugins": {
"cordova-plugin-camera": {
"CAMERA_USAGE_DESCRIPTION": " ",
"PHOTOLIBRARY_USAGE_DESCRIPTION": " "
},
"cordova-plugin-console": {},
"cordova-plugin-device": {},
"cordova-plugin-dialogs": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-statusbar": {},
"cordova-plugin-whitelist": {},
"cordova-plugin-file": {},
"cordova-sqlite-storage": {}
}
}
]
}
{
"android": "6.1.2",
"ios": "4.3.1",
"browser": "4.1.0"
}
\ No newline at end of file
{
"prepare_queue": {
"installed": [],
"uninstalled": []
},
"config_munge": {
"files": {}
},
"installed_plugins": {
"cordova-plugin-whitelist": {
"PACKAGE_NAME": "com.jffc.vcd"
},
"cordova-plugin-camera": {
"PACKAGE_NAME": "com.jffc.vcd"
},
"cordova-plugin-statusbar": {
"PACKAGE_NAME": "com.jffc.vcd"
},
"cordova-plugin-splashscreen": {
"PACKAGE_NAME": "com.jffc.vcd"
},
"cordova-plugin-dialogs": {
"PACKAGE_NAME": "com.jffc.vcd"
},
"cordova-plugin-file": {
"PACKAGE_NAME": "com.jffc.vcd"
},
"cordova-sqlite-storage": {
"PACKAGE_NAME": "com.jffc.vcd"
},
"cordova-plugin-device": {
"PACKAGE_NAME": "com.jffc.vcd"
},
"cordova-plugin-console": {
"PACKAGE_NAME": "com.jffc.vcd"
}
},
"dependent_plugins": {
"cordova-plugin-compat": {
"PACKAGE_NAME": "com.jffc.vcd"
}
}
}
\ No newline at end of file
{
"prepare_queue": {
"installed": [],
"uninstalled": []
},
"config_munge": {
"files": {}
},
"installed_plugins": {
"cordova-plugin-whitelist": {
"PACKAGE_NAME": "com.jffc.vcd"
},
"cordova-plugin-camera": {
"PACKAGE_NAME": "com.jffc.vcd"
},
"cordova-plugin-statusbar": {
"PACKAGE_NAME": "com.jffc.vcd"
},
"cordova-plugin-splashscreen": {
"PACKAGE_NAME": "com.jffc.vcd"
},
"cordova-plugin-dialogs": {
"PACKAGE_NAME": "com.jffc.vcd"
},
"cordova-plugin-file": {
"PACKAGE_NAME": "com.jffc.vcd"
},
"cordova-sqlite-storage": {
"PACKAGE_NAME": "com.jffc.vcd"
},
"cordova-plugin-device": {
"PACKAGE_NAME": "com.jffc.vcd"
},
"cordova-plugin-console": {
"PACKAGE_NAME": "com.jffc.vcd"
}
},
"dependent_plugins": {
"cordova-plugin-compat": {
"PACKAGE_NAME": "com.jffc.vcd"
}
}
}
\ No newline at end of file
<!--
#
# 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.
#
-->
# Contributing to Apache Cordova
Anyone can contribute to Cordova. And we need your contributions.
There are multiple ways to contribute: report bugs, improve the docs, and
contribute code.
For instructions on this, start with the
[contribution overview](http://cordova.apache.org/contribute/).
The details are explained there, but the important items are:
- Sign and submit an Apache ICLA (Contributor License Agreement).
- Have a Jira issue open that corresponds to your contribution.
- Run the tests so your patch doesn't break existing functionality.
We look forward to your contributions!
Apache Cordova
Copyright 2012 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
{
"name": "cordova-plugin-camera",
"version": "2.4.1",
"description": "Cordova Camera Plugin",
"types": "./types/index.d.ts",
"cordova": {
"id": "cordova-plugin-camera",
"platforms": [
"firefoxos",
"android",
"amazon-fireos",
"ubuntu",
"ios",
"blackberry10",
"wp7",
"wp8",
"windows8",
"browser",
"windows"
]
},
"repository": {
"type": "git",
"url": "https://github.com/apache/cordova-plugin-camera"
},
"keywords": [
"cordova",
"camera",
"ecosystem:cordova",
"cordova-firefoxos",
"cordova-android",
"cordova-amazon-fireos",
"cordova-ubuntu",
"cordova-ios",
"cordova-blackberry10",
"cordova-wp7",
"cordova-wp8",
"cordova-windows8",
"cordova-browser",
"cordova-windows"
],
"scripts": {
"precommit": "npm run gen-docs && git add README.md",
"gen-docs": "jsdoc2md --template \"jsdoc2md/TEMPLATE.md\" \"www/**/*.js\" --plugin \"dmd-plugin-cordova-plugin\" > README.md",
"test": "npm run jshint",
"jshint": "node node_modules/jshint/bin/jshint www && node node_modules/jshint/bin/jshint src && node node_modules/jshint/bin/jshint tests"
},
"author": "Apache Software Foundation",
"license": "Apache-2.0",
"engines": {
"cordovaDependencies": {
"3.0.0": {
"cordova": ">100"
}
}
},
"devDependencies": {
"dmd-plugin-cordova-plugin": "^0.1.0",
"husky": "^0.10.1",
"jsdoc-to-markdown": "^1.2.0",
"jshint": "^2.6.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 (Uri inputUri)
{
//Determine whether the file is a content or file URI
if(inputUri.getScheme().equals("content"))
{
androidUri = inputUri;
fileName = getFileNameFromUri(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(Uri uri) {
String fullUri = uri.toString();
String partial_path = fullUri.split("external_files")[1];
File external_storage = Environment.getExternalStorageDirectory();
String path = external_storage.getAbsolutePath() + partial_path;
return path;
}
}
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
package org.apache.cordova.camera;
import java.io.IOException;
import android.media.ExifInterface;
public class ExifHelper {
private String aperture = null;
private String datetime = null;
private String exposureTime = null;
private String flash = null;
private String focalLength = null;
private String gpsAltitude = null;
private String gpsAltitudeRef = null;
private String gpsDateStamp = null;
private String gpsLatitude = null;
private String gpsLatitudeRef = null;
private String gpsLongitude = null;
private String gpsLongitudeRef = null;
private String gpsProcessingMethod = null;
private String gpsTimestamp = null;
private String iso = null;
private String make = null;
private String model = null;
private String orientation = null;
private String whiteBalance = null;
private ExifInterface inFile = null;
private ExifInterface outFile = null;
/**
* The file before it is compressed
*
* @param filePath
* @throws IOException
*/
public void createInFile(String filePath) throws IOException {
this.inFile = new ExifInterface(filePath);
}
/**
* The file after it has been compressed
*
* @param filePath
* @throws IOException
*/
public void createOutFile(String filePath) throws IOException {
this.outFile = new ExifInterface(filePath);
}
/**
* Reads all the EXIF data from the input file.
*/
public void readExifData() {
this.aperture = inFile.getAttribute(ExifInterface.TAG_APERTURE);
this.datetime = inFile.getAttribute(ExifInterface.TAG_DATETIME);
this.exposureTime = inFile.getAttribute(ExifInterface.TAG_EXPOSURE_TIME);
this.flash = inFile.getAttribute(ExifInterface.TAG_FLASH);
this.focalLength = inFile.getAttribute(ExifInterface.TAG_FOCAL_LENGTH);
this.gpsAltitude = inFile.getAttribute(ExifInterface.TAG_GPS_ALTITUDE);
this.gpsAltitudeRef = inFile.getAttribute(ExifInterface.TAG_GPS_ALTITUDE_REF);
this.gpsDateStamp = inFile.getAttribute(ExifInterface.TAG_GPS_DATESTAMP);
this.gpsLatitude = inFile.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
this.gpsLatitudeRef = inFile.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF);
this.gpsLongitude = inFile.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
this.gpsLongitudeRef = inFile.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF);
this.gpsProcessingMethod = inFile.getAttribute(ExifInterface.TAG_GPS_PROCESSING_METHOD);
this.gpsTimestamp = inFile.getAttribute(ExifInterface.TAG_GPS_TIMESTAMP);
this.iso = inFile.getAttribute(ExifInterface.TAG_ISO);
this.make = inFile.getAttribute(ExifInterface.TAG_MAKE);
this.model = inFile.getAttribute(ExifInterface.TAG_MODEL);
this.orientation = inFile.getAttribute(ExifInterface.TAG_ORIENTATION);
this.whiteBalance = inFile.getAttribute(ExifInterface.TAG_WHITE_BALANCE);
}
/**
* Writes the previously stored EXIF data to the output file.
*
* @throws IOException
*/
public void writeExifData() throws IOException {
// Don't try to write to a null file
if (this.outFile == null) {
return;
}
if (this.aperture != null) {
this.outFile.setAttribute(ExifInterface.TAG_APERTURE, this.aperture);
}
if (this.datetime != null) {
this.outFile.setAttribute(ExifInterface.TAG_DATETIME, this.datetime);
}
if (this.exposureTime != null) {
this.outFile.setAttribute(ExifInterface.TAG_EXPOSURE_TIME, this.exposureTime);
}
if (this.flash != null) {
this.outFile.setAttribute(ExifInterface.TAG_FLASH, this.flash);
}
if (this.focalLength != null) {
this.outFile.setAttribute(ExifInterface.TAG_FOCAL_LENGTH, this.focalLength);
}
if (this.gpsAltitude != null) {
this.outFile.setAttribute(ExifInterface.TAG_GPS_ALTITUDE, this.gpsAltitude);
}
if (this.gpsAltitudeRef != null) {
this.outFile.setAttribute(ExifInterface.TAG_GPS_ALTITUDE_REF, this.gpsAltitudeRef);
}
if (this.gpsDateStamp != null) {
this.outFile.setAttribute(ExifInterface.TAG_GPS_DATESTAMP, this.gpsDateStamp);
}
if (this.gpsLatitude != null) {
this.outFile.setAttribute(ExifInterface.TAG_GPS_LATITUDE, this.gpsLatitude);
}
if (this.gpsLatitudeRef != null) {
this.outFile.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, this.gpsLatitudeRef);
}
if (this.gpsLongitude != null) {
this.outFile.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, this.gpsLongitude);
}
if (this.gpsLongitudeRef != null) {
this.outFile.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, this.gpsLongitudeRef);
}
if (this.gpsProcessingMethod != null) {
this.outFile.setAttribute(ExifInterface.TAG_GPS_PROCESSING_METHOD, this.gpsProcessingMethod);
}
if (this.gpsTimestamp != null) {
this.outFile.setAttribute(ExifInterface.TAG_GPS_TIMESTAMP, this.gpsTimestamp);
}
if (this.iso != null) {
this.outFile.setAttribute(ExifInterface.TAG_ISO, this.iso);
}
if (this.make != null) {
this.outFile.setAttribute(ExifInterface.TAG_MAKE, this.make);
}
if (this.model != null) {
this.outFile.setAttribute(ExifInterface.TAG_MODEL, this.model);
}
if (this.orientation != null) {
this.outFile.setAttribute(ExifInterface.TAG_ORIENTATION, this.orientation);
}
if (this.whiteBalance != null) {
this.outFile.setAttribute(ExifInterface.TAG_WHITE_BALANCE, this.whiteBalance);
}
this.outFile.saveAttributes();
}
public int getOrientation() {
int o = Integer.parseInt(this.orientation);
if (o == ExifInterface.ORIENTATION_NORMAL) {
return 0;
} else if (o == ExifInterface.ORIENTATION_ROTATE_90) {
return 90;
} else if (o == ExifInterface.ORIENTATION_ROTATE_180) {
return 180;
} else if (o == ExifInterface.ORIENTATION_ROTATE_270) {
return 270;
} else {
return 0;
}
}
public void resetOrientation() {
this.orientation = "" + ExifInterface.ORIENTATION_NORMAL;
}
}
<?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">
<external-path name="external_files" path="."/>
</paths>
\ No newline at end of file
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
/* globals qnx, FileError, PluginResult */
var PictureSourceType = {
PHOTOLIBRARY : 0, // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
CAMERA : 1, // Take picture from camera
SAVEDPHOTOALBUM : 2 // Choose image from picture library (same as PHOTOLIBRARY for Android)
},
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] === 'cordova-plugin-camera') {
if (args[1] === 'cancel') {
cancel('User canceled');
} else if (args[1] === 'error') {
fail(args[2]);
} else {
saveImage(args[1], done, fail);
}
wv.un('JavaScriptCallback', arguments.callee);
wv.visible = false;
wv.destroy();
qnx.webplatform.getApplication().unlockRotation();
}
});
wv.on('Destroyed', function () {
wv.delete();
});
qnx.webplatform.getApplication().lockRotation();
qnx.webplatform.getController().dispatchEvent('webview.initialized', [wv]);
});
}
//create unique name for saved file (same pattern as BB10 camera app)
function imgName() {
var date = new Date(),
pad = function (n) { return n < 10 ? '0' + n : n; };
return 'IMG_' + date.getFullYear() + pad(date.getMonth() + 1) + pad(date.getDate()) + '_' +
pad(date.getHours()) + pad(date.getMinutes()) + pad(date.getSeconds()) + '.png';
}
//convert dataURI to Blob
function dataURItoBlob(dataURI) {
var byteString = atob(dataURI.split(',')[1]),
mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0],
arrayBuffer = new ArrayBuffer(byteString.length),
ia = new Uint8Array(arrayBuffer),
i;
for (i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([new DataView(arrayBuffer)], { type: mimeString });
}
//save dataURI to file system and call success with path
function saveImage(data, success, fail) {
var name = savePath + imgName();
require('lib/webview').setSandbox(false);
window.webkitRequestFileSystem(window.PERSISTENT, 0, function (fs) {
fs.root.getFile(name, { create: true }, function (entry) {
entry.createWriter(function (writer) {
writer.onwriteend = function () {
success(name);
};
writer.onerror = fail;
writer.write(dataURItoBlob(data));
});
}, fail);
}, fail);
}
function encodeBase64(filePath, callback) {
var sandbox = window.qnx.webplatform.getController().setFileSystemSandbox, // save original sandbox value
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);
}
};
/*
*
* 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 HIGHEST_POSSIBLE_Z_INDEX = 2147483647;
function takePicture(success, error, opts) {
if (opts && opts[2] === 1) {
capture(success, error, opts);
} else {
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.name = 'files[]';
input.onchange = function(inputEvent) {
var reader = new FileReader();
reader.onload = function(readerEvent) {
input.parentNode.removeChild(input);
var imageData = readerEvent.target.result;
return success(imageData.substr(imageData.indexOf(',') + 1));
};
reader.readAsDataURL(inputEvent.target.files[0]);
};
document.body.appendChild(input);
}
}
function capture(success, errorCallback, opts) {
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 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.height = targetHeight;
button.innerHTML = 'Capture!';
button.onclick = function() {
// create a canvas and capture a frame from video stream
var canvas = document.createElement('canvas');
canvas.width = targetWidth;
canvas.height = targetHeight;
canvas.getContext('2d').drawImage(video, 0, 0, targetWidth, targetHeight);
// convert image stored in canvas to base64 encoded image
var imageData = canvas.toDataURL('image/png');
imageData = imageData.replace('data:image/png;base64,', '');
// stop video stream, remove video and button.
// Note that MediaStream.stop() is deprecated as of Chrome 47.
if (localMediaStream.stop) {
localMediaStream.stop();
} else {
localMediaStream.getTracks().forEach(function (track) {
track.stop();
});
}
parent.parentNode.removeChild(parent);
return success(imageData);
};
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
var successCallback = function(stream) {
localMediaStream = stream;
video.src = window.URL.createObjectURL(localMediaStream);
video.play();
document.body.appendChild(parent);
};
if (navigator.getUserMedia) {
navigator.getUserMedia({video: true, audio: true}, successCallback, errorCallback);
} else {
alert('Browser does not support camera :(');
}
}
module.exports = {
takePicture: takePicture,
cleanup: function(){}
};
require("cordova/exec/proxy").add("Camera",module.exports);
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
/* globals MozActivity */
function takePicture(success, error, opts) {
var pick = new MozActivity({
name: "pick",
data: {
type: ["image/*"]
}
});
pick.onerror = error || function() {};
pick.onsuccess = function() {
// image is returned as Blob in this.result.blob
// we need to call success with url or base64 encoded image
if (opts && opts.destinationType === 0) {
// TODO: base64
return;
}
if (!opts || !opts.destinationType || opts.destinationType > 0) {
// url
return success(window.URL.createObjectURL(this.result.blob));
}
};
}
module.exports = {
takePicture: takePicture,
cleanup: function(){}
};
require("cordova/exec/proxy").add("Camera", module.exports);
/*
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 <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <CoreLocation/CLLocationManager.h>
#import <Cordova/CDVPlugin.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 CDVCamera : CDVPlugin <UIImagePickerControllerDelegate,
UINavigationControllerDelegate,
UIPopoverControllerDelegate,
CLLocationManagerDelegate>
{}
@property (strong) CDVCameraPicker* pickerController;
@property (strong) NSMutableDictionary *metadata;
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (strong) NSData* data;
/*
* getPicture
*
* arguments:
* 1: this is the javascript function that will be called with the results, the first parameter passed to the
* javascript function is the picture as a Base64 encoded string
* 2: this is the javascript function to be called if there was an error
* options:
* quality: integer between 1 and 100
*/
- (void)takePicture:(CDVInvokedUrlCommand*)command;
- (void)cleanup:(CDVInvokedUrlCommand*)command;
- (void)repositionPopover:(CDVInvokedUrlCommand*)command;
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info;
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingImage:(UIImage*)image editingInfo:(NSDictionary*)editingInfo;
- (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker;
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
- (void)locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation*)oldLocation;
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error;
@end
/*
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 CordovaLib_ExifData_h
#define CordovaLib_ExifData_h
// exif data types
typedef enum exifDataTypes {
EDT_UBYTE = 1, // 8 bit unsigned integer
EDT_ASCII_STRING, // 8 bits containing 7 bit ASCII code, null terminated
EDT_USHORT, // 16 bit unsigned integer
EDT_ULONG, // 32 bit unsigned integer
EDT_URATIONAL, // 2 longs, first is numerator and second is denominator
EDT_SBYTE,
EDT_UNDEFINED, // 8 bits
EDT_SSHORT,
EDT_SLONG, // 32bit signed integer (2's complement)
EDT_SRATIONAL, // 2 SLONGS, first long is numerator, second is denominator
EDT_SINGLEFLOAT,
EDT_DOUBLEFLOAT
} ExifDataTypes;
// maps integer code for exif data types to width in bytes
static const int DataTypeToWidth[] = {1,1,2,4,8,1,1,2,4,8,4,8};
static const int RECURSE_HORIZON = 8;
#endif
/*
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 <Foundation/Foundation.h>
@interface CDVJpegHeaderWriter : NSObject {
NSDictionary * SubIFDTagFormatDict;
NSDictionary * IFD0TagFormatDict;
}
- (NSData*) spliceExifBlockIntoJpeg: (NSData*) jpegdata
withExifBlock: (NSString*) exifstr;
- (NSString*) createExifAPP1 : (NSDictionary*) datadict;
- (NSString*) formattedHexStringFromDecimalNumber: (NSNumber*) numb
withPlaces: (NSNumber*) width;
- (NSString*) formatNumberWithLeadingZeroes: (NSNumber*) numb
withPlaces: (NSNumber*) places;
- (NSString*) decimalToUnsignedRational: (NSNumber*) numb
withResultNumerator: (NSNumber**) numerator
withResultDenominator: (NSNumber**) denominator;
- (void) continuedFraction: (double) val
withFractionList: (NSMutableArray*) fractionlist
withHorizon: (int) horizon;
//- (void) expandContinuedFraction: (NSArray*) fractionlist;
- (void) splitDouble: (double) val
withIntComponent: (int*) rightside
withFloatRemainder: (double*) leftside;
- (NSString*) formatRationalWithNumerator: (NSNumber*) numerator
withDenominator: (NSNumber*) denominator
asSigned: (Boolean) signedFlag;
- (NSString*) hexStringFromData : (NSData*) data;
- (NSNumber*) numericFromHexString : (NSString *) hexstring;
/*
- (void) readExifMetaData : (NSData*) imgdata;
- (void) spliceImageData : (NSData*) imgdata withExifData: (NSDictionary*) exifdata;
- (void) locateExifMetaData : (NSData*) imgdata;
- (NSString*) createExifAPP1 : (NSDictionary*) datadict;
- (void) createExifDataString : (NSDictionary*) datadict;
- (NSString*) createDataElement : (NSString*) element
withElementData: (NSString*) data
withExternalDataBlock: (NSDictionary*) memblock;
- (NSString*) hexStringFromData : (NSData*) data;
- (NSNumber*) numericFromHexString : (NSString *) hexstring;
*/
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <UIKit/UIKit.h>
@interface UIImage (CropScaleOrientation)
- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize;
- (UIImage*)imageCorrectedForCaptureOrientation;
- (UIImage*)imageCorrectedForCaptureOrientation:(UIImageOrientation)imageOrientation;
- (UIImage*)imageByScalingNotCroppingForSize:(CGSize)targetSize;
@end
\ No newline at end of file
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "UIImage+CropScaleOrientation.h"
@implementation UIImage (CropScaleOrientation)
- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize
{
UIImage* sourceImage = self;
UIImage* newImage = nil;
CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;
CGPoint thumbnailPoint = CGPointMake(0.0, 0.0);
if (CGSizeEqualToSize(imageSize, targetSize) == NO) {
CGFloat widthFactor = targetWidth / width;
CGFloat heightFactor = targetHeight / height;
if (widthFactor > heightFactor) {
scaleFactor = widthFactor; // scale to fit height
} else {
scaleFactor = heightFactor; // scale to fit width
}
scaledWidth = width * scaleFactor;
scaledHeight = height * scaleFactor;
// center the image
if (widthFactor > heightFactor) {
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
} else if (widthFactor < heightFactor) {
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
}
}
UIGraphicsBeginImageContext(targetSize); // this will crop
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width = scaledWidth;
thumbnailRect.size.height = scaledHeight;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
if (newImage == nil) {
NSLog(@"could not scale image");
}
// pop the context to get back to the default
UIGraphicsEndImageContext();
return newImage;
}
- (UIImage*)imageCorrectedForCaptureOrientation:(UIImageOrientation)imageOrientation
{
float rotation_radians = 0;
bool perpendicular = false;
switch (imageOrientation) {
case UIImageOrientationUp :
rotation_radians = 0.0;
break;
case UIImageOrientationDown:
rotation_radians = M_PI; // don't be scared of radians, if you're reading this, you're good at math
break;
case UIImageOrientationRight:
rotation_radians = M_PI_2;
perpendicular = true;
break;
case UIImageOrientationLeft:
rotation_radians = -M_PI_2;
perpendicular = true;
break;
default:
break;
}
UIGraphicsBeginImageContext(CGSizeMake(self.size.width, self.size.height));
CGContextRef context = UIGraphicsGetCurrentContext();
// Rotate around the center point
CGContextTranslateCTM(context, self.size.width / 2, self.size.height / 2);
CGContextRotateCTM(context, rotation_radians);
CGContextScaleCTM(context, 1.0, -1.0);
float width = perpendicular ? self.size.height : self.size.width;
float height = perpendicular ? self.size.width : self.size.height;
CGContextDrawImage(context, CGRectMake(-width / 2, -height / 2, width, height), [self CGImage]);
// Move the origin back since the rotation might've change it (if its 90 degrees)
if (perpendicular) {
CGContextTranslateCTM(context, -self.size.height / 2, -self.size.width / 2);
}
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
- (UIImage*)imageCorrectedForCaptureOrientation
{
return [self imageCorrectedForCaptureOrientation:[self imageOrientation]];
}
- (UIImage*)imageByScalingNotCroppingForSize:(CGSize)targetSize
{
UIImage* sourceImage = self;
UIImage* newImage = nil;
CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;
CGFloat scaleFactor = 0.0;
CGSize scaledSize = targetSize;
if (CGSizeEqualToSize(imageSize, targetSize) == NO) {
CGFloat widthFactor = targetWidth / width;
CGFloat heightFactor = targetHeight / height;
// opposite comparison to imageByScalingAndCroppingForSize in order to contain the image within the given bounds
if (widthFactor > heightFactor) {
scaleFactor = heightFactor; // scale to fit height
} else {
scaleFactor = widthFactor; // scale to fit width
}
scaledSize = CGSizeMake(MIN(width * scaleFactor, targetWidth), MIN(height * scaleFactor, targetHeight));
}
// If the pixels are floats, it causes a white line in iOS8 and probably other versions too
scaledSize.width = (int)scaledSize.width;
scaledSize.height = (int)scaledSize.height;
UIGraphicsBeginImageContext(scaledSize); // this will resize
[sourceImage drawInRect:CGRectMake(0, 0, scaledSize.width, scaledSize.height)];
newImage = UIGraphicsGetImageFromCurrentImageContext();
if (newImage == nil) {
NSLog(@"could not scale image");
}
// pop the context to get back to the default
UIGraphicsEndImageContext();
return newImage;
}
@end
/*
*
* 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"
}
}
}
/*
*
* 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;
}
/*
*
* 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
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment