ionic 3从相机上传图像不使用文件,文件传输,文件上传插件
Posted
技术标签:
【中文标题】ionic 3从相机上传图像不使用文件,文件传输,文件上传插件【英文标题】:ionic 3 upload image from camera NOT USING file, file-transfer, file-upload plugins 【发布时间】:2018-08-16 17:30:54 【问题描述】:我想使用 FormData 将图像上传到我的后端,但由于 Ionic DEVAPP 和 Ionic VIEW 不支持文件、文件传输和文件上传插件,我只需要使用 Angular Http 或 HttpClient 来完成.
当使用 DestinationType.FILE_URI 时,我可以从文件中获取内部 url 并将其显示在 img 对象上,但如果没有本机文件、文件路径和文件传输插件,我无法从此 url 创建 typescript File 对象。
getImage()
const options: CameraOptions =
quality: 100,
destinationType: this.camera.DestinationType.FILE_URI,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY
this.camera.getPicture(options).then((imageData) =>
this.imageURI = this.sanitizer.bypassSecurityTrustUrl(imageData)
, (err) =>
console.log(err)
this.presentToast(err)
)
使用这个模板
<ion-content padding>
<ion-item>
<p>imageFileName</p>
<button ion-button color="secondary" (click)="getImage()">Get Image</button>
</ion-item>
<ion-item>
<h4>Image Preview</h4>
<img style="display:block" [src]="imageURI" *ngIf="imageURI" />
</ion-item>
<ion-item>
<button ion-button (click)="uploadFile()">Upload</button>
</ion-item>
</ion-content>
使用 DestinationType.DATA_URL 时,我可以显示图像,但无法使用原始文件名创建所需的打字稿文件对象,以将图像附加到 Ionic 应用程序的上传服务上使用的 FormData。
看来我可以找到一种方法来使用来自 FILE_URI 的原始文件名和来自 DATA_URL 的 base64 编码数据使用cordova相机本机插件中的 camera.getPicture 创建这个打字稿文件对象。
将文件上传到我的后端的服务只是使用这种方法:
postImage(image: File): Observable<any>
const formData = new FormData()
.append('file', image, image.name)
return this.httpClient.post<any>(this.myUrl,formData)
来自组件 myPage.ts 的 getImage 和来自uploadservice.ts 的 postImage 工作正常,但我找不到从 camera.getPicture imageData 创建 File 对象的方法
【问题讨论】:
【参考方案1】:如果你不想使用原生插件,你总是可以使用 angular。对于这种情况,请使用离子输入文件:
<ion-input type="file"></ion-input>
剩下的就用 Angular 来完成: https://www.academind.com/learn/angular/snippets/angular-image-upload-made-easy/
你可以使用这个例子:
https://github.com/diegogplfree/Ionic3-fileupload-non-native
亲切的问候。
【讨论】:
【参考方案2】:答案主要来自here,但适用于@ionic-native/camera
插件getPicture
命令。
private urltoFile(url, filename, mimeType)
return (fetch(url)
.then(function(res)return res.arrayBuffer();)
.then(function(buf)return new File([buf], filename, type:mimeType);)
);
getPicture()
const options: CameraOptions =
quality: 50,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
correctOrientation: true
this.camera.getPicture(options).then((imageData) =>
let base64Image = 'data:image/jpeg;base64,' + imageData
this.urltoFile(base64Image, 'filename.jpg', 'image/jpeg')
.then((file) =>
// You now have a file object that you can attach to a form e.g.
this.myForm.get("imageToUpload").setValue(file)
)
, (err) =>
// Handle error
);
需要注意的重点是
-
目标类型必须是
DATA_URL
必须在 data:image/jpeg;base64,
前面加上 imageData
【讨论】:
来自 ionic doc:DATA_URL 可能会占用大量内存并导致应用程序崩溃或内存不足错误。如果可能,请使用 FILE_URI 或 NATIVE_URI【参考方案3】:我遇到了同样的问题,并且确实喜欢这个及其对我有用的东西。但需要注意的一点是,我没有先显示选定的图像。上传后仅可见。
openImage()
const options: CameraOptions =
quality: 100,
destinationType: this.camera.DestinationType.FILE_URI,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
correctOrientation: true,
allowEdit: false
;
this.camera.getPicture(options).then(imageData =>
this.ImageFile = imageData;
, err =>
this.commonProvider.showToast('Error occured while opening the image' + err);
);
upload(msg: string)
this.businessProvider.upload(this.Id, this.ImageFile)
.then(
data =>
let response = JSON.parse(data["response"]);
if (response.code === '1')
this.commonProvider.showToast('Business successfully ' + msg);
this.navCtrl.pop();
else
this.commonProvider.showToast(response.message);
this.commonProvider.dismissLoader();
,
error =>
this.commonProvider.showToast(JSON.stringify(error));
this.commonProvider.dismissLoader();
);
这是我的业务提供商
import Injectable from '@angular/core';
import HttpClient, HttpErrorResponse from '@angular/common/http';
import Observable from 'rxjs/Observable';
import ErrorObservable from 'rxjs/observable/ErrorObservable';
import catchError from 'rxjs/operators';
import Constant from '../app/app.constants';
import AuthenticationProvider from '../providers/authentication';
import FileTransfer, FileUploadOptions, FileTransferObject from '@ionic-native/file-transfer';
@Injectable()
export class BusinessProvider
private actionUrl: string;
constructor(
private http: HttpClient,
private auth: AuthenticationProvider,
private constant: Constant,
private transfer: FileTransfer
)
this.actionUrl = this.constant.getServerWithApiUrl() + 'Business/';
upload(Id: number, ImageFile): any
const fileTransfer: FileTransferObject = this.transfer.create();
const headers = this.auth.getHeader();
let options: FileUploadOptions =
fileKey: 'ionicfile',
fileName: 'ionicfile.jpg',
chunkedMode: false,
mimeType: "image/jpeg",
headers: headers
return fileTransfer.upload(ImageFile, this.actionUrl + 'Upload/' + Id, options);
【讨论】:
您没有提供有关您的 businessProvider.upload() 函数的详细信息,因此我们无法使用您的“解决方案” 添加了缺失的部分 不回答问题,要求解决方案没有文件传输以上是关于ionic 3从相机上传图像不使用文件,文件传输,文件上传插件的主要内容,如果未能解决你的问题,请参考以下文章
文件上传选项以从相机拍摄图像或从图库中选择不适用于 Mozilla Firefox 中的 Web 应用程序