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从相机上传图像不使用文件,文件传输,文件上传插件的主要内容,如果未能解决你的问题,请参考以下文章

使用 Ionic 使用相机拍摄多张照片

文件上传选项以从相机拍摄图像或从图库中选择不适用于 Mozilla Firefox 中的 Web 应用程序

如何从使用 Ionic 框架中的相机插件选择的视频文件 URI 创建 Blob?

选择文件,设置图像和上传,而不阻塞用户界面

文件未在服务器 ionic3 中上传

iOS 上的 Plupload 仅适用于新照片,不适用于相机胶卷