Native ImagePicker + File.readAsDataURL() Worked! But mystery continues

There are many unanswered questions about File.readAsDataURL() on this forum.
I somehow got it to work with the following code.

ImagePicker.getPictures(options).then((results) => {
      let imageURLs=[];
      for (var i = 0; i < results.length; i++) {
          console.log('Image URI: ' + results[i]);
          // note the results of ImagePicker is reversely ordered, thus unshift() 
          imageURLs.unshift(results[i]);
      }
      let imageB64strs=[];
      for (var i = 0; i < imageURLs.length; i++) {
        var imagePath = imageURLs[i].substr(0, imageURLs[i].lastIndexOf('/') + 1);
        var imageName = imageURLs[i].substr(imageURLs[i].lastIndexOf('/') + 1);
        
        console.log('File.readAsDataURL: imagePath: ' + imagePath);
        console.log('File.readAsDataURL: imageName: ' + imageName);
        console.log('cordova.file.dataDirectory: ' + cordova.file.dataDirectory);

        File.readAsDataURL(imagePath, imageName).then((b64str) => {
          console.log('Image B64 URL: ' + b64str);
          
        }).catch(err => {
          console.log('readAsDataURL failed: (' + err.code + ")" + err.message);
        })
      }
    }
    ,(err) => { });

The mystery continues because the first parameter SHOULD be “Base FileSystem”, IE. “cordova.file.dataDirectory”, according to the documentation.

In Short, this line:
File.readAsDataURL(imagePath, imageName).
SHOULD be like this, according to the doc:
File.readAsDataURL(cordova.file.dataDirectory, imageName).

The culprit seems to be different directory naming schemes, “cache” vs " files"

The file, from ImagePicker, parent path is:
file:///data/user/0/com.ionicframework.myionic2project764460/cache

Yet cordova.file.dataDirectory is
file:///data/user/0/com.ionicframework.myionic2project764460/files/

So now the questions are:

  1. Why ?!
  2. Would my solution work for majority of Andriod devices?

Please help.

I’m getting the FILE_URI as file:///storage/emulated/0/Android/data/com.myapp.app1/cache/.Pic.jpg?1490768822733.
Due to this extra parameter I’m getting NOT_FOUND_ERR. What should I do???

Looking at your path, perhaps you are using Android studio emulator?
I got it working on Genymotion, and a real device (Nexus 5).
Have you tried your code on Genymotion and real device?

I’m running it on my Asus Zenfone 2

Have you tried to remove the extra parameters after ‘?’.

I don’t think that’ll work coz the second image has the same file name but with different parameter.
Also if I use it in <img src>, it displays fine.

It seems to be a device specific issue, because it worked just fine on Nexus 5.
If I were you, I would reach out to ImagePicker (Cordova) team.
Please let me know how it goes.

Another option is to read the image into Base64 String.
This is code example I copy/paste from ImagePicker issue discussion: https://github.com/wymsee/cordova-imagePicker/issues/112

function getBase64Image (img) {
// Create an empty canvas element
var canvas = document.createElement(‘canvas’);
canvas.width = img.width;
canvas.height = img.height;

// Copy the image contents to the canvas
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
// Get the data-URL formatted image
// Firefox supports PNG and JPEG. You could check img.src to
// guess the original format, but be aware the using 'image/jpg'
// will re-encode the image.
var dataURL = canvas.toDataURL('image/png');
return dataURL.replace(/^data:image\/(png|jpg);base64,/, '');

}
function encodeImageUri(imageUri) {
var deferred = $q.defer();

var c = document.createElement('canvas');
var ctx = c.getContext('2d');
var img = new Image();
img.onload = function(){
    c.width = this.width;
    c.height = this.height;
    ctx.drawImage(img, 0,0);
};
img.src = imageUri;
return getBase64Image(img);

}

encodeImageUri(imageUrlHere)

I don’t know if this is relevant to others, but when I moved my app to the Ionic 3 / Angular 4 beta with lazy page loading, ImagePicker started crashing my app hard. If it’s feasible for you, maybe look at substituting the Camera plugin instead.

@sifang ohhh!!! sry I was actually using cordova-plugin-camera and not the cordova-plugin-image-picker. Will try and check this with other devices.

1 Like