Search Unity

Native Gallery for Android & iOS [Open Source]

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

  1. blaumeisje

    blaumeisje

    Joined:
    Dec 31, 2017
    Posts:
    19
    Got it, thanks a lot. I will check it out.
     
  2. blaumeisje

    blaumeisje

    Joined:
    Dec 31, 2017
    Posts:
    19
    Seems the nativeGallery …/tmp.png files are deleted correctly and there are no additional files in the unity. apps documents folders. No further idea, except that iPhoneIOS automatically keeps a trash copy when deleting (like for any deleted photo) and I have no idea where to find the path for that or how to empty that trash folder without corrupting IOS. If you every hear anything about that, I am happy to know.

    Anyway, a great plugin and thanks for your work creating it and your support here.
     
    yasirkula likes this.
  3. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    What happens if you delete the previous tmp.png image by code before overwriting it? In other words, try inserting
    [[NSFileManager defaultManager] removeItemAtPath:imageSavePath error:nil];
    to here and see if it changes anything.
     
  4. blaumeisje

    blaumeisje

    Joined:
    Dec 31, 2017
    Posts:
    19
    Thanks for the thoughts. In my Unity script, I delete the tmp.png at the path, where I read it before. No errors. Only after deleting it, I allow calling nativeGallery for another pick. So probably, it is deleted already and not overwriting. I also use the Directory to see, if there is any file in the cache path, and nothing is shown. So very probably no overwriting.

    Actually I give the iPhone conversion a break and will come back to it later. Ill try your idea then. Thanks a lot.
     
  5. blaumeisje

    blaumeisje

    Joined:
    Dec 31, 2017
    Posts:
    19
    Finally, found it!!

    Somehow with each picked file from local Galery, there is a .png file with a cryptic filename stored locally under Application.persistentDataPath BUT not ending on /Documents but ending on /tmp . Deleting the tmp.png file from this other path as returned as path from nativeGalery is not enough. These stored png files are NOT deleted, when the app is closed, so the storage becomes bigger and bigger with each pick.

    I will delete also this …/tmp/xxx.png file. Hope that does the trick.
     
  6. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Nice observation! You may try the following to resolve this issue:

    1. Insert this code to here:

    Code (CSharp):
    1. #if UNITY_IOS
    2.     UnityEngine.iOS.Device.SetNoBackupFlag(m_temporaryImagePath);
    3. #endif
    2. And this code to here:

    Code (CSharp):
    1. #if UNITY_IOS
    2.     UnityEngine.iOS.Device.SetNoBackupFlag(m_iOSSelectedImagePath);
    3. #endif
     
    blaumeisje likes this.
  7. jasminepark

    jasminepark

    Joined:
    Aug 21, 2018
    Posts:
    3
    Hi yasirkula, would like to ask whether it is possible to ask for permission to access gallery/photos at the start of the app instead of when im saving the video? For iOS. thank you so much!
     
  8. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Of course, the permission dialog will be shown when you call
    NativeGallery.RequestPermission()
    . On iOS, however, this permission dialog can be shown only once. If user denies the permission, then they must give the permission from Settings (you can use
    NativeGallery.OpenSettings()
    to open the app settings automatically). So I'd recommend you to make sure that user understands why the permission dialog pops up when the app starts.
     
  9. Realillusions

    Realillusions

    Joined:
    Oct 17, 2017
    Posts:
    2
    Hello @yasirkula,
    First thank you for your really nice and open plugin :)
    I'm struguling to change something for the iOS Part : I need to switch from PNG to JPEG and I also need to grab the file without any compression or conversion by iOS.
    I successfully achieved this for the video pick by adding :

    imagePicker.videoExportPreset = AVAssetExportPresetPassthrough;

    I already tried myself by adding in "NativeGallery.mm".
    imagePicker.imageExportPreset = UIImagePickerControllerImageURLExportPresetCurrent;

    and by changing

    [UIImagePNGRepresentation(image) writeToFile:pickedMediaSavePath atomically:YES];

    to
    [UIImageJPEGRepresentation(image, 1.0) writeToFile:pickedMediaSavePath atomically:YES];


    but everytime I get a corrupted image (basicaly 95% is ok, but always at the top the image is corrupted).
     

    Attached Files:

  10. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Your code looks fine to me, I'm as surprised as you are. For testing purposes, you can try changing 1.0 to e.g. 0.9 and see if the line still exists. If the line doesn't exist on the PNG image, you can export the image as PNG and then convert that image to JPEG in Objective-C.
     
  11. Realillusions

    Realillusions

    Joined:
    Oct 17, 2017
    Posts:
    2
    Today I tried with the default "NativeGallery.mm" file and displayed the image in a RawImage before upload to our server and the image looks fine in the App after selection.
    After the upload the PNG image is corrupted... I was thinking PNG files were OK but not so sorry for that.

    I checked the same with Postman for testing our API alone and the image is OK, so our API is out.
    The only thing I see is that there is a corruption when the file is uploaded.

    Here is what I do:

    I first grab the byte array and title of the image returned.


    byte[] imageData;
    string imageName;

    NativeGallery.GetImageFromGallery(path => {
    Debug.Log("Image path: " + path);
    if (path != null) {
    imageData = File.ReadAllBytes(path);
    imageName = Path.GetFileName(path);
    } }, "Choose image");


    Then I have my upload Form that takes the image and two other videos for upload (the weird thing is that the two videos uploaded are not corrupted and uploads fine) :


    WWWForm form = new WWWForm();

    form.AddBinaryData("image", imageData, imageName, "image/png");
    form.AddBinaryData("video", videoData, videoName);
    form.AddBinaryData("video_en", videoDataEn, videoNameEn);

    UnityWebRequest request = UnityWebRequest.Post("apiurl", form);

    yield return request.SendWebRequest();


    Maybe
    form.AddBinaryData
    is not the correct way to upload the image ?
     
  12. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    I don't have any experience with uploading files to a server but you can try using UnityWebRequest instead of WWW to see if it makes any difference.
     
  13. Sczone

    Sczone

    Joined:
    May 9, 2019
    Posts:
    6
    Hello, @yasirkula . I have such a problem, could you give me a solution? I need the code to do what it did before. Now it does not work (the code should save the image in the android device gallery. The code worked, but now I am faced with the problem that UnityWebRequest.Send () is outdated. I would be very grateful for your help!
    upload_2019-7-27_20-16-12.png
     
  14. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    You can simply replace Send with SendWebRequest.
     
  15. Sczone

    Sczone

    Joined:
    May 9, 2019
    Posts:
    6
    @yasirkula If I replace Send the code does not work(
     
  16. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    If the failing part is UnityWebRequest, then I don't think I can resolve this issue as that class is outside the scope of this plugin. You can check logcat to determine whether UnityWebRequest is failing or NativeGallery is failing. You may also try using WWW instead of UnityWebRequest to see if it changes anything.
     
  17. Sczone

    Sczone

    Joined:
    May 9, 2019
    Posts:
    6
    @yasirkula The problem is that the file is saved, but is not displayed as a new image in the gallery. If I want to save another image, it replaces the old image.
     
  18. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Try changing the ".png" parameter to "Image {0}.png".
     
  19. Sczone

    Sczone

    Joined:
    May 9, 2019
    Posts:
    6
    yasirkula likes this.
  20. tuncturel

    tuncturel

    Joined:
    Jul 20, 2012
    Posts:
    47
    Hi @yasirkula

    First and foremost thank you for writing this plugin!

    I'm using your package for iOS and had a question: I'd like to know if the user has given permission to save the image or declined it after being asked so I can show the correct window and give the user feedback.

    I also would like to know if the image has successfully saved or failed to save so I can again tell the user about this.

    I see that the save method returns a permission variable however I have a difficult time understanding how I should react in code when the permission returned is ShouldAsk.

    Thanks again,
    Tunc
     
  21. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
  22. tuncturel

    tuncturel

    Joined:
    Jul 20, 2012
    Posts:
    47
    @yasirkula thanks a bunch! Your suggestions have worked nicely.
     
    yasirkula likes this.
  23. TwerkyMan

    TwerkyMan

    Joined:
    Jan 4, 2017
    Posts:
    2
    Hello. This is an amazing plugin. Though it was easy to set up, I still have one question. Is it possible to load the first frame of a video into Texture2D? I've managed to load the images into Textures, but I'm struggling with the video files. Thanks in advance.
     
  24. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
  25. unicoea

    unicoea

    Joined:
    Feb 18, 2013
    Posts:
    60
    Hi!
    It is very nice.Thank you!
    I want to find out how to open special gallery folder by code when try to pick image?
     
  26. Kiromin

    Kiromin

    Joined:
    Aug 6, 2019
    Posts:
    3
    Hello hope you guys can reply quick

    I need to make a gallery using this plugin

    what I want:
    get all images from the IOS album made by this plugin...
    displays all of the images on a game object from that album....
     
  27. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    @unicoea @Kiromin This plugin doesn't support picking media from a specific album, sorry. @Kiromin If you don't need those images to appear in the Photos app, then you can simply save your photos to a directory inside
    Application.persistentDataPath
    and to fetch all the images in that directory, you can use
    Directory.GetFiles
    . To load an image into a Texture2D, you can either use
    NativeGallery.LoadImageAtPath
    or use
    Texture2D.LoadImage
    .
     
  28. JufJannieApps

    JufJannieApps

    Joined:
    Jan 8, 2016
    Posts:
    26
    Hello,
    I am using this plugin on a very basic shader. The shader is applied to a sprite. but the shader automatically stretches the image to device width and height.
    Is there a way to get the original images dimensions?
    If I use:
    Code (CSharp):
    1.  NativeGallery.ImageProperties test=   NativeGallery.GetImageProperties(path);
    I get the device width and height.
    The code is in the PickImage function.
    I need the original dimensions so I can use the tiling option in shader graph to correct the aspect ratio.

    The puzzle is something like this where you rotate the circles to get the image:
    https://i.etsystatic.com/15062905/r/il/bdbf8e/1798869772/il_fullxfull.1798869772_mhk4.jpg

    The plugin is working fine for the images I am adding myself, but they have the correct aspect ration. The images from the user do not.

    I have a hard time explaining what I mean sorry.

    Thanks
     
  29. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    It is weird that NativeGallery.GetImageProperties returns screen dimensions, maybe you are reading a screenshot's properties? If that function doesn't work, then you can try reading the loaded Texture2D's
    width
    and
    height
    properties.
     
  30. Kiromin

    Kiromin

    Joined:
    Aug 6, 2019
    Posts:
    3
    Thanks for the update.....how do I get the directory of the native gallery....I used it to save the image....
     
  31. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    It is not possible on iOS but there is a workaround on Android. You can make NativeGallery.GetSavePath function public and call
    System.IO.Path.GetDirectoryName(NativeGallery.GetSavePath("Album Name", "dummy.png"))
    .
     
  32. JufJannieApps

    JufJannieApps

    Joined:
    Jan 8, 2016
    Posts:
    26
    Hello, thank you for the reply. i found the problem. I had set the pickImage size to the device height. And the foto's I used all where in the 4:3 ratio so when they were scaled they where the device dimensions. I made a weird sized image tested it again and i got the correct values.
     
    yasirkula likes this.
  33. Kiromin

    Kiromin

    Joined:
    Aug 6, 2019
    Posts:
    3
    So I wont be able to get an album of pictures to the app that I am making on IOS???
     
  34. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Yes, you can't access the folders inside Photos with NativeGallery. If you don't need those images to appear in Photos, then you can simply store the images in
    Application.persistentDataPath
    as I suggested in a previous post.
     
  35. unicoea

    unicoea

    Joined:
    Feb 18, 2013
    Posts:
    60
    Hi!
    Thank you for reply.
    So it mean that, if store the images in Application.persistentDataPath, then need to implement a library management program by self? So it will act like native photo program?
     
  36. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
  37. JufJannieApps

    JufJannieApps

    Joined:
    Jan 8, 2016
    Posts:
    26
    When using this with the iPad I get the following error message if you tap next to the library pop up window. It closes the window and xcode keeps displaying this error:
    Code (CSharp):
    1. FileNotFoundException: File not found at
    2.   at NativeGallery.GetImageProperties (System.String imagePath) [0x00000] in <00000000000000000000000000000000>:0
    3.   at HetPuzzelPlaatje+<>c__DisplayClass13_0.<PickImage>b__0 (System.String path) [0x00000] in <00000000000000000000000000000000>:0
    4.   at NativeGallery+MediaPickCallback.Invoke (System.String path) [0x00000] in <00000000000000000000000000000000>:0
    5.   at NativeGalleryNamespace.NGMediaReceiveCallbackiOS.Update () [0x00000] in <00000000000000000000000000000000>:0
    6. (Filename: currently not available on il2cpp Line: -1)
    Trying to reopen the photo library doesn't work. I even left the scene opent a different scene, but the library won't open again.
    Is this a known issue? Or am I doing something weird.
    Also is there a way to have the pop up library not close if you tap outside of it?
     
    Last edited: Aug 8, 2019
  38. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    You should check if the returned path is null before calling GetImageProperties. This will fix the issue you are having.

    It might be possible to prevent the popup from getting closed when tapped outside of it (google
    UIPopoverController close when click outside
    to learn more) but I believe the dismiss behaviour is the expected behaviour, so I'm not planning to change it at the moment.
     
  39. JufJannieApps

    JufJannieApps

    Joined:
    Jan 8, 2016
    Posts:
    26
    I am checking if it is null. I used your example from git.


    Code (CSharp):
    1.  public void PickImage( int maxSize )
    2.     //private void PickImage( int maxSize )
    3.     {
    4.         NativeGallery.Permission permission = NativeGallery.GetImageFromGallery( ( path ) =>
    5.         {
    6.              
    7.             Debug.Log( "Image path: " + path );
    8.             if( path != null )
    9.             {
    10.                 // Create Texture from selected image
    11.                 deTexture = NativeGallery.LoadImageAtPath( path, maxSize );
    12.                 achtergrond.GetComponent<Renderer>().material.SetTexture("_deTexture", deTexture);
    13.  
    14.                 if( deTexture == null )
    15.                 {
    16.                     Debug.Log( "Couldn't load texture from " + path );
    17.                     return;
    18.                 }
    19.             }
    20.         }, "Select a PNG image", "image/png", maxSize );
    21.  
    22.         Debug.Log( "Permission result: " + permission );
    23.     }
    I will search google for the outside tap option.
     
  40. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    The exception message says that you are calling NativeGallery.GetImageProperties from
    HetPuzzelPlaatje.DisplayClass.PickImage
    function. This is where you should check for null path.
     
  41. JufJannieApps

    JufJannieApps

    Joined:
    Jan 8, 2016
    Posts:
    26
    I only use the function I showed. That is the only "PickImage" function I have. I check for null in there. I guess I am not understanding where to check for null.
     
  42. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Aren't you calling NativeGallery.GetImageProperties anywhere in your project? Please see:

     
  43. JufJannieApps

    JufJannieApps

    Joined:
    Jan 8, 2016
    Posts:
    26
    Ok, posting the code actually fixed it cause I had a debug message in there that called it. But to post the code I cleaned it up and removed it. So when I looked at the posted code there was no more extra call to the path before the null check. And now in the original code it was also gone cause I cleaned it up. But after doing some undos I saw it.
    So thanks. I now know what the problem was. And it is fixed.
     
    yasirkula likes this.
  44. JufJannieApps

    JufJannieApps

    Joined:
    Jan 8, 2016
    Posts:
    26
    Is there a way to get a notification from the script when the library window has finished loading? So when I use async to load a scene I can use that to lat the level display when it has finished showing the library?
     
  45. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Do you mean a callback that is invoked when the gallery displayed via GetImageFromGallery is closed? If so, the first parameter of the function, MediaPickCallback, is invoked after the gallery is closed.
     
  46. JufJannieApps

    JufJannieApps

    Joined:
    Jan 8, 2016
    Posts:
    26
    I am going to be honest here and say . probably. But if so I wouldn't know how to use it. I looked in the code and indeed saw a callback.
    Code (CSharp):
    1. asyncOperation.allowSceneActivation = false;
    Is what I use. I want set it to true when the Image library is finished loading and is shown on the screen. It takes some time to pop up on iPad so I don't want the user to look at an empty screen.
     
  47. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Inside the MediaPickCallback, you can initialize the screen (image library) as you like and call StartCoroutine(SwitchScenes());. Then, define the following coroutine in your script:

    Code (CSharp):
    1. IEnumerator SwitchScenes()
    2. {
    3.     // We are waiting for 2 frames before switching the scene, should be enough for the UI to update itself
    4.     yield return null;
    5.     yield return null;
    6.  
    7.     asyncOperation.allowSceneActivation = true;
    8. }
     
  48. TwerkyMan

    TwerkyMan

    Joined:
    Jan 4, 2017
    Posts:
    2
    Hi again. I wanted to ask about LoadImage function. For me it is exceptionally slow - I have to wait atleast 2 seconds for the image to load. Is there any faster way to load Images into textures? Thanks in advance.
     
  49. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    If you are not using the maxSize property, then I'd recommend you to do so. Otherwise, you can try calling Texture2D.LoadImage with the bytes of the image file (instead of NativeGallery.LoadImageAtPath).
     
  50. ChatAttack

    ChatAttack

    Joined:
    Jun 17, 2019
    Posts:
    1
    Como eu faço pra colocar a imagem no ui?