Search code examples
angularionic-frameworkionic4capacitor

Ionic Capacitor Camera, generate full quality image and display it without generating Base64 and DataUri


In my Ionic Project, I am using Capacitor for deployment in mobile platforms.

For capturing an image from device, I am using Capacitor Camera which helps me to get the image in three formats. 1. Base64. 2. DataUrl. 3. FileUri.

onCaptureImage() {
    if (!Capacitor.isPluginAvailable('Camera')) {
      this._sharedService.showToastMessage(
        'Unable To Open Camera', 1000);
      return;
    }
    Plugins.Camera.getPhoto({
      quality: 60,
      source: CameraSource.Prompt,
      correctOrientation: true,
      resultType: CameraResultType.DataUrl
    })
      .then(image => {
        const blobImg = this._sharedService.dataURItoBlob(image.dataUrl);
        this.myfiles.push(blobImg);
        this.urls.push(this.sanitizer.bypassSecurityTrustUrl(image.dataUrl));
      })
      .catch(error => {
        return false;
      });
  }

From this DataUrl I am using to display the image and for uploading this image, I am converting it into Blob and then sending it through FormData.

Right now the quality is 60, I want the quality as 100. But it hangs the device when we generate DataUrl out of 100 quality image.

I just want to know that is there any way that we can generate FileUri with having quality 100 and also can preview the image without generating Base64 or DataUrl out of it.

Thanks.


Solution

  • The size of the huge base64 string is what hangs the app. Look at this solution...

    Use the camera settings as below:

    Camera.getPhoto({
        quality: 100,
        resultType: CameraResultType.Uri,
        source: CameraSource.Prompt
      }).then((image) => {
    //imgSrc is passed to src of img tag
    imgSrc = this.domSanitizer.bypassSecurityTrustResourceUrl(image && (image.webPath));
    
    // image.path is what you will have to send to the uploadPhoto method as uripath
          });
    

    The Uri format will give you the local file path which can be easily passed to the filetransfer plugin... image.path is the local file path returned by the camera..

    For transferring the file to a server, you will need the cordova file-transfer plugin..the code will look like this..

    import { FileTransfer, FileUploadOptions, FileTransferObject } from '@ionic-native/file-transfer/ngx';
    
    constructor(private transfer: FileTransfer)
    
    uploadPhoto(fileName:string, uripath:string):Promise<any>{
    return new Promise((resolve,reject) => {
      const fileTransfer: FileTransferObject = this.transfer.create();
      const options: FileUploadOptions = {
        fileKey: 'file',
        fileName: fileName,
        mimeType: 'image/jpg',
        chunkedMode: false,
        params: {
          //any params that you want to attach for the server to use
        },
        headers: {
          //any specific headers go here
        }
      };
      fileTransfer.upload(uripath, <APIEndpointURL>, options)
        .then((result) => {
          // success
        resolve(result);
        }, (err) => {
          // error
          reject(err);
        });
    });
    }
    

    With this your server will definitely receive the file, irrespective of image quality.. i have used this method on both node.js and php servers.