【问题标题】:ionic 3 upload image from camera NOT USING file, file-transfer, file-upload pluginsionic 3从相机上传图像不使用文件,文件传输,文件上传插件
【发布时间】: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" alt="Ionic File" width="300" />
  </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 对象的方法

【问题讨论】:

    标签: angular typescript ionic3 cordova-plugins ionic-native


    【解决方案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
          });
      }
      

      需要注意的重点是

      1. 目标类型必须是DATA_URL
      2. 必须在 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() 函数的详细信息,因此我们无法使用您的“解决方案”
      • 添加了缺失的部分
      • 不回答问题,要求解决方案没有文件传输
      猜你喜欢
      • 1970-01-01
      • 2018-05-13
      • 2019-11-12
      • 2016-05-14
      • 2019-07-03
      • 2020-01-15
      • 2016-01-11
      • 1970-01-01
      • 2012-01-20
      相关资源
      最近更新 更多