Ionic 4 and Capacitor Filesystem - Help please

Good Day,
I am fairly new to mobile development in general and need some help, please.
The aim is to take a photo with an Ionic / Capacitor app and save it on a PHP server at a specific location.

There are so many Cordova tutorials and still little Capacitor posts and the Capacitor posts I could find just made me more confused…

What I have managed so far is to build the part where you can take a photo, it is the rest I have a problem with.

I have tried multiple different options including converting it to base64… but every time posting it to the server I ran into problems.

The server I use for testing is a basic localhost wampp setup.

The code I have so far:
tab1.page.html

<ion-header>
  <ion-toolbar>
    <ion-title>
      Capture
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
    <img [src]="photo" >
    <ion-fab vertical="bottom" horizontal="center" slot="fixed">
        <ion-fab-button (click)="takePhoto()">
          <ion-icon name="camera"></ion-icon>
        </ion-fab-button>
      </ion-fab>
    
</ion-content>

then tab1.page.ts

import { Component } from '@angular/core';
import { Plugins, CameraResultType, CameraSource } from '@capacitor/core';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-tab1',
  templateUrl: 'tab1.page.html',
  styleUrls: ['tab1.page.scss'],
})

export class Tab1Page {
  photo: SafeResourceUrl;

  constructor(private sanitizer: DomSanitizer, private http: HttpClient) {}

  async takePhoto() {
    const image = await Plugins.Camera.getPhoto({
      quality: 75,
      allowEditing: true,
      resultType: CameraResultType.DataUrl,
      source: CameraSource.Camera,
    });

    this.photo = this.sanitizer.bypassSecurityTrustResourceUrl(image && (image.dataUrl));
  }
}

I have completely removed my junk code to try and put it on server location… it was a mess…

I do however get the Base64 string for the image:

SafeValue must use [property]=binding: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAI.......... 

and a lot more :slight_smile: when I look at this.photo

How do I pass this to the localhost PHP server for saving the file?

Can anyone please assist me in achieving the end result?

Thank you in advance!

I have since my post updated the tab1.page.ts code with the following:

import { Component } from '@angular/core';
import { Plugins, CameraResultType, CameraSource } from '@capacitor/core';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { HttpClient } from '@angular/common/http';

import { AlertController } from '@ionic/angular';

import { Capacitor, FilesystemDirectory } from '@capacitor/core';

@Component({
  selector: 'app-tab1',
  templateUrl: 'tab1.page.html',
  styleUrls: ['tab1.page.scss'],
})

export class Tab1Page {
  photo: SafeResourceUrl;

  constructor(private sanitizer: DomSanitizer, private http: HttpClient, public alertController: AlertController) {}

  // async takePhoto() {
  //   const image = await Plugins.Camera.getPhoto({
  //     quality: 75,
  //     allowEditing: true,
  //     resultType: CameraResultType.Uri,
  //     source: CameraSource.Camera,
  //   });

  //   this.photo = this.sanitizer.bypassSecurityTrustResourceUrl(image && (image.path));
  //   console.log(this.photo);
  //   this.presentAlert(this.photo);
  // }

  async takePhoto() {
    const { Camera, Filesystem } = Plugins;
    const options = {
      quality: 20,
      resultType: CameraResultType.Uri
    };

    const originalPhoto = await Camera.getPhoto(options);
    const photoInTempStorage = await Filesystem.readFile({ path: originalPhoto.path });

    const date = new Date(),
      time = date.getTime(),
      fileName = time + '.jpeg';

    await Filesystem.writeFile({
      data: photoInTempStorage.data,
      path: fileName,
      directory: FilesystemDirectory.Data
    });

    const finalPhotoUri = await Filesystem.getUri({
      directory: FilesystemDirectory.Data,
      path: fileName
    });

    const photoPath = Capacitor.convertFileSrc(finalPhotoUri.uri);
    console.log(photoPath);
  }

  async presentAlert(content) {
    const alert = await this.alertController.create({
      header: 'Alert',
      subHeader: 'Subtitle',
      message: content,
      buttons: ['OK']
    });

    await alert.present();
  }
}

When I use this on my phone, I do get the temp file location now which is a great step forward.

Can anyone please help me, how do I now send this file to new php server location?

That totally depends on what your server is expecting. In general terms, you can simply use HttpClient to POST or PUT it as part of or the entirety of the body of the request.

Incidentally, IMHO a considerably easier way to do the part you’ve already been fighting with is:

takePhoto(opts: CameraOptions): Observable<ArrayBuffer> {
  return from(Plugins.Camera.getPhoto(opts)).pipe(
    map(camphoto => camphoto.webPath),
    switchMap(uri => this.http.get(uri, {responseType: "arraybuffer"}));
}

The way I do it is to get the photo, as a base64 image, in an object that might look like…

{
  "imageName`: "First Photo",
  "imageBase64": "data:image/jpeg;base64,/9j/4AAQSk..."
}

…that would come from a simple form with a camera button.

Then you can create a service to upload the object to a REST server, where your php code handles the received object and can convert the image to a file, or store it in a database, or whatever?

There is no way for an Ionic app to save the image directly to your server.