Nativescript如何在自定义组件中将图像保存到文件
Nativescript how to save image to file in custom component
我创建了一个自定义组件,可以访问设备的相机来拍摄照片,将其设置为 ImageView
的来源,然后将其保存到文件中。
这是 Javascript 代码
CAMERA.JS
这里是imageView的初始化
export function cameraLoaded(args):void{
cameraPage = <Page> args.object;
imageView = <Image> cameraPage.getViewById("img_upload");...
}
这里我设置imageViews
'来源为刚拍的照片
export function takePicture():void{
camera.takePicture(
{
})
.then(
function(picture){
imageView.imageSource = picture;
},function(error){
});
}
这非常有效。
现在我尝试将图片保存到文件中。
export function saveToFile():void{
try {
let saved = imageView.imageSource.saveToFile(path,enums.ImageFormat.png);
HalooseLogger.log(saved,"upload");
})
}catch (e){
...
}
}
这里报错cannot read property saveToFile of undefined
这很不寻常,事实上如果我 console.log(imageView)
这里是输出:
Image<img_upload>@file:///app/views/camera/camera.xml:4:5;
但如果我 console.log(imageView.imageSource
) 我看到它是“未定义的”。
这怎么可能?我做错了什么?
附加信息
之前的代码和relatexxml包含在另一个视图中如下:
MAIN.XML
<Page
xmlns="http://schemas.nativescript.org/tns.xsd"
xmlns:cameraPage="views/camera"
loaded="loaded">
<StackLayout orientation="vertical">
<StackLayout id="mainContainer">
<!-- DYNAMIC CONTENT GOES HERE -->
</StackLayout>
</StackLayout>
</Page>
MAIN.JS
这是动态加载的相机视图
export function loaded(args):void{
mainPage = <Page>args.object;
contentWrapper = mainPage.getViewById("mainContainer");
DynamicLoaderService.loadPage(mainPage,contentWrapper,mainViewModel.currentActive);
}
loadPage
方法执行以下操作:
public static loadPage(pageElement,parentElement,currentActive):void{
let component = Builder.load({
path : "views/camera",
name : "camera",
page : pageElement
});
parentElement.addChild(component);
}
问题是,从 NativeScript 2.4.0 开始,为 Android 创建的 Image 的 属性 return 将始终为 null imageSource。目前,正在优化以防止在处理多个大图像时出现与内存不足相关的问题,这就是 image-asset 在 nativeScript 2.4.0 中出现的原因。
现在我不确定您是否使用最新的 nativescript-camera(强烈推荐),但如果是这样,您应该考虑 takePicture() 的承诺是 returning imageAsset。由于内存优化,imageSource 将始终 return undefined(对于 Android),除非您专门创建一个。您可以使用 fromAsset() 方法来执行此操作,该方法提供来自相机回调的 ImageAsset return。
示例:
import { EventData } from 'data/observable';
import { Page } from 'ui/page';
import { Image } from "ui/image";
import { ImageSource, fromAsset } from "image-source";
import { ImageAsset } from "image-asset";
import * as camera from "nativescript-camera";
import * as fs from "file-system";
var imageModule = require("ui/image");
var img;
var myImageSource: ImageSource;
// Event handler for Page "navigatingTo" event attached in main-page.xml
export function onLoaded(args: EventData) {
// Get the event sender
let page = <Page>args.object;
img = <Image>page.getViewById("img");
camera.requestPermissions();
}
export function takePhoto() {
camera.takePicture()
.then(imageAsset => {
console.log("Result is an image asset instance");
img.src = imageAsset;
fromAsset(imageAsset).then(res => {
myImageSource = res;
console.log(myImageSource);
})
}).catch(function (err) {
console.log("Error -> " + err.message);
});
}
export function saveToFile(): void {
var knownPath = fs.knownFolders.documents();
var folderPath = fs.path.join(knownPath.path, "CosmosDataBank");
var folder = fs.Folder.fromPath(folderPath);
var path = fs.path.join(folderPath, "Test.png");
var saved = myImageSource.saveToFile(path, "png");
console.log(saved);
}
我创建了一个自定义组件,可以访问设备的相机来拍摄照片,将其设置为 ImageView
的来源,然后将其保存到文件中。
这是 Javascript 代码
CAMERA.JS
这里是imageView的初始化
export function cameraLoaded(args):void{
cameraPage = <Page> args.object;
imageView = <Image> cameraPage.getViewById("img_upload");...
}
这里我设置imageViews
'来源为刚拍的照片
export function takePicture():void{
camera.takePicture(
{
})
.then(
function(picture){
imageView.imageSource = picture;
},function(error){
});
}
这非常有效。
现在我尝试将图片保存到文件中。
export function saveToFile():void{
try {
let saved = imageView.imageSource.saveToFile(path,enums.ImageFormat.png);
HalooseLogger.log(saved,"upload");
})
}catch (e){
...
}
}
这里报错cannot read property saveToFile of undefined
这很不寻常,事实上如果我 console.log(imageView)
这里是输出:
Image<img_upload>@file:///app/views/camera/camera.xml:4:5;
但如果我 console.log(imageView.imageSource
) 我看到它是“未定义的”。
这怎么可能?我做错了什么?
附加信息 之前的代码和relatexxml包含在另一个视图中如下:
MAIN.XML
<Page
xmlns="http://schemas.nativescript.org/tns.xsd"
xmlns:cameraPage="views/camera"
loaded="loaded">
<StackLayout orientation="vertical">
<StackLayout id="mainContainer">
<!-- DYNAMIC CONTENT GOES HERE -->
</StackLayout>
</StackLayout>
</Page>
MAIN.JS
这是动态加载的相机视图
export function loaded(args):void{
mainPage = <Page>args.object;
contentWrapper = mainPage.getViewById("mainContainer");
DynamicLoaderService.loadPage(mainPage,contentWrapper,mainViewModel.currentActive);
}
loadPage
方法执行以下操作:
public static loadPage(pageElement,parentElement,currentActive):void{
let component = Builder.load({
path : "views/camera",
name : "camera",
page : pageElement
});
parentElement.addChild(component);
}
问题是,从 NativeScript 2.4.0 开始,为 Android 创建的 Image 的 属性 return 将始终为 null imageSource。目前,正在优化以防止在处理多个大图像时出现与内存不足相关的问题,这就是 image-asset 在 nativeScript 2.4.0 中出现的原因。
现在我不确定您是否使用最新的 nativescript-camera(强烈推荐),但如果是这样,您应该考虑 takePicture() 的承诺是 returning imageAsset。由于内存优化,imageSource 将始终 return undefined(对于 Android),除非您专门创建一个。您可以使用 fromAsset() 方法来执行此操作,该方法提供来自相机回调的 ImageAsset return。
示例:
import { EventData } from 'data/observable';
import { Page } from 'ui/page';
import { Image } from "ui/image";
import { ImageSource, fromAsset } from "image-source";
import { ImageAsset } from "image-asset";
import * as camera from "nativescript-camera";
import * as fs from "file-system";
var imageModule = require("ui/image");
var img;
var myImageSource: ImageSource;
// Event handler for Page "navigatingTo" event attached in main-page.xml
export function onLoaded(args: EventData) {
// Get the event sender
let page = <Page>args.object;
img = <Image>page.getViewById("img");
camera.requestPermissions();
}
export function takePhoto() {
camera.takePicture()
.then(imageAsset => {
console.log("Result is an image asset instance");
img.src = imageAsset;
fromAsset(imageAsset).then(res => {
myImageSource = res;
console.log(myImageSource);
})
}).catch(function (err) {
console.log("Error -> " + err.message);
});
}
export function saveToFile(): void {
var knownPath = fs.knownFolders.documents();
var folderPath = fs.path.join(knownPath.path, "CosmosDataBank");
var folder = fs.Folder.fromPath(folderPath);
var path = fs.path.join(folderPath, "Test.png");
var saved = myImageSource.saveToFile(path, "png");
console.log(saved);
}