Skip to content

Imagepicker not working, selection is empty #189

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
miguelopezv opened this issue May 18, 2018 · 21 comments
Closed

Imagepicker not working, selection is empty #189

miguelopezv opened this issue May 18, 2018 · 21 comments

Comments

@miguelopezv
Copy link

Which platform(s) does your issue occur on?

  • Both
  • iOS 10 - 11/Android 7
  • emulator and device. iPhone 5s - Xiaomi Mi Note 4

Please, provide the following version numbers that your issue occurs with:

  • CLI: 4.0.0
  • Cross-platform modules: 4.0.0
  • Runtime(s): 4.0.1
  • Plugin(s):
    "dependencies": {
    "@angular/animations": "~5.2.0",
    "@angular/common": "~5.2.0",
    "@angular/compiler": "~5.2.0",
    "@angular/core": "~5.2.0",
    "@angular/forms": "~5.2.0",
    "@angular/http": "~5.2.0",
    "@angular/platform-browser": "~5.2.0",
    "@angular/platform-browser-dynamic": "~5.2.0",
    "@angular/router": "~5.2.0",
    "nativescript-angular": "~5.2.0",
    "nativescript-camera": "^4.0.2",
    "nativescript-drop-down": "^3.2.1",
    "nativescript-imagepicker": "^6.0.1",
    "nativescript-iqkeyboardmanager": "^1.2.0",
    "nativescript-ngx-fonticon": "^4.1.0",
    "nativescript-plugin-firebase": "^5.2.0",
    "nativescript-social-login": "^4.0.0",
    "nativescript-sqlite": "^2.0.1",
    "nativescript-telerik-ui": "^3.1.4",
    "nativescript-theme-core": "~1.0.4",
    "nativescript-ui-listview": "^3.5.4",
    "nativescript-ui-sidedrawer": "^3.5.2",
    "reflect-metadata": "~0.1.10",
    "rxjs": "~5.5.5",
    "tns-core-modules": "^4.0.0",
    "zone.js": "~0.8.18"
    },
    "devDependencies": {
    "@angular/compiler-cli": "~5.2.0",
    "@ngtools/webpack": "~1.9.1",
    "babel-traverse": "6.4.5",
    "babel-types": "6.4.5",
    "babylon": "6.4.5",
    "clean-webpack-plugin": "~0.1.19",
    "codelyzer": "~4.0.2",
    "copy-webpack-plugin": "~4.3.0",
    "css-loader": "~0.28.7",
    "extract-text-webpack-plugin": "~3.0.2",
    "lazy": "1.0.11",
    "nativescript-dev-sass": "^1.3.5",
    "nativescript-dev-typescript": "~0.6.0",
    "nativescript-dev-webpack": "^0.11.0",
    "nativescript-worker-loader": "~0.8.1",
    "raw-loader": "~0.5.1",
    "resolve-url-loader": "~2.2.1",
    "sass-loader": "~6.0.6",
    "tns-platform-declarations": "^4.0.0",
    "tslint": "~5.8.0",
    "typescript": "~2.6.2",
    "uglifyjs-webpack-plugin": "~1.1.6",
    "webpack": "~3.10.0",
    "webpack-bundle-analyzer": "^2.9.1",
    "webpack-sources": "~1.1.0"
    }

Please, tell us how to recreate the issue in as much detail as possible.

When trying to select an image, this code that I've been using for a while stopped working, returning undefined is not an object (evaluating 'file.split'). Also, according to the demo provided selection[0] returns

{
    "_observers": {},
    "_options": {
        "keepAspectRatio": true
    },
    "_ios": {}
}

Is there any code involved?

private _startSelection(context) {
        context.authorize().then(() => {
            return context.present();
        }).then((selection) => {
            selection.forEach((selected) => this.user.image = selected.fileUri);
            const base64 = this._imgToBase64(this.user.image);
            const data = `data:image/${this.user.image.split('.').pop().toLowerCase()};base64,${base64}`;
            this._userService.saveImage({image: data}).subscribe(
                (result: any) =>  {
                    console.log(result);
                },
                (error: any) => {
                    console.log(error);
                }
            );
            this._changeDetectionRef.detectChanges();
        }).catch((e) => console.log(e));
    }
@snq
Copy link

snq commented May 21, 2018

I'm having the same exact issue here

@snq
Copy link

snq commented May 22, 2018

I just found out that on android this happens for the photos saved on SD card, when I copy the photos to Downloads folder and try again, it works fine.

on iOS though I haven't had any luck as no matter where the photo is located, it never works.

@sivamamidi-REISys
Copy link

+1

@snq
Copy link

snq commented May 23, 2018

Any help would be much appreciated

@spmamidi
Copy link

After upgrading to 5.0. selectedImage is not having getImage method.

@snq
Copy link

snq commented May 24, 2018

The issue is not about the getImage method, it’s about selected or selection[0] being empty.

@lini
Copy link
Contributor

lini commented May 25, 2018

I just want to confirm the issues because it does seem like there are two different ones:

  • iOS: always unable to get image path.
  • Android: unable to get image path if selected image is not stored in the device's internal memory (Google Drive, SD Card, etc.)

For the iOS issue - please try the following approach to get the image path - #181 (comment)

For the Android issue - can you confirm that selecting files from internal memory works and only selecting files from external locations produces an null location?

@sivamamidi-REISys
Copy link

Hi Lini,

we were using same example, getImage method is not undefined. I am looking at the documentation migrations to 6. it says method will return imageAsset instead of custom object.

We are getting imageAsset instead of custom image.

@lini
Copy link
Contributor

lini commented May 25, 2018

Thank you for the additional information. I contacted the people, who wrote the new 6.x version and they confirmed that the fileUri property is removed in the latest version and this was not mentioned in the migration section of the readme. I updated the relevant text to prevent other people who upgrade from hitting this issue. If you feel that the fileUri property should be part of the returned ImageAsset object, I suggest that you submit an issue in the main NativeScript repository - https://github.com/NativeScript/NativeScript/issues

@snq
Copy link

snq commented May 25, 2018

@lini thank you for your reply.

iOS: always unable to get image path.
Android: unable to get image path if selected image is not stored in the device's internal memory (Google Drive, SD Card, etc.)

Yes that's correct.

For the iOS issue - please try the following approach to get the image path - #181 (comment)

I've tried that and it doesn't work. The solution above relies on the selection which for me looks like this:

JS: {
JS:   "_observers": {},
JS:   "_options": {
JS:     "keepAspectRatio": true
JS:   },
JS:   "_ios": ""
JS: }

For the Android issue - can you confirm that selecting files from internal memory works and only selecting files from external locations produces an null location?

I can definitely confirm that that's the case. Even testing the demo app gives me the same issue.

@lini
Copy link
Contributor

lini commented May 25, 2018

Hi @snq,
Thank you for the details for Android - this is now marked as a bug.
For iOS I am still not sure how to reproduce the issue with the demo app. Are you using a real device or a simulator? Which iOS version? Did you modify some of the code in the demo app? Does the app have permission to access the internal storage? Here is what I see in the console log when I run it on a real device with iOS 11.3 and the latest 6.x image picker plugin version and select an image (pick single in this case):

CONSOLE LOG file:///app/main-view-model.js:89:24: Selection done: [{"_observers":{},"_options":{"keepAspectRatio":true},"_ios":{}}]

This is the selection object, which holds the individual selected ImageAsset objects.

@snq
Copy link

snq commented May 25, 2018

@lini okay I just tested it on a real iOS device and I can successfully select the image and the preview would appear on the list view.

But I'm confused then, if that is my selection object (as you mentioned and also how I get it) how would I access the ImageAsset? to be able to store it or show it in any other way?

Are you using a real device or a simulator?

Initially simulator only and now both.

Which iOS version?

11.2

Did you modify some of the code in the demo app?

No.

Does the app have permission to access the internal storage?

Yes.

@sivamamidi-REISys
Copy link

Hi Lini,

we also have requirement to upload image but it was working properly. After upgrade we are not even able to view and upload for both ios and android. We are using following code.

selection.forEach(  (selected_item) => {
                   selected_item.getImage().then( (imagesource) => {

                   if (platformModule.device.os === "Android") {
                       fileUri = selected_item.android;
                   } else {
                       // selected_item.ios for iOS is PHAsset and not path - so we are creating own path
                       let folder = fs.knownFolders.documents();
                       let path = fs.path.join(folder.path, "prescription.png");
                       let saved = imagesource.saveToFile(path,  enums.ImageFormat.png);
                       fileUri = path;
                   }
                   fileUri = fileUri || selection[0].fileUri;
                   this.upload(fileUri);
                })
               });

Any help is highly appreciated.

@snq
Copy link

snq commented May 25, 2018

@lini Now I'm able to get the ImageAsset on iOS with the following code you proposed, thank you!

selection.forEach(function(selected) {
  const ios = selected.ios;
  if (ios && ios.mediaType === PHAssetMediaType.Image) {
      const opt = PHImageRequestOptions.new();
      opt.version = PHImageRequestOptionsVersion.Current;
      PHImageManager.defaultManager().requestImageDataForAssetOptionsResultHandler(
          ios, opt, (NSData, dataUTI, UIImageOrientation, NSDictionary) => {
              console.log(NSDictionary);
          });
  } 
});

My only problem now is the bug in Android: not able to select photos located on the external SD card.

@snq
Copy link

snq commented May 26, 2018

@sivamamidi-REISys the issue you're facing is about getImage method.

If you upgraded to 6.0 forget about this method. What you need to do now is:

selection.forEach( (selected_item) => {
   if (platformModule.device.os === "Android") {
       //fileUri = selected_item.android;
       fileUri = selected_item.android.toString();
   } else {
       // selected_item.ios for iOS is PHAsset and not path - so we are creating own path
       /*
       let folder = fs.knownFolders.documents();
       let path = fs.path.join(folder.path, "prescription.png");
       let saved = imagesource.saveToFile(path,  enums.ImageFormat.png);
       fileUri = path;
       */
       const opt = PHImageRequestOptions.new();
       opt.version = PHImageRequestOptionsVersion.Current;
       PHImageManager.defaultManager().requestImageDataForAssetOptionsResultHandler(
        ios, opt, (NSData, dataUTI, UIImageOrientation, NSDictionary) => {
        fileUri = NSDictionary.objectForKey("PHImageFileURLKey").toString();
        });
   }
   fileUri = fileUri || selection[0].fileUri;
   this.upload(fileUri);
});

@sivamamidi-REISys
Copy link

Getting an error like ReferenceError: Can't find variable: QBImagePickerControllerDelegate in ios.

@shayfriedman
Copy link

@sivamamidi-REISys remove and add the ios platform:
tns platform remove ios
tns platform add ios

That fixed that issue for me.

@snq
Copy link

snq commented Jul 7, 2018

This is still a bug for Android. Selecting images from external SD returns null. Any updates?

@d3mac123
Copy link

Hi, I am also moving from version 3.x to the newest one and I am having issues capturing the image, then working with it using BitmapFactory. Below my code:
`
viewModel.onTapPhoto = function(args) {
var context = imagepickerModule.create({
mode: "single"
});
startSelection(context);
}

function startSelection(context) {
    context
        .authorize()
        .then(function() {
            return context.present();
        })
        .then(function(selection) {
            selection.forEach(function(selected) {
                var a = "";
                if (page.android) {
                    a = selected.android.toString();
                    source = a;
                    console.log("Android source: "+source)
                    fbPhotoHolder.src = source;
                } else {
                    const opt = PHImageRequestOptions.new();
                    opt.version = PHImageRequestOptionsVersion.Current;
                    PHImageManager.defaultManager().requestImageDataForAssetOptionsResultHandler(
                        selected.ios, opt, (NSData, dataUTI, UIImageOrientation, NSDictionary) => {
                        a = NSDictionary.objectForKey("PHImageFileURLKey").toString();
                        picExt = a.substr(a.length-3, a.length).toLowerCase()
                        source = a.substr(7, a.length)
                        var path = fs.path.join(folder.path, fbUID+"_temp.jpg");
                        a = a || selection[0].a;
                        //this.upload(a);
                        var img = a
                        var bmp = BitmapFactory.create(100, 100);
                        bmp.dispose(function(b) {
                            b.insert(img);
                            var b2 = b           
                            var thumb_image = b2.toImageSource();            
                            var saved = thumb_image.saveToFile(
                                path,
                                enums.ImageFormat.jpeg
                            );
                    });
                  }          
                changedPicture = 1;
            });
        }).catch(function (e) {
            console.log(e);
        });
}

`

I am getting the following error:
JavaScript error: file:///app/tns_modules/nativescript-bitmap-factory/BitmapFactory.js:473:48: JS ERROR TypeError: null is not an object (evaluating 'this._nativeObject.size')

Pretty much stating the object I should send to BitmapFactory is null (as you can see, I am using here the string with the file path because this.upload(a) did not work.

Question is, how can I get image object with the new implementation, as I used to get with the old one:
selected.getImage().then((imagesource)=>{ var img = imagesource; })

@tgpetrov
Copy link
Contributor

With v.6.0.3 the image picking intent on android will only display local images (excluding external storages like Photos, Drive, etc.) so they won't get the above mentioned error. If you need support for external files in your app, you are more than welcome to send us a PR to review.

For the empty selection on iOS, please refer to this thread.

@ghost ghost removed the bug label Jul 17, 2018
@falodunos
Copy link

@miguelopezv find my solution here ...

#197 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants