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:
    2,879
    I think it is self explanatory:

    var props = NativeGallery.GetImageProperties(imagePath);
    Debug.Log( props.width + " " + props.height );
     
  2. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    185
    Cant seem to get SaveImageTo Gallery working or Videos saved. these are my functions

    Code (CSharp):
    1. public void DownloadImage()
    2.         {
    3.            
    4.            
    5.             StartCoroutine(StartImageDownload());
    6.            
    7.            
    8.         }
    9.  
    10.         IEnumerator StartImageDownload()
    11.         {
    12.             UnityWebRequest www = UnityWebRequestTexture.GetTexture(LoadedFeed.ImageURL);
    13.             yield return www.SendWebRequest();
    14.             Texture2D texture = ((DownloadHandlerTexture)www.downloadHandler).texture;
    15.            
    16.             #if UNITY_ANDROID
    17.                 string filePath = Application.persistentDataPath;
    18.                 File.WriteAllBytes(filePath, texture.EncodeToPNG());
    19.                 NativeGallery.SaveImageToGallery(filePath,"Squadron Pics","Squad Pic"+ System.DateTime.Now);
    20.             #elif UNITY_IPHONE
    21.                 string filePath = Application.persistentDataPath;
    22.                 File.WriteAllBytes(filePath, texture.EncodeToPNG());
    23.                 NativeGallery.SaveImageToGallery(filePath,"Squadron Pics","Squad Pic"+ System.DateTime.Now);
    24.            
    25.             #endif
    26.         }
    27.  
    28.        
    29.  
    30.         public void DownloadVideo()
    31.         {
    32.            
    33.            
    34.             StartCoroutine(StartVideoDownload());
    35.            
    36.            
    37.            
    38.         }
    39.  
    40.         IEnumerator StartVideoDownload()
    41.         {
    42.             UnityWebRequest www = UnityWebRequestTexture.GetTexture(LoadedFeed.VideoURL);
    43.             yield return www.SendWebRequest();
    44.             Texture2D texture = ((DownloadHandlerTexture)www.downloadHandler).texture;
    45.            
    46.              #if UNITY_ANDROID
    47.                 string filePath = Application.persistentDataPath;
    48.                
    49.                 NativeGallery.SaveVideoToGallery(filePath,"Squadron Vids","Squad Pic"+ System.DateTime.Now);
    50.             #elif UNITY_IPHONE
    51.                 string filePath = Application.persistentDataPath;
    52.                 NativeGallery.SaveVideoToGallery(filePath,"Squadron Vids","Squad Pic"+ System.DateTime.Now);
    53.            
    54.             #endif
    55.         }
     
  3. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    File.WriteAllBytes is throwing the error, not NativeGallery. Application.persistentDataPath is a folder, your filePath must point to a file inside that folder, not the folder itself. You should use Path.Combine for it. Even better, you can just pass the texture to SaveImageToGallery because you don't need to save it to the filesystem.

    Your video download code is very problematic, you are using GetTexture and texture properties. Video files aren't textures. You must download the video to a file path using DownloadHandlerFile and pass that file path to SaveVideoToGallery. I'd recommend you to google "unity download video" to see how a video can be downloaded.
     
  4. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    185
    I use Unitywebrequest to download a video from firebase. Thats how i get all my videos into my app, that part i know. But i couldnt find where your package uses this file path to return a video to the device gallery is all. ill search a little deeper.
     
  5. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    SaveVideoToGallery calls native functions on Android & iOS to copy the file from the specified filePath to where the Gallery/Photos files are located at. But the code you've posted won't work with video files, it will only work for image files. You have to google "unity download video" so that you know how to download a video to a specified path of your choice, and then pass that path to SaveVideoToGallery.
     
  6. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    185
    So i changed it to this for images. Still not working on device. I dont get a pop up message for a network error or anything but im also not getting the pop up message for image downloaded and of course it isnt in my gallery.

    Code (CSharp):
    1. IEnumerator StartImageDownload()
    2.         {
    3.          
    4.          
    5.  
    6.             UnityWebRequest www = UnityWebRequestTexture.GetTexture(LoadedFeed.ImageURL);
    7.             yield return www.SendWebRequest();
    8.             if(www.isNetworkError || www.isHttpError) {
    9.              
    10.                 AppManager.VIEW_CONTROLLER.ShowPopupMSG(MessageCode.FileNotDownloaded);
    11.             }
    12.             else
    13.             {
    14.              
    15.                 Texture2D texture = ((DownloadHandlerTexture)www.downloadHandler).texture;
    16.              
    17.                 NativeGallery.SaveImageToGallery(texture,"Squadron Pics","Squad Pic"+ System.DateTime.Now);
    18.                 AppManager.VIEW_CONTROLLER.ShowPopupMSG(MessageCode.FileDownloaded);
    19.             }
    20.         }
     
  7. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    185
    Its all working now
     
    yasirkula likes this.
  8. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Happy to hear that. If the issue was related to NativeGallery, please share your findings.
     
  9. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    185
    The issue was the name i was giving it
    "Squad Pic"+ System.DateTime.Now
    woldnt save for some reason, so i just removed that and made it
    image.png
    . Not sure if the .png was the issue but it worked.
     
    yasirkula likes this.
  10. EvanMcGrath

    EvanMcGrath

    Joined:
    Dec 1, 2020
    Posts:
    6
    Hello, I'm trying to set write permissions at runtime on Android, but they seem to always be enabled. My app does not have access to external storage (I have tested with storage set to internal and external, the same issue occurs), nor does it have storage permissions enabled. However, when I use the sample code to take a screenshot, it takes the screenshot and saves it to my device. The app also never pulls up the permissions dialogue. Strangely, the app would ask for read permissions just fine with the sample code. I have skip permissions enabled, so it doesn't ask when the app boots.

    If it helps any, my phone is running Android 10.
     
  11. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    On Android 10 and later, write permission isn't needed. It is a feature of the plugin :D
     
    EvanMcGrath likes this.
  12. igor691

    igor691

    Joined:
    Apr 23, 2018
    Posts:
    11
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class NewBehaviourScript : MonoBehaviour
    6. {
    7.     // Start is called before the first frame update
    8.     void Start()
    9.     {
    10.         NativeGallery.Permission // not see this
    11.     }
    12.  
    13.     // Update is called once per frame
    14.     void Update()
    15.     {
    16.        
    17.     }
    18. }


    I can't connect a namespace.
    I can`t used NativeGallery.Permission
     
    Last edited: Dec 7, 2020
  13. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    There is no namespace. If you are using Assembly Definition Files, you must add NativeGallery.Runtime as reference to your asmdef file. Otherwise, if Unity's Console window doesn't show any errors, then the issue is with Visual Studio and you should google "unity visual studio unity classes red" to resolve it.
     
  14. igor691

    igor691

    Joined:
    Apr 23, 2018
    Posts:
    11
    everything is cool. I rebooted the Visual Studio and now everything sees. thanks.
     
    yasirkula likes this.
  15. si_eta

    si_eta

    Joined:
    Oct 29, 2019
    Posts:
    2
    For everyone who has this problem, you can read this:
    https://forum.unity.com/threads/visual-studio-cannot-find-unity-namespaces.863944/

    My case is on Unity 2020.1.2f1 and VS Code 1.51

    What i've done is,
    1. In Unity, go to Window/Package Manager
    2. Search for your Visual Studio Code Editor package
    3. Downgrade to version 1.1.3 (My case just upgrade to the current version 1.2.3)
    4. Close Unity
    5. Delete your .csproj and .sln files in your project
    6. Open Unity
    7. Reopen VS Code and the errors are gone
     
    Last edited: Dec 10, 2020
    yasirkula likes this.
  16. parimalapari

    parimalapari

    Joined:
    Feb 13, 2019
    Posts:
    1
    My free mode permission is true.



    private const bool PermissionFreeMode = true;



    I am taking screenshot and storing it to Gallery, for that I am using the below line



    Debug.Log("Permission result: " + NativeGallery.SaveImageToGallery(ss, "Sample", "My img {0}.png"));



    I am opening my app in iPhone 11 max pro running on iOS 14. After taking the screenshot it is asking me the allow gallery access permission with three option “Select Photos,”Access all photos ”,”Deny”. If I click the “Select Photos”, app is crashing
     
  17. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Building the app with iOS 14 SDK (Xcode 12) will resolve the issue.
     
  18. asrulazmir96

    asrulazmir96

    Joined:
    Dec 22, 2020
    Posts:
    1
    Hye, 1st of all sorry because I'm a bit new to Unity. Currently I'm trying to create a function to load images from Gallery. Currently I'm able to save a screenshot to a path using your plugin.

    Let say I have list of images stored in Gallery, how do I create UI Image based on and assign each picture to the UI Image?
     
  19. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    If you are trying to create UI Images for each image that you've previously saved to gallery via NativeGallery, it isn't possible. NativeGallery doesn't keep track of the saved images. For this, you need to keep a separate copy of each image in Application.persistentDataPath. Then you can load these images one by one with NativeGallery.LoadImageAtPath.
     
  20. Lilbokeboi

    Lilbokeboi

    Joined:
    Jul 29, 2019
    Posts:
    3
    Goodmorning, i have a question, how can i get a video from Android/IOs gallery? Becausa i cant found the solution to set the videplayer url. Onrutnime in editor works fine with videoPlayer.url = "file://" + path;, but in Android doesnt.
     
  21. Lilbokeboi

    Lilbokeboi

    Joined:
    Jul 29, 2019
    Posts:
    3
    My code is the next one

    Code (CSharp):
    1.  public void AddVideo() {
    2.  
    3.         NativeGallery.Permission permission = NativeGallery.GetVideoFromGallery((path) =>
    4.         {
    5.             Debug.Log("Video path: " + path);
    6.             if (path != null)
    7.             {
    8.                 // Create Texture from selected image
    9.                 Texture2D texture = NativeGallery.LoadImageAtPath(path, 2048);
    10.                 if (texture == null)
    11.                 {
    12.                     Debug.Log("Couldn't load texture from " + path);
    13.                     return;
    14.                 }
    15.                 else
    16.                 {
    17.                     var trackableBehaviour = GameObject.Find("DownloadFromURL");
    18.                     GameObject plane = GameObject.CreatePrimitive(PrimitiveType.Plane);
    19.                     plane.transform.SetParent(trackableBehaviour.gameObject.transform);
    20.                     plane.transform.localScale = new Vector3(plane.transform.localScale.x * ModelSize * 1.6f, plane.transform.localScale.y, plane.transform.localScale.z * ModelSize);
    21.                     plane.transform.localPosition = Vector3.zero;
    22.                     plane.transform.localRotation = Quaternion.Euler(0, 180, 0);
    23.                     var videoPlayer = plane.AddComponent<VideoPlayer>();
    24.                     videoPlayer.source = VideoSource.Url;
    25.                     videoPlayer.url = "file://" + path;
    26.                     plane.gameObject.name = "VideoPlane";
    27.                     videoPlayer.Play();
    28.                     plane.AddComponent<LeanTranslate>();
    29.                     plane.AddComponent<LeanRotate>();
    30.                     plane.AddComponent<LeanScale>();
    31.                     plane.AddComponent<BoxCollider>();
    32.                 }
    33.             }
    34.         }, "Select a video.");
    35.     }
     
  22. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    You should remove this part because it is related to images, not videos:
    Code (CSharp):
    1. Texture2D texture = NativeGallery.LoadImageAtPath(path, 2048);
    2. if (texture == null)
    3. {
    4.     Debug.Log("Couldn't load texture from " + path);
    5.     return;
    6. }
    7. else
     
  23. nnton3

    nnton3

    Joined:
    Sep 8, 2017
    Posts:
    19
    Hi! Ihave some problem wih pick image. Sometimes my app crashes or restarts, when i pick image from gallery.
    Code:
    Code (CSharp):
    1.     public void PickImage(Image _img)
    2.     {
    3.         NativeGallery.GetImageFromGallery((path) =>
    4.         {
    5.             if (path != null)
    6.             {
    7.                 Texture2D texture = NativeGallery.LoadImageAtPath(path, -1, false);
    8.                 if (texture == null)
    9.                     return;
    10.  
    11.                 image1data = texture;
    12.                 userPhoto1.SetActive(true);
    13.                 StartCoroutine(SetTextureToImg(image1data, image1));
    14.             }
    15.         });
    16.     }
    Logs when i normally load photo:


    Logs when load crashes:



    On powerfull devices i can load more images, when on weak devices. Samsung A51 not crashed, but on phones with 2 and less Gb RAM app crash after 2-3 images.
     
  24. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Uncompressed images can consume a lot of memory. Thus, you need to be extra cautious about the following points:
    • Calling
      Destroy(unusedTexture)
      for the Textures that you no longer need (only for the ones that you've generated with LoadImageAtPath) so that they no longer consume RAM
    • Passing a small value like 256 or 512 to LoadImageAtPath's second parameter so that the created Texture is downscaled to that size. You almost never need a 3k Texture that consumes ~50 MB in memory
     
  25. nnton3

    nnton3

    Joined:
    Sep 8, 2017
    Posts:
    19
    That solution didn't help me. I use second param for compressing, but app still crash ((
     
  26. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    What did you change the second parameter to?
     
  27. nnton3

    nnton3

    Joined:
    Sep 8, 2017
    Posts:
    19
    I change 256 and image resolution has decreased
     
  28. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    I'd be surprised if the game crashed again after picking the 3rd image with this change. I'd expect it to crash after maybe picking the 20th image.

    You can check the crash log and see if there are any NativeGallery-related logs there but I'm confident that this issue is related to the device's low memory and unfortunately I can't resolve this issue. If it wasn't caused by low memory, then the game would crash on all devices while picking the first image.
     
  29. nnton3

    nnton3

    Joined:
    Sep 8, 2017
    Posts:
    19
  30. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    You have to destroy Textures created with LoadImageAtPath in order to release their memory.
     
  31. nnton3

    nnton3

    Joined:
    Sep 8, 2017
    Posts:
    19
    If I destroy texture, how i use it?
     
  32. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    You can't. Only the textures that you no longer need are eligible for this.

    I think you should reduce your normal Unity textures' Max Size properties from the Inspector, make sure that they are using Compression (i.e. not set to None) and either make sure that their dimensions are power-of-2 or that they are packed in textures atlases with power-of-2 dimensions. For sprites, creating textures atlases is extremely easy using Sprite Atlas assets.
     
  33. orizvida

    orizvida

    Joined:
    Aug 9, 2018
    Posts:
    21
    Hey,
    I am using your native file picker for unity asset and it is terrific.
    I have one issue though when trying to get an image from iPhone the dialog does open but I cannot see the files in the iPhone from it.
    I imported manually in Xcode the iCloud accessibility.

    Please help
     
  34. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    I've also noticed it. As far as I understand, the file picker dialog doesn't support picking files from Photos. Only iCloud and other document providers are interactable. To pick image and video files, you should use NativeGallery. For other files, you should use NativeFilePicker.
     
  35. nnton3

    nnton3

    Joined:
    Sep 8, 2017
    Posts:
    19
    After analyse memory in profiler I came to the conclusion: all gallery imgs load in scenememory. Imgs in build load in assets. If gallery imgs size more then 15-20 mb app crush. Can u help? How should I use picked texture. I save them in device storage and use every game session. Maybe I can save imgs in specific folder?
     
  36. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    I can't help with the low memory issue. I've already told you about Destroy and maxSize. If those didn't help, you must reduce your assets' size.
     
  37. snurri

    snurri

    Joined:
    Jul 20, 2018
    Posts:
    2
    Hey, I've encountered the same problem lately.
    I even prepared a raw image and created a raw texture, assigned it to the video player and the raw image. I then loaded the video the same way you did, but also added a coroutine that does the following: videoPlayer.Prepare(), yield return new wait until videoPlayer.isPrepared, and finally: videoPlayer.Play(). Nothing happens.
    Loading the video and playing it from Handheld.PlayMovieFullscreen (as shown in the github example) thing works for me, but I can't use it for my example sadly.
    If the yasirkula could help here a bit, it would mean so much.
     
  38. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Playing videos with VideoPlayer isn't really relevant to my plugin. My plugin is only responsible from fetching you the selected video's path and it does it well since you can play the video with Handheld.PlayMovieFullscreen.

    You need to call GetVideoFromGallery (NOT GetImageFromGallery, you are picking a video NOT an image) and then google "unity videoplayer from path". Here's a sample code that may be helpful: https://github.com/yasirkula/UnityNativeGallery/issues/21#issuecomment-380409079
     
    snurri likes this.
  39. snurri

    snurri

    Joined:
    Jul 20, 2018
    Posts:
    2
    I did use GetVideoFromGallery. I will try the sample code you sent now. Thank you.
     
    yasirkula likes this.
  40. orizvida

    orizvida

    Joined:
    Aug 9, 2018
    Posts:
    21
    Hey,
    I used NativeGallery and it works on android and editor but on iPhone it still does not work and not showing any of the images in the gallery.
    Why is that?
     
  41. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    I don't know. It showed images in the gallery on the iPhone I've tested. Are there any error messages in Xcode console maybe?
     
  42. makaka-org

    makaka-org

    Joined:
    Dec 1, 2013
    Posts:
    1,026
    Your asset is used in my project now to load media on face and save photos: AR Masker app.

     
    LYNXS_ and yasirkula like this.
  43. Marnelle

    Marnelle

    Joined:
    Apr 14, 2015
    Posts:
    17
    Hi! I'm an getting error when I'm trying to pick an image

    01-05 20:33:37.259: E/Unity(25292): UnauthorizedAccessException: Access to the path "/storage/emulated/0/DCIM/Facebook/FB_IMG_1608605913734.jpg" is denied.

    Could you help me?
    My code:
    Code (CSharp):
    1. NativeGallery.Permission permission = NativeGallery.CheckPermission(true);
    2.             if (permission == NativeGallery.Permission.Granted)
    3.             {
    4.                 PickImage(2048);
    5.             }
    6.             else
    7.             {
    8.                 permission = NativeGallery.RequestPermission(true);
    9.                 if (permission == NativeGallery.Permission.Granted)
    10.                 {
    11.                     PickImage(2048);
    12.                 }
    13.             }
    Manifest:
    Code (CSharp):
    1. <meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="true" />
    2.  
    3. <provider
    4.           android:name="com.yasirkula.unity.NativeCameraContentProvider"
    5.           android:authorities="MY_UNIQUE_AUTHORITY"
    6.           android:exported="false"
    7.           android:grantUriPermissions="true"/>
    8.  
    9. <uses-permission android:name="android.permission.CAMERA" />
    10.   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" tools:node="replace"/>
    11.   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace"/>
    Native camera works great btw
     
    Last edited: Jan 5, 2021
  44. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Is the plugin up-to-date? If it is, can I see the relevant parts of PickImage?
     
  45. TheDylonFive

    TheDylonFive

    Joined:
    Mar 27, 2015
    Posts:
    8
    Hey there! Great plugin like everyone else said! haha, so Ive sorted through the 21 pages of comments and didn't see an answer for this:

    I'm trying to NOT show images that have been selected already, perhaps ill save them to PlayerPrefs or something, but I can take care of the data and figuring out which photos have already been selected, but I cant figure out how to specify that a picture not be loaded by name or maybe by ID, do you have any help for me by chance? :)

    This is for iOS if that matters at all
     
  46. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    On iOS, UIImagePickerViewController (iOS 13-) and PHPickerViewController (iOS 14+) are used and AFAIK, you can't filter the presented media as you suggested with these tools.
     
    TheDylonFive likes this.
  47. Marnelle

    Marnelle

    Joined:
    Apr 14, 2015
    Posts:
    17
    It's up-to-date (1.6.1)

    Code (CSharp):
    1. private void PickImage(int maxSize)
    2.     {
    3.         NativeGallery.Permission permission = NativeGallery.GetImageFromGallery((path) =>
    4.         {
    5.             if (path != null)
    6.             {
    7.                 Texture2D texture = NativeGallery.LoadImageAtPath(path, maxSize, false); //ERROR IS HERE
    8.                 if (texture == null)
    9.                 {
    10.                     Debug.Log("Couldn't load texture from " + path);
    11.                     return;
    12.                 }
    13.  
    14.                 LoadTextureToImage(texture);
    15.             }
    16.         }, "Choose a photo", "image/*");
    17.  
    18.         Debug.Log("Permission result: " + permission);
    19.     }
     
  48. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    I'm deliberately checking if picked files are accessible via File API, so I don't have any ideas why this is happening, honestly :/

    P.S. Seen this somewhere else. Does adding
    android:requestLegacyExternalStorage="true"
    to
    application
    tag in AndroidManifest resolve the issue?

    P.P.S. And can you reproduce the issue on an empty project?
     
    Last edited: Jan 6, 2021
  49. Marnelle

    Marnelle

    Joined:
    Apr 14, 2015
    Posts:
    17
    android:requestLegacyExternalStorage="true"
    to
    application
    tag in AndroidManifest

    This one did a trick, thank you!
     
    yasirkula likes this.
  50. LYNXS_

    LYNXS_

    Joined:
    Mar 30, 2019
    Posts:
    2
    Can you teach me how to record video without UI? thank you