@codesthings/camera
提供设备摄像头的 API
npm i --save @codesthings/camera

NativeScript Camera

与摄像头插件协同工作

概述

几乎每个移动应用程序都需要捕获、保存和分享图像的选项。NativeScript 摄像头插件是为这项工作的前两部分设计的(拍照和可选地保存到设备存储)。

安装

npm install @nativescript/camera --save

API

方法

方法 描述
takePicture(options?: CameraOptions) 使用摄像头拍照,可选参数用于设置不同的摄像头选项。
requestPermissions() 请求用户权限以访问其保存的照片以及其摄像头。返回一个 Promise。
requestCameraPermissions() 请求用户权限以访问其摄像头。返回一个 Promise。
requestPhotosPermissions() 请求用户权限以访问其保存的照片。返回一个 Promise。
isAvailable() 设备摄像头是否可用。

CameraOptions

属性 默认值 平台 描述
width 0 Both 定义所期望的图像宽度(以设备独立像素为单位)。应与 height 属性一起使用。如果 keepAspectRatio,实际图像宽度可能不同,以保持原始摄像头图像的宽高比。如果设备的显示密度更高(大于 1)(全高清+分辨率),实际图像宽度将大于请求的宽度。
height 0 Both 定义所期望的图像高度(以设备独立像素为单位)。应与 width 属性一起使用。如果 keepAspectRatio,实际图像高度可能不同,以保持原始摄像头图像的宽高比。如果设备的显示密度更高(大于 1)(全高清+分辨率),实际图像高度将大于请求的高度。
keepAspectRatio true Both 定义是否在调整图片大小时保持摄像头图片的宽高比。此属性可能会影响宽度和高度返回值。
saveToGallery true Both 定义是否将摄像头图片复制到照片图库(Android)或照片(iOS)。
allowsEditing false iOS 定义是否在摄像头的“重新拍照”或“使用照片”屏幕上强制用户裁剪摄像头图片为正方形,并可选择放大。
cameraFacing rear Both 初始摄像头方向。使用 'front' 进行自拍。

注意:Android 上的 saveToGallery 选项可能会出现意外的行为!某些供应商摄像头应用(例如 LG)将保存所有捕获的图像到图库,不管 saveToGallery 的值是什么。这种行为无法通过摄像头插件控制,如果您必须将捕获的图像从照片图库中排除,您将需要获取本地存储的读写权限,并编写自定义代码以找到图库位置并从该位置删除新图像。

用法

请求权限

Android 和 iOS 都需要显式权限,以便应用程序可以访问摄像头并将照片保存到设备。一旦用户授予了权限,就可以使用摄像头模块。

import { requestPermissions } from '@nativescript/camera';

requestPermissions().then(
function success() {
// permission request accepted or already granted
// ... call camera.takePicture here ...
},
function failure() {
// permission request rejected
// ... tell the user ...
}
);

Android 注意:不使用请求权限弹出窗口的较旧版本的 Android 不会受 requestPermissions 方法使用的影响。

针对iOS的说明:如果用户拒绝了iOS弹出窗口的权限请求,应用将不允许再次请求。您可以指导用户前往应用设置,并从那里手动启用相机权限。此外,App Store指南5.1.1要求应用明确说明相机和照片库的使用情况。为此,请编辑您的app/App_Resources/iOS/Info.plist文件并添加以下说明

<key>NSCameraUsageDescription</key>
<string>enter your camera permission request text here</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>enter your photo library permission request text here</string>

使用相机模块拍照

使用相机模块相对简单。但是,有一些需要稍作解释的点。

为了使用相机模块,只需像示例1中那样请求它

示例1:在应用程序中请求相机模块

// JavaScript
const camera = require("@nativescript/camera");
// TypeScript
import * as camera from "@nativescript/camera";

然后您就可以开始使用了

示例2:如何拍照并接收图像资源

// JavaScript
const { Image } = require("@nativescript/core");

camera.takePicture()
.then(function (imageAsset) {
console.log("Result is an image asset instance");
var image = new Image();
image.src = imageAsset;
}).catch(function (err) {
console.log("Error -> " + err.message);
});
// TypeScript
import { Image } from "@nativescript/core";

camera.takePicture()
.then((imageAsset) => {
console.log("Result is an image asset instance");
var image = new Image();
image.src = imageAsset;
}).catch((err) => {
console.log("Error -> " + err.message);
});

示例2中的代码将启动本地平台相机应用。拍照并点击按钮保存(Android)或使用图片(iOS)后,Promise将解析then部分,并将图像资源设置为ui/image控制的src

使用选项进行内存高效的拍照

示例2显示了如何使用NativeScript相机模块拍照。然而,它捕获了一个巨大的图像(即使是中端设备也有5MP相机,结果图像为2580x2048,在位图中的大小约为15MB)。在许多情况下,您不需要如此大的图片来显示100x100大小的图像,所以捕获大图片只是浪费内存。camera takePicture()方法接受一个可选参数,可以帮助解决这个问题。使用该可选参数,您可以设置一些属性,例如

  • width:图片期望的宽度(以设备独立像素为单位)。
  • height:图片期望的高度(以设备独立像素为单位)。
  • keepAspectRatio:一个布尔参数,表示是否应该保持宽高比。
  • saveToGallery:一个布尔参数,表示是否将原始捕获的照片保存到“照片”中(Android)或在iOS中保存到“相机胶卷”。
  • allowsEditing:(仅iOS)一个布尔参数,表示相机“重拍”或“使用照片”屏幕是否强制用户裁剪相机图片为正方形,并可选地允许他们放大。
  • cameraFacing:从设备的“前”或“后”(默认)相机开始。当前实现不适用于所有Android设备,在这种情况下,将回退到默认行为。

什么是设备独立像素?NativeScript布局机制使用设备独立像素来测量UI控件。这允许您声明一个布局,该布局将适用于所有设备(无论设备的显示分辨率如何)。为了获得高分辨率设备(如iPhone视网膜和Android Full HD)的适当图像质量,相机将返回一个具有更大维度的图像。例如,如果我们请求一个100x100的图像,在iPhone 6上实际的图像将是200x200(因为其显示密度因子是2 -> 1002x1002)。设置keepAspectRatio属性可能导致与请求的宽度和高度不同。相机将返回具有正确宽高比的图像,但通常只有(从宽度和高度)一个与请求相同;另一个值将计算出来以保留原始图像的宽高比。

示例3显示了如何使用选项参数

示例3:如何为相机模块设置widthheightkeepAspectRatiosaveToGallery属性

// JavaScript

const options = {
width: 300,
height: 300,
keepAspectRatio: false,
saveToGallery: true
};

camera.takePicture(options)
.then(function (imageAsset) {
console.log("Size: " + imageAsset.options.width + "x" + imageAsset.options.height);
console.log("keepAspectRatio: " + imageAsset.options.keepAspectRatio);
console.log("Photo saved in Photos/Gallery for Android or in Camera Roll for iOS");
}).catch(function (err) {
console.log("Error -> " + err.message);
});
// TypeScript
import { Image } from "@nativescript/core";

const options = {
width: 300,
height: 300,
keepAspectRatio: false,
saveToGallery: true
};

camera.takePicture(options)
.then((imageAsset) => {
console.log("Size: " + imageAsset.options.width + "x" + imageAsset.options.height);
console.log("keepAspectRatio: " + imageAsset.options.keepAspectRatio);
console.log("Photo saved in Photos/Gallery for Android or in Camera Roll for iOS");
}).catch((err) => {
console.log("Error -> " + err.message);
});

保存图片

为了保存您定义的宽度和高度的图片,您必须使用imageAsset并将其保存到文件系统,如下所示

import { ImageSource, knownFolders, path } from '@nativescript/core';

const source = new ImageSource();

source.fromAsset(imageAsset)
.then((imageSource: ImageSource) => {
const folderPath: string = knownFolders.documents().path;
const fileName: string = "test.jpg";
const filePath: string = path.join(folderPath, fileName);
const saved: boolean = imageSource.saveToFile(filePath, "jpg");

if (saved) {
console.log("Gallery: " + this._dataItem.picture_url);
console.log("Saved: " + filePath);
console.log("Image saved successfully!");
}
});

这可以用来在您的应用中快速显示缩略图。

检查设备是否有可用的摄像头

开发者在检查设备是否有可用摄像头时应做的第一件事。如果摄像头硬件准备好使用,方法isAvaiable将返回true,否则返回false。

const isAvailable = camera.isAvailable();

注意:在iOS模拟器中使用此方法将返回false(因为模拟器没有摄像头硬件)