Search Unity

Native Gallery for Android & iOS [Open Source]

Discussion in 'Assets and Asset Store' started by yasirkula, Feb 28, 2018.

  1. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    Did you change the value of Write Permission in Player Settings, though?
     
  2. Entsking

    Entsking

    Joined:
    Apr 29, 2018
    Posts:
    3
    But the image data is in the phone storage. The simple code example that you give in the firsts comments about open the gallery should work well in any case? if it dont, can you give me some insight about what to do? cause i gessed it was to be easy to just open an image from the gallery but i'm stuked on it XD
     
  3. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    The plugin will only work with the External (SDCard) permission. Don't let the word SDCard confuse you, External allows the plugin to access the files in Gallery.
     
    Entsking likes this.
  4. HnS_Alexa

    HnS_Alexa

    Joined:
    Jan 23, 2019
    Posts:
    1
    Screenshot not at all saving while taking build to android phones but it works fine in editor @yasirkula
     
  5. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    Try using logcat and/or this asset to see if there are any error messages
     
  6. adminsh123

    adminsh123

    Joined:
    Jul 16, 2017
    Posts:
    1
    hi, thanks for this plugin
    I want to know how can I open some specific folder with Android Native gallery? i dont want use image as texture i just want my app show all of images in the folder
     
  7. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    It is not possible, sorry.
     
  8. unity_sSPz4cLF4k7NsQ

    unity_sSPz4cLF4k7NsQ

    Joined:
    Apr 18, 2019
    Posts:
    4
    Thank you for the useful plugin!

    First of all, sorry for may be stupid question.
    Could you please say how is it possible, for picture that is picked from the gallery, to appear not in the middle of the screen on a random quad, but on a specific place on the screen on Image or rawImage.
    Thank you very much in advance
     
  9. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    Thanks! In the example code, the line
    Texture2D texture = NativeGallery.LoadImageAtPath( path, maxSize );
    creates a texture from the picked image. If this texture is not null, you can assign it to a RawImage's texture property or to the mainTexture property of an object's Renderer's material.
     
  10. unity_sSPz4cLF4k7NsQ

    unity_sSPz4cLF4k7NsQ

    Joined:
    Apr 18, 2019
    Posts:
    4
    Could you please help with the code?
     
  11. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    Where do you try to assign the texture to?
     
  12. unity_sSPz4cLF4k7NsQ

    unity_sSPz4cLF4k7NsQ

    Joined:
    Apr 18, 2019
    Posts:
    4
    Not to the random quad that appears in the middle of the screen, but to already existing image element(UI) that was created by me.

    Thank you very much in advance! I am trying to solve this problem already for a very long time.
     
  13. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    Just create a public
    RawImage rawImage;
    variable and call
    rawImage.texture = texture;
    in your code:

    Code (CSharp):
    1. public RawImage image;
    2.  
    3. private void PickImage( int maxSize )
    4. {
    5.     NativeGallery.GetImageFromGallery( ( path ) =>
    6.     {
    7.         Debug.Log( "Image path: " + path );
    8.         if( path != null )
    9.         {
    10.             // Create Texture from selected image
    11.             Texture2D texture = NativeGallery.LoadImageAtPath( path, maxSize );
    12.             if( texture == null )
    13.             {
    14.                 Debug.Log( "Couldn't load texture from " + path );
    15.                 return;
    16.             }
    17.            
    18.             // Optional: free up the memory consumed by the current Texture
    19.             // assigned to the RawImage
    20.             Destroy( image.texture );
    21.  
    22.             // Assign the texture to the RawImage
    23.             image.texture = texture;
    24.         }
    25.     }, "Select an image", "image/*", maxSize );
    26. }
     
  14. unity_sSPz4cLF4k7NsQ

    unity_sSPz4cLF4k7NsQ

    Joined:
    Apr 18, 2019
    Posts:
    4
    Should I also change something in the RawImages' Inspector?
     
  15. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    Not at all, you just need to position its RectTransform as you wish.
     
  16. Scientistca

    Scientistca

    Joined:
    Apr 22, 2019
    Posts:
    1
    Hey! Awesome plugin, just what I was looking for.

    I just wanted to ask one question. Is it possible to call PickImage buy pressing the button(not the 2/3 of the screen)? What should I do for that?

    Thank you!
     
  17. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    Of course, you can make the PickImage function public and add it to the button's On Click event.
     
  18. tal1

    tal1

    Joined:
    Apr 28, 2018
    Posts:
    2
    hey! great plugin, but when i use it to get a picture from gallery it's doesn't work. i have checked and pickedImage is null.
    Here's the script:
    Code (CSharp):
    1.  public Texture2D pickedImage;
    2.     public GameObject[] images;
    3.  
    4.     // Start is called before the first frame update
    5.     void Start()
    6.     {
    7.         PickImageFromGallery(1024);
    8.         for (int i = 0; i < 4; i++) {
    9.             images[i].GetComponent<Image>().material.mainTexture = pickedImage;
    10.         }
    11.     }
    12.  
    13.     public void PickImageFromGallery(int maxSize)
    14.     {
    15.         NativeGallery.GetImageFromGallery((path) =>
    16.         {
    17.             if (path != null)
    18.             {
    19.                 // Create Texture from selected image
    20.                 pickedImage = NativeGallery.LoadImageAtPath(path, maxSize);
    21.             }
    22.         }, maxSize: maxSize);
    23.     }
     
  19. tal1

    tal1

    Joined:
    Apr 28, 2018
    Posts:
    2
    and i am using nox app player with android 5
     
  20. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    NativeGallery.GetImageFromGallery is an asynchronous function, you need to move the for-loop inside the
    if(path!=null)
    condition.
     
  21. psy4lyf

    psy4lyf

    Joined:
    Mar 11, 2019
    Posts:
    5
    Hi again. I am trying to do some processing on an image I have selected from the native gallery.

    1) When I try to use the openCV function Mat img = Unity.TextureToMat(loadedTextureFromGallery), I receive a notice that the texture is not readable, and that line causes a crash.

    2) When I try to read the image from the temporary path, "path", using Cv2.ImRead(path), it does seem read the image, but the image file seems to be empty/no data. Then when I try to do more processing on it, the script crashes:

    Mat img1 = Cv2.ImRead(path); (log output)--> Mat [ 0*0*CV_8UC1, IsContinuous=False, IsSubmatrix=False, Ptr=0xffffffff80345300, Data=0x0 ]
    ...
    Mat imgGray = new Mat();
    Cv2.CvtColor(img1, imgGray, ColorConversionCodes.BGR2GRAY); --> (log output: OpenCV Error: Assertion failed (scn == 3 || scn == 4) in void cv::cvtColor(cv::InputArray, cv::OutputArray, int, int) ---> crash)

    My question is, what is the best way to use the image selected from the gallery, and work with it for processing?

    Code (CSharp):
    1. public class TryingOpenCV : MonoBehaviour
    2.     {
    3.         public RawImage display;
    4.  
    5.         public void ProcessImageClick()
    6.         {
    7.             LoadAndProcessGalleryImage(512);
    8.         }
    9.  
    10.         public void LoadAndProcessGalleryImage(int maxSize)
    11.         {
    12.             NativeGallery.Permission permission = NativeGallery.GetImageFromGallery((path) =>
    13.             {
    14.                 Debug.Log("Image path: " + path);
    15.                 if (path != null)
    16.                 {
    17.                     // Create Texture from selected image
    18.                     Texture2D unproc2D_Texture = NativeGallery.LoadImageAtPath(path, maxSize);
    19.  
    20.                     if (unproc2D_Texture == null)
    21.                     {
    22.                         Debug.Log("Couldn't load texture from " + path);
    23.                         return;
    24.                     }
    25.  
    26.                     display.texture = unproc2D_Texture; //display the texture on the Raw Image in the scene
    27.  
    28.                     Texture2D contourTex = new Texture2D(unproc2D_Texture.width, unproc2D_Texture.height, TextureFormat.RGB24, false);
    29.  
    30.                     Debug.Log("TextureType: " + unproc2D_Texture);
    31.                     Debug.Log("Texture Is Readable?: " + unproc2D_Texture.isReadable);
    32.  
    33.                  //   Mat img = Unity.TextureToMat(unproc2D_Texture); -->causes crash because the texture is not readable
    34.  
    35.                     //Convert image to grayscale
    36.  
    37.                     Mat img1 = Cv2.ImRead(path);
    38.                     Debug.Log("after imRead, mat type " + img1);
    39.  
    40.                     //Convert image to grayscale
    41.  
    42.                     Mat imgGray = new Mat();
    43.  
    44.                     Cv2.CvtColor(img1, imgGray, ColorConversionCodes.BGR2GRAY); //causes crash because img1 is empty?
    45.                 }
    46.             }, "Select a PNG image", "image/png", maxSize); //allow selection of the image from gallery
    47.  
    48.             Debug.Log("Permission result: " + permission);
    49.         }
    50.     }
     
  22. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    1) Try using
    NativeGallery.LoadImageAtPath(path, maxSize, false);

    2) I don't know why this happens, sorry :/
     
    psy4lyf likes this.
  23. psy4lyf

    psy4lyf

    Joined:
    Mar 11, 2019
    Posts:
    5
    @yasirkula you're a hero! Your solution to 1) solved everything I needed to to processing of the texture. I should have seen the markTextureNonReadable bool option in LoadImageAtPath. Thanks for covering all the details with this tool.
     
  24. apev

    apev

    Joined:
    Feb 6, 2017
    Posts:
    4
    Hi @yasirkula, your plugin seems exactly like what I need, and after reading through this thread I can see you've been on top of support! I'm working on an iOS app, and am trying to move a generated video file from a subfolder within persistentdatapath to the gallery.

    After getting your plugin off the Asset store, and using the 'SaveVideoToGallery' method, I get an 'UnauthorizedAccessException' in Xcode saying that access to the existing file path is denied.

    I have confirmed I have both read and write access to the device, as well as read/write access to photos. A permissions check with 'CheckPermissions()' returns 'Granted'. I also confirmed both the file and the directory exist, and am using Path.Combine to create the file path from the persistent data path and the file name, so it should be consistent.

    The test device I am using has iOS 12. I tried testing while not connected to my build machine, but didn't get any difference in results. I'm at a bit of a loss as to what I should try next, and what the issue could be. Should I use the version from your public repo instead of the Asset Store version instead?

    Any ideas would be appreciated. Thanks!
     
  25. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    Both versions are identical at the moment, so using the Asset Store version is fine.

    Does the example code on GitHub work for saving screenshots to Photos? How exactly are you calling SaveVideoToGallery? Can you add Debug.Log's to that function (and the functions it calls) to pinpoint the problematic line (or maybe using a Development build would automatically give that information)?
     
  26. apev

    apev

    Joined:
    Feb 6, 2017
    Posts:
    4
    Code (CSharp):
    1.         void MoveVideoToGallery()
    2.         {
    3.             NativeGallery.Permission hasPermission = NativeGallery.CheckPermission();
    4.             if (hasPermission == NativeGallery.Permission.Granted)
    5.             {
    6.                 Debug.Log("Permission granted");
    7.                 //folderLocation is Application.persistentDataPath + "/videos/"
    8.                 if (Directory.Exists(folderLocation))
    9.                 {
    10.                     //save location is Application.persistentDataPath + "/videos/" + "testvideo.mp4"
    11.                     string filename = "testvideo.mp4";
    12.                     if (File.Exists(saveLocation))
    13.                     {
    14.                         NativeGallery.Permission moveToGallery = NativeGallery.SaveVideoToGallery(saveLocation, "Videos", filename);
    15.                         //^^ this is where the access denied error is thrown, so the below debug never gets called
    16.                         Debug.Log("Tried to move to gallery, Permission returned: " + moveToGallery.ToString());
    17.                     }
    18.                     else
    19.                     {
    20.                         Debug.Log("File not found");
    21.                     }
    22.                 }
    23.                 else
    24.                 {
    25.                     Debug.Log("Directory not found");
    26.                 }
    27.             }
    28.             else
    29.             {
    30.                 Debug.Log("Permission not granted");
    31.             }
    32.         }
    Thanks for the quick response! Above is my stripped down code I've been trying to debug with. I gets to the SaveVideoToGallery call and that is when I get the access error. I will try testing the screenshot saving example and report back.
     
  27. apev

    apev

    Joined:
    Feb 6, 2017
    Posts:
    4
    The screenshot saving works flawlessly, right out the gate. Makes me think that this may not be an issue related to the use of the plugin. I'm going to look into if the video file I have generated is the problem somehow, perhaps with specific file settings. Thanks for the help though, confirming that the screenshots work was a good call. Paring down what the issue could be is helpful regardless!
     
  28. nikosurfing

    nikosurfing

    Joined:
    Mar 11, 2014
    Posts:
    34
    Hi, thank you very much for your info. I swiched from Unity 2018.3.13 to 2018.3.1f1 and it works. You save my time.
    @yasirkula : Still great asset, i've been using it for almost 2 years i forgot Lol. Please add support for latest unity (for callback issue). Thank you

    EDIT: Sorry, it was my fault! It works on latest Unity Unity 2018.3.14 26 Apr, 2019. Just update this asset and clean install unity. AWESOME!
     
    Last edited: Apr 27, 2019
    yasirkula likes this.
  29. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    @apev I'm guessing it is related to this line: https://github.com/yasirkula/UnityN...b/Plugins/NativeGallery/NativeGallery.cs#L331

    I haven't encountered UnauthorizedAccessException on this line before, it is simply creating a temporary copy of the file and then getting rid of it once it is saved to Photos.

    Are you sure that the video is not currently being processed while you are calling SaveVideoToGallery (some plugins may save the video asynchronously)? Can you put Debug.Log's around the line I mentioned and see what
    File.Exists(existingMediaPath)
    and
    File.Exists(path)
    return?
     
  30. JavierTeckdes

    JavierTeckdes

    Joined:
    Aug 22, 2017
    Posts:
    4
    Hi @yasirkula, Thank you very much for your plugin. Is there A way to use it to retrieve other files (Like a gltf 3d model) Im currently using your plugin to retrieve image path and i'td be cool to use the same plugin to get other files.
     
  31. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    nikosurfing likes this.
  32. JavierTeckdes

    JavierTeckdes

    Joined:
    Aug 22, 2017
    Posts:
    4
    Thanks! :D but Im needing something seamless for the user, and for ios & android. Just like whatsapp does
     
  33. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    Unfortunately I don't have any solutions for this :/
     
  34. alfms0725

    alfms0725

    Joined:
    Mar 21, 2018
    Posts:
    2
    Thanks for the good material. And please understand that it is awkward to use a translator. I have a question Do you have a way to get pictures directly from the camera to the album like the attached image?

    And when you select an album, can you make the gallery application selection window open only once?
     

    Attached Files:

    Last edited: May 8, 2019
  35. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    You can use NativeCamera to take pictures using the camera and then save these images to the Gallery via NativeGallery.

    In your second question, do you mean removing the popup that prompts the user to select an app to pick the image with? If so, I'm afraid you can't get rid of that popup, at least not without making changes to the Android JAR source code.
     
  36. alfms0725

    alfms0725

    Joined:
    Mar 21, 2018
    Posts:
    2
    Thank you. Your answer was helpful. One more thing I have to ask, what parts need to be fixed before the album comes up on the camera. My album does not appear on my screen at this time.
     

    Attached Files:

  37. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    If this screenshot is taken from NativeCamera, then why are you looking for a Gallery icon there? Camera's purpose is to take a photo. Are you looking for a solution where user can pick a photo from either the Gallery or the camera?
     
  38. sergiovgg

    sergiovgg

    Joined:
    May 7, 2018
    Posts:
    3
    in xcode of IOS have this error :

    discovery] errors encountered while discovering extensions: Error Domain=PlugInKit Code=13 "query cancelled" UserInfo={NSLocalizedDescription=query cancelled}


    and I use this example code
    Code (CSharp):
    1.  public void PickImage(int maxSize)
    2.     {
    3.         NativeGallery.Permission permission = NativeGallery.GetImageFromGallery((path) =>
    4.         {
    5.             Debug.Log("<color=yellow>Image path:</color> " + path);
    6.             if (path != null)
    7.             {
    8.                 Debug.Log("ingreso " + "------>" + path);
    9.                 // Create Texture from selected image
    10.                 Texture2D texture = NativeGallery.LoadImageAtPath(path, maxSize);
    11.  
    12.                 if (texture == null)
    13.                 {
    14.                     Debug.Log("Couldn't load texture from " + path);
    15.                     return;
    16.                 }
    17.  
    18.                 // Assign texture to a temporary quad and destroy it after 5 seconds
    19.                 GameObject quad = GameObject.CreatePrimitive(PrimitiveType.Quad);
    20.                 quad.transform.position = Camera.main.transform.position + Camera.main.transform.forward * 2.5f;
    21.                 quad.transform.forward = Camera.main.transform.forward;
    22.                 quad.transform.localScale = new Vector3(1f, texture.height / (float)texture.width, 1f);
    23.                 quad.AddComponent<MeshCollider>();
    24.                 Material material = image.GetComponent<Image>().material;
    25.  
    26.                 if (!material.shader.isSupported) // happens when Standard shader is not included in the build
    27.                     material.shader = Shader.Find("Legacy Shaders/Diffuse");
    28.  
    29.                 material.mainTexture = texture;
    30.  
    31.                 Destroy(quad, 5f);
    32.  
    33.                 // If a procedural texture is not destroyed manually,
    34.                 // it will only be freed after a scene change
    35.                 Destroy(texture, 5f);
    36.             }
    37.         }, "Select a PNG image", "image/png", maxSize);
    38.  
    39.         Debug.Log("Permission result: " + permission);
    40.     }
     
  39. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    Does the image picker UI not appear at all?
     
  40. sergiovgg

    sergiovgg

    Joined:
    May 7, 2018
    Posts:
    3
    Yes the UI of iOS , but do not load the image in unity 3d
     

    Attached Files:

  41. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    Maybe it is an SRP issue. Try putting a cube inside your scene so that the shader of the default material also gets distributed with the game.
     
  42. sergiovgg

    sergiovgg

    Joined:
    May 7, 2018
    Posts:
    3
    ok.... but, no load the texture of the imagen of galley selected
     
  43. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    Even after adding a cube to the scene? How about testing on a new project using legacy render pipeline (i.e. not using HDRP or LWRP); does it work then?
     
  44. Amorino

    Amorino

    Joined:
    Jul 11, 2013
    Posts:
    3
    Hello, first of all, awesome plugin, thanks.

    Second, one question: Is it possible to list both videos and images? Right now you have GetImageFromGallery and GetVideoFromGallery, is it possible to have a GetImageOrVideoFromGallery?
     
  45. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    Unfortunately not, sorry.
     
  46. montaal1996

    montaal1996

    Joined:
    May 2, 2019
    Posts:
    1
    Hey, I'm trying to save a video into the iOS Gallery, but it is not being saved, it creates the folder but there is nothing in it. I know the file is on the folder where I'm thinking because it is being played by the same app from the same path. Has anyone else had the same issue? It is working perfectly on Android though
     
  47. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    Does saving an image work, e.g. when using the example code?
     
  48. fuzzl

    fuzzl

    Joined:
    May 13, 2019
    Posts:
    4
    First of all i have to thank you for your awesome work, it already helped me so much. Thanks!


    But i have a question for iOS .. is it possible that it doesnt save the images all over again ? I made a button to save pictures to gallery but how can i make sure that these pictures aren't already in this gallery ? Is there a way to do this?
     
    yasirkula likes this.
  49. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,056
    It is not possible :/
     
  50. fuzzl

    fuzzl

    Joined:
    May 13, 2019
    Posts:
    4
    oh my gosh... still a nice plugin. but i have the problem that the apple review team want me to make my image markers (augmented app) accessable without download.. i thought i could solve it like this but now i have no clue again ^^