Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cordova camera take picture as Blob object

Tags:

cordova

I'm trying to take a picture using cordova-plugin-camera. I'd like the result to be a File or Blob object.

However, the destinationType must be one of DATA_URL or FILE_URI.

The docs state:

DATAURL can be very memory intensive and cause app crashes or out of memory errors. Use FILEURI or NATIVE_URI if possible

However, as far as I can tell, converting such a file uri to a Blob takes these steps:

  1. Rendering the uri on a <img/
  2. Draw image on a canvas
  3. Read canvas as base64
  4. Convert base64 to Blob

I find it hard to believe that this is more efficient than using DATAURL. So I might just as well use DATAURL for this and skip steps 1-3.

Is there a way to just get a picture taken as a Blob object in a more efficient way?

like image 760
Remco Haszing Avatar asked Apr 28 '16 11:04

Remco Haszing


People also ask

What is camera getPicture?

getPicture. Takes a photo using the camera or retrieves a photo from the device's album. The image is returned as a base64 encoded String or as the URI of an image file.

What is camera plugin?

Details. A plugin that enables an application to access the camera features of the user's device. This plugin allows the implementation of actions for taking pictures or choosing images from the device gallery.


1 Answers

Unfortunately, you can't extract a BLOB from the Cordova camera plugin.

The way to get a BLOB is to convert your base64 encoded string to a BLOB and use that.

Here's a method (ES6 compliant) that allows you to convert to BLOB and just the sliceSize to be more memory efficient.

/**
 * Turn base 64 image into a blob, so we can send it using multipart/form-data posts
 * @param b64Data
 * @param contentType
 * @param sliceSize
 * @return {Blob}
 */
private getBlob(b64Data:string, contentType:string, sliceSize:number= 512) {
    contentType = contentType || '';
    sliceSize = sliceSize || 512;

    let byteCharacters = atob(b64Data);
    let byteArrays = [];

    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        let slice = byteCharacters.slice(offset, offset + sliceSize);

        let byteNumbers = new Array(slice.length);
        for (let i = 0; i < slice.length; i++) {
            byteNumbers[i] = slice.charCodeAt(i);
        }

        let byteArray = new Uint8Array(byteNumbers);

        byteArrays.push(byteArray);
    }

    let blob = new Blob(byteArrays, {type: contentType});
    return blob;
}
like image 58
0x1ad2 Avatar answered Sep 30 '22 04:09

0x1ad2