使用Ionic 4将图像捕获并上传到服务器 [英] Capture and upload image to server using Ionic 4

查看:109
本文介绍了使用Ionic 4将图像捕获并上传到服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经尝试捕获图像并将其上传到服务器数天了,但是没有运气. 我将Ionic 4用于客户端,并将Java作为后端(我使用Jersey将后端暴露给REST).

I've been trying to capture an image and upload it to the server for days but no luck. I'm using Ionic 4 for my client side, and Java as my backend (I used Jersey to expose my backend to REST).

现在,问题在于拍摄完图像并尝试上传后,我一直在后端接收到空值.

Now, the problem is that after taking the image, and try to upload it I keep recieving a null in my backend.

这是我的客户端代码:

    openCam(){
    const options: CameraOptions = {
      quality: 100,
      destinationType: this.camera.DestinationType.FILE_URI,
      encodingType: this.camera.EncodingType.JPEG,
      mediaType: this.camera.MediaType.PICTURE,
      correctOrientation: true,
      cameraDirection: 1
    }

    this.camera.getPicture(options).then((imageData) => {
     // imageData is either a base64 encoded string or a file URI
     // If it's base64 (DATA_URL):
     //alert(imageData)
     this.imageData = imageData;
     this.image=(<any>window).Ionic.WebView.convertFileSrc(imageData);
     this.isImageCaptureed = true;

    }, (err) => {
     // Handle error
     alert("error "+JSON.stringify(err))
    });
  }


    upload(){
      let  url = 'http://mydommain/api/upload';
      let dataURL  = 'data:image/jpeg;base64,' + this.imageData;
      let  postData = new FormData();
      postData.append('file', dataURL);

      let data:Observable<any> = this.http.post(url,postData);
      data.subscribe((result) => {
        console.log(result);
      });
  }

我尝试将imageData直接传递给FormData对象,我还尝试使用DataURIToBlob()函数将其转换,因为我发现了其他一些类似的问题,但是还是没有运气.

I tried to pass imageData directly to FormData object,I also tried to convert it using DataURIToBlob() funcion as I found on some other similar problem but still no luck..

    dataURItoBlob(dataURI) {
    // convert base64/URLEncoded data component to raw binary data held in a string
    var byteString;
    if (dataURI.split(',')[0].indexOf('base64') >= 0)
        byteString = atob(dataURI.split(',')[1]);
    else
        byteString = unescape(dataURI.split(',')[1]);

    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

    // write the bytes of the string to a typed array
    var ia = new Uint8Array(byteString.length);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }

    return new Blob([ia], {type:mimeString});
}

我知道问题仅在于imageData格式.由于我设法使用HTML输入标签发送选择文件,然后使用上述相同的upload()函数和我的后端API上传文件.

I know the problem is just in the imageData format. Since I managed to send to select a file using HTML input tag, and upload it using the same upload() function mentioned above and my backend API.

推荐答案

这是将Ionic 4拍摄的图像上传到后端服务器的详细方法.

Here's a detailed way to upload captured images taken by Ionic 4 to backend server.

我们假设我们有以下CaptureImage类,专门用于捕获和上传拍摄的图像

Let's assume that we have the following class CaptureImage dedicated to capture and upload the taken image

export class CaptureImage  implements OnInit {
 constructor() { }
  ngOnInit() {
  }
}

首先,我们需要使用以下命令安装@ ionic-native/camera:

First, we need to install @ionic-native/camera using :

ionic cordova plugin add cordova-plugin-camera
npm install @ionic-native/camera

您可以参考离子文档

然后您需要在您的类中声明一个照相机对象,这样我们的类将变为:

Then you need to declare a camera object in to your class, so our class will become:

import { Camera, CameraOptions } from '@ionic-native/camera/ngx';

export class CaptureImage implements OnInit {

  //image to be displayed in template
  image;
  imageData;
  constructor(private camera: Camera) { }
          ngOnInit() {
          }
}

接下来,我们需要模板中的触发器,以便调用将捕获图片的函数,因此模板(capture-image.page.html)将如下所示:

Next we need a trigger in our template, in order to call a function which will capture the picture, so the template (capture-image.page.html) will look something like this:

<ion-fab vertical="bottom" horizontal="end" slot="fixed">
      <ion-fab-button (click)="capture()">
          <ion-icon ios="ios-camera" md="md-camera"></ion-icon>
      </ion-fab-button>
 </ion-fab>

请注意,我们定义了一个click事件,该事件称为capture()函数.现在我们需要实现此功能.

Note that we defined a click event which called capture() function. Now we need to implement this function.

回到我们的CaptureImage类,这是capture()函数:

So back to our CaptureImage class, here's the capture() function :

  openCamera(){
    const options: CameraOptions = {
    quality: 100,
    destinationType: this.camera.DestinationType.DATA_URL,
    encodingType: this.camera.EncodingType.JPEG,
    mediaType: this.camera.MediaType.PICTURE,
   }

    this.camera.getPicture(options).then((imageData) => {
    this.imageData = imageData;
    this.image=(<any>window).Ionic.WebView.convertFileSrc(imageData);
    }, (err) => {
       // Handle error
       alert("error "+JSON.stringify(err))
  });
}

请注意,destinationType必须为this.camera.DestinationType.DATA_URL

恭喜!您已经拍照,可以使用以下模板在模板中查看拍照的图片:

Congratulation ! you have taken the picture , you can view the taken picture in your template using:

<img [src]="image" >     

现在我们需要将其上传到服务器.为了简单起见,我将直接在CaptureImage类中实现上载功能.但实际上,最好在专用服务中实现所有后端调用,然后将其注入您的类中.

now we need to upload it to the server. For sake of simplicity, I will implement the upload function directly in the class CaptureImage. but in reality it is better to implement all backend calls in a dedicated service, and then inject it in your class.

因此,要上传图片,我们将再次需要一个触发器,因此在模板中,我们定义一个上传按钮:

So in order to upload the image, we'll need again a trigger, so in our template, let's define an upload button :

 <ion-button (click)="upload()" color="success">
    <ion-icon slot="icon-only" name="checkmark"></ion-icon>
 </ion-button>

所以回到CaptureImage类中,让我们首先将HttpClient注入构造函数中

So back in the CaptureImage class, let's first inject the HttpClient in the constructor

import { HttpClient } from '@angular/common/http';

export class CaptureImage implements OnInit {
  //image to be displayed in template
  image;
  imageData;
  constructor(private camera: Camera,
          private http: HttpClient){ }
          ngOnInit() {
          }
   }

然后,让我们定义upload()函数:

then,let's define the upload() function :

upload(){
  let  url = 'your REST API url';
  const date = new Date().valueOf();

  // Replace extension according to your media type
  const imageName = date+ '.jpeg';
  // call method that creates a blob from dataUri
  const imageBlob = this.dataURItoBlob(this.imageData);
  const imageFile = new File([imageBlob], imageName, { type: 'image/jpeg' })

  let  postData = new FormData();
  postData.append('file', imageFile);

  let data:Observable<any> = this.http.post(url,postData);
  data.subscribe((result) => {
    console.log(result);
  });
}

快完成了!我们仍然需要实现另一个功能:dataURItoBlob,该功能从dataURLI创建blob文件:

Almost done ! we still need to implement one more function : dataURItoBlob, this function creates blob files from dataURLI:

dataURItoBlob(dataURI) {
  const byteString = window.atob(dataURI);
  const arrayBuffer = new ArrayBuffer(byteString.length);
  const int8Array = new Uint8Array(arrayBuffer);
  for (let i = 0; i < byteString.length; i++) {
    int8Array[i] = byteString.charCodeAt(i);
   }
  const blob = new Blob([int8Array], { type: 'image/jpeg' });    
 return blob;
}

最后,这是CaptureImage类的结尾:

Finally, this is how the CaptureImage class will look at the end :

import { Observable } from 'rxjs';
import { OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Camera, CameraOptions } from '@ionic-native/camera/ngx';

export class CaptureImage implements OnInit {

 //image to be displayed in template
 image;
 imageData;
constructor(private camera: Camera,
        private http: HttpClient) { }
  ngOnInit() {
  }

  openCamera(){
    const options: CameraOptions = {
    quality: 100,
    destinationType: this.camera.DestinationType.DATA_URL,
    encodingType: this.camera.EncodingType.JPEG,
    mediaType: this.camera.MediaType.PICTURE,
   }

    this.camera.getPicture(options).then((imageData) => {
    this.imageData = imageData;
    this.image=(<any>window).Ionic.WebView.convertFileSrc(imageData);
    }, (err) => {
       // Handle error
       alert("error "+JSON.stringify(err))
  });
}
  upload(){
    let  url = 'your REST API url';
    const date = new Date().valueOf();

    // Replace extension according to your media type
    const imageName = date+ '.jpeg';
    // call method that creates a blob from dataUri
    const imageBlob = this.dataURItoBlob(this.imageData);
    const imageFile = new File([imageBlob], imageName, { type: 'image/jpeg' })

    let  postData = new FormData();
    postData.append('file', imageFile);

    let data:Observable<any> = this.http.post(url,postData);
    data.subscribe((result) => {
      console.log(result);
    });
  }

  dataURItoBlob(dataURI) {
    const byteString = window.atob(dataURI);
   const arrayBuffer = new ArrayBuffer(byteString.length);
    const int8Array = new Uint8Array(arrayBuffer);
    for (let i = 0; i < byteString.length; i++) {
      int8Array[i] = byteString.charCodeAt(i);
     }
    const blob = new Blob([int8Array], { type: 'image/jpeg' });    
   return blob;
  }
}

这篇关于使用Ionic 4将图像捕获并上传到服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆