Stream file to server from Cordoba application

I have a cordova application where the user should be able to select an image from their phone and upload it to AWS S3. I am using cordova-plugin-camera and S3 SDK for this. I have code that works fine (see below), but requires the entire image to be taken out into memory inside the base64 encoded string (behind Camera.DestinationType.DATA_URL ), and then back in Buffer.

I would prefer it to be disconnected from the phone’s hard drive to reduce potential memory problems. The cordova-plugin-camera website even has a warning about this:

/ ** * Warning: using DATA_URL is not recommended! DATA_URL destination type * very intensive, even with poor quality installation. Using it * may lead to memory errors and application crashes. Use FILE_URI * or NATIVE_URI instead. * /

So, is there a way to move a photo directly from disk to S3 using FILE_URIor NATIVE_URIor any other technique?

Here is my current code:

doTheThing() {
    let options = {
        quality: 50,
        destinationType: Camera.DestinationType.DATA_URL,
        sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
        encodingType: Camera.EncodingType.JPG
    };

    navigator.camera.getPicture(imgData => {
       this.uploadToS3(imgData);
    }, options);


    uploadToS3(data) {
        let AWS = require('aws-sdk');

        AWS.config = new AWS.Config();
        AWS.config.accessKeyId = 'noway';
        AWS.config.secretAccessKey = 'jose';
        AWS.config.region = 'us-east-2';

        let s3 = new AWS.S3();
        let uploadParams = { Bucket: 'iamkule/f1/f2', Key: '', Body: new Buffer(data, 'base64') };
        uploadParams.Key = 'myfile.jpg';

        s3.upload(uploadParams, function (err, data) {
           if (data) {
              console.log('yay!');
           }
        });
    }
}
+4
source share
1 answer

This should help you get started. Please forgive my pseudo code. Feel free to edit it as needed.

The device saves the image to disk:

function takePicture(urlCallback){
    let options = {
        quality: 50,
        destinationType: Camera.DestinationType.FILE_URI,// <--
        sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
        encodingType: Camera.EncodingType.JPG
    };
    navigator.camera.getPicture(urlCallback, onFail, options);  
    function onFail(message) {
        alert('Failed because: ' + message);
    }
}

Get the image from disk as blob:

function getImageAsBlob(url, blobCallback) {
    var xhr = new XMLHttpRequest();
    xhr.open( "GET", url, true );
    xhr.responseType = "arraybuffer";
    xhr.onload = function( ev ) {
        // Obtain a blob: URL for the image data.
        var arrayBufferView = new Uint8Array( this.response );
        var blob = new Blob( [ arrayBufferView ], { type: "image/jpeg" } );
        blobCallback(blob);
    };
    xhr.send();
}

Download blob on S3:

function uploadToS3(blob, callback) {
    let AWS = require('aws-sdk');
    AWS.config = new AWS.Config();
    AWS.config.accessKeyId = 'noway';
    AWS.config.secretAccessKey = 'jose';
    AWS.config.region = 'us-east-2';
    let s3 = new AWS.S3();
    let options = { Bucket: 'iamkule/f1/f2', Key: 'myfile.jpg', Body: blob };// <--
    s3.upload(options, callback);
}

Putting it all together:

takePicture(function(url){
    getImageAsBlob(url, function(blob){
        uploadToS3(blob, function (err, data) {
            if (data) console.log('yay!');
        });
    });
});

S3 . .   !

+1

Source: https://habr.com/ru/post/1689419/


All Articles