How to show a picture taked by Camera?

Hi all,
I tryed to show a picture taked by Camera with Ionic-Native but i don’t understand how proceed…
I open the camera, take the picture, preview her with android and when i want to use the path in html it doesn’t work :frowning:

There is my code :
.ts

import { Component } from '@angular/core';
import { IonicPage } from 'ionic-angular';
import { Camera, CameraOptions } from '@ionic-native/camera';

@IonicPage()
@Component({
  selector: 'page-annonce-form',
  templateUrl: 'annonce-form.html',
})
export class AnnonceFormPage {
  photo;

  constructor(private camera: Camera) {
    camera.getPicture().then((imageData) => {
       this.photo = imageData
    }, (err) => {
       console.log(err);
    });
  }
}

.html :

<ion-header>
  <ion-navbar></ion-navbar>
</ion-header>


<ion-content padding>
    <img [src]="photo" *ngIf="photo" />
    <ion-item>
        <ion-label color="primary" full floating>Titre {{image}}</ion-label>
        <ion-input type="text" [(ngModel)]="titre" required="true"></ion-input>
    </ion-item>
    <ion-item>
      <ion-label color="primary" full floating stacked>Description</ion-label>
      <ion-textarea [(ngModel)]="description"></ion-textarea>
    </ion-item>
    <ion-grid>
      <ion-row>
        <ion-col>
          <ion-item>
              <ion-label color="primary" full floating>Tarif proposé</ion-label>
              <ion-input type="number" [(ngModel)]="description" required="true"></ion-input>
          </ion-item>
        </ion-col>
        <ion-col>
          <ion-item>
            <ion-label color="primary">Négociable</ion-label>
            <ion-select [(ngModel)]="negociable">
              <ion-option value="true">Oui</ion-option>
              <ion-option value="false">Non</ion-option>
            </ion-select>
          </ion-item>
        </ion-col>
      </ion-row>
    </ion-grid>

  <button ion-button block id="btnContact"><p>Envoyer l'annonce</p><ion-icon margin-left=2% name="send"></ion-icon></button>
</ion-content>

Ty for help :bowing_man:

So when you put a breakpoint on this line:

during debugging, what is imageData?

this.photo = `data:image/png;base64,${imageData}`;

That assumes they have set their camera options to DATA_URL, which is not the default and isn’t recommended as it’s very memory intensive and slow.

:thinking: Didn’t know that. What about getting it from the device? Does it apply too?

Only converting to a base64 string causes the issue, because you are taking a large binary file and turning it into a string…which isn’t great. It’s mentioned multiple times in the plugin docs, but people still use it because it’s simple.

NOTE: Photo resolution on newer devices is quite good. Photos selected from the device’s gallery are not downscaled to a lower quality, even if a quality parameter is specified. To avoid common memory problems, set Camera.destinationType to FILE_URI rather than DATA_URL.

Return base64 encoded string. DATA_URL can be very memory intensive and cause app crashes or out of memory errors. Use FILE_URI or NATIVE_URI if possible

Edited to clarify that any time you convert an image to base64 this issue could happen, both from the camera or gallery.

2 Likes

Hi, ty for reply !
imageData = “file:///storage/emulated/0/Android/data/io.ionic.starter/cache/1526978307100.jpg” during debugging :confused:

Okay, that seems correct to me and should work, however, I think you just need to install the cordova-plugin-file plugin.

ionic cordova plugin add cordova-plugin-file

After that it should work, I just verified it locally. Here’s all my exact code I used to verify:

These are my camera options:

 private cameraOptions: CameraOptions = {
    quality: 100,
    destinationType: this.camera.DestinationType.FILE_URI,
    encodingType: this.camera.EncodingType.JPEG,
    mediaType: this.camera.MediaType.PICTURE
  };

I have a simple service method that then takes the picture with those options, logs the path, and returns the path:

async getFilePathFromCamera() {
  const imagePath: string = await this.camera.getPicture(this.cameraOptions);
  console.log(imagePath);
  return imagePath;
}

I’m using async/await instead of a regular promise but this is functionally equivalent to what you have. This logs out to the console: file:///storage/emulated/0/Android/data/io.ionic.starter/cache/1527001151725.jpg

So same path and everything. Then in my view I simply call that service method:

export class HomePage implements OnInit{
  filePath: string;

  async showImageFromCamera() {
      try {
        this.filePath = await this.imageManagementService.getFilePathFromCamera();
      } catch(error) {
        console.log(error);
      }
  }
}

Again I’m using async await instead of a regular promise but again it should be the same, I set a string property on the page that sets that path. Then in the html:

<img [src]="filePath">

And the image shows up for me with no issue. Install the file plugin and maybe check your camera options to see if they match. If those don’t resolve it, check the network panel and see if it tries to load the image (it should) you’ll be able to see an error. Here’s what it looks like on mine, which works fine:
image

Edited to clarify after I verified the behavior of the file plugin

Ty for this response ! I’m going to apply it but i seen you use google chrome ? Cordova can work on it ? :open_mouth:

It’s the remote debugging feature of chrome dev tools. How are you debugging your app without using it?

All you have to do is go to the “Remote Devices” tab and you’ll see any connected devices, click on a device and you’ll see any open webviews (including your cordova app and any chrome tabs), then just click inspect on your app. It is as far as I know the only way to debug your app on Android…

2 Likes

Hi rlouie, sorry for late response. I’m work on it now and ou you use imageManagementService, what is it ?
Ty :slight_smile: