Search Unity

  1. We would like to hear your feedback about Unity and our products. Click here for more information.
    Dismiss Notice

Native Camera for Android & iOS [Open Source]

Discussion in 'Assets and Asset Store' started by yasirkula, May 2, 2018.

  1. LS0

    LS0

    Joined:
    Mar 8, 2019
    Posts:
    3
    Yeah it worked fine with a fresh project.
    Fixed now, the issue was that I'd set MY_UNIQUE_AUTHORITY in the manifest to my bundle identifier as suggested in your installation instructions, but also done the same when installing your ShareContentProvider previously, so they weren't unique. just added a few extra chars on the android:authorities tag and it works a dream, thanks!
     
    yasirkula likes this.
  2. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    @hitarthdoc1994 By soft close, do you mean it restarts itself after closing the camera? I encounter this issue only on devices with low memory. OS automatically closes background activities if there is not enough memory for the foreground activity.

    Saying photo = null; won't GC the photo, its C++ data will remain there. But that data should indeed vanish after a Resources.UnloadUnusedAssets call, so I'm not about the root of the issue. You can try using a memory profiler to see the memory usage of the app, though. See if it gets a soft close after a memory spike.
     
  3. unity_4ydI3ikQ6-qZng

    unity_4ydI3ikQ6-qZng

    Joined:
    Sep 7, 2018
    Posts:
    1
    Hey man, thank you for this plugin. Your work is amazing and much appreciated.
     
    yasirkula likes this.
  4. hitarthdoc1994

    hitarthdoc1994

    Joined:
    Dec 17, 2015
    Posts:
    14
    @yasirkula
    Yes. That happened with us even on high memory devices and with a few apps running in the background.

    I am also destroying the loaded texture before unloading unused Resources.

    There are no memory spikes in the editor while using only
    NativeCamera.LoadImageAtPath()
    to test.

    Thanks for clearing the use case for the soft closing of the application. Please be kind enough to post any methods to prevent any such OS exits if there are or might come in your knowledge in the future.
     
  5. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    Can you also use Android Studio's profiler to see if it is a memory issue? I don't know any other causes for a soft close, to be honest.
     
  6. psy4lyf

    psy4lyf

    Joined:
    Mar 11, 2019
    Posts:
    5
    Hello @yasirkula . Thank you so much for you Native Camera and Native Gallery plugins. I have implemented them in our phone apps for Android and iOS, and they make something that is pretty comprehensive, seem much easier.

    I would like to take a picture with some guidelines - think square box for mobile check deposit. Is there a way to overlay a raw image on the Native phone camera, the way banking apps do it? I a scene I have, I have the camera view displayed on a raw image, but once I access the Native phone camera with a button, it leaves the scene to go to the native camera, and the overlay/guidelines disappear. I'd like to keep the guidelines there when taking the photo, but save the photo without guidelines (why a screenshot won't work). Can this be done?
     

    Attached Files:

  7. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    Unfortunately not. NativeCamera doesn't support any overlays. The image is captured via the native camera app and thus, the plugin's functionality is limited by the native camera app's functionality.
     
  8. psy4lyf

    psy4lyf

    Joined:
    Mar 11, 2019
    Posts:
    5
    Shoot! Alright, thanks for your quick response. Again, great work with the plugins!
     
    yasirkula likes this.
  9. edgars_unity

    edgars_unity

    Joined:
    Feb 7, 2019
    Posts:
    15
    Does this plugin using native camera embed images with metadata such as Exif? I need to be able to geo tag images so hoping by connecting to native camera I can do it
     
    Last edited: Apr 17, 2019
  10. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    The image comes from the camera. On Android, at least, if geo tagging is enabled in the camera app's settings, then the images should have such exif metadata.
     
    edgars_unity likes this.
  11. edgars_unity

    edgars_unity

    Joined:
    Feb 7, 2019
    Posts:
    15
    Ok worked flawlessly. Question is there a way for me to constantly take images once the default camera opens. I.e every second take picture? Can I access any camera params? Mainly interested in some way to access the device button to take the image I could then control frequency through the button then...
     
    Last edited: Apr 18, 2019
  12. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    I don't think it is possible. If there is burst image functionality in your camera app, you may try taking pictures in a burst to see how it goes but I don't think you'll be able to achieve the desired result.
     
  13. adre

    adre

    Joined:
    Mar 28, 2014
    Posts:
    37
    Hello @yasirkula,
    is it possible to record a video specifying that must record in 1920x1080 25fps?

    Resolution and FPS must always be these to append video to other videos in FFMPEG.
     
  14. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    Unfortunately not. NativeCamera just sends a quality level (Low, Medium, High) to the camera application and the rest is handled by the native camera app. I don't think older devices can record videos in 1080p anyways.
     
  15. AdrianoAlemanno

    AdrianoAlemanno

    Joined:
    Nov 6, 2018
    Posts:
    6
    Hello there,
    i'm sorry but i'm back again to ask for your help.
    Trying to build my project for iOS and in xcode i'm having this issue:

    bitcode bundle could not be generated because 'project_folder/Libraries/Plugins/iOS/libNativeToolkit.a(Camera.o)' was built without full bitcode. All object files and libraries for bitcode must be generated from Xcode Archive or Install build file 'project_folder/Libraries/Plugins/iOS/libNativeToolkit.a' for architecture arm64

    Could it be something related to you plugin?
    Thanks a lot for your work and your support
     
  16. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    First time seeing this. What happens when you remove NativeCamera from your project and build again?
     
  17. AdrianoAlemanno

    AdrianoAlemanno

    Joined:
    Nov 6, 2018
    Posts:
    6
    Sorry, after lots of investigations about the problem i found that it is related to another plugin ("libnativetoolkit.a" and "camera.o" were not the right keywords to look for the error).
    i want to thank you again for your awesome plugins that "just" work fine!
     
    yasirkula likes this.
  18. abeldantas

    abeldantas

    Joined:
    Jul 28, 2013
    Posts:
    12
    On Unity 2018.3.13f1 on an android Xiaomi device I followed all the steps and no matter what I get 'Permission result: Denied'.

    Manifest in staging looks good.
    Opened settings and gave permission for camera.
    Not sure if it is the device or what.
     
  19. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    How about other devices or emulators?
     
  20. Farhan-Aqeel

    Farhan-Aqeel

    Joined:
    Aug 18, 2014
    Posts:
    2
    Hi YasirKula, I am currently using both of your assets. it is indeed one of the best thing i've found on assetstore.
    i am getting a similar error

    "Can't find ContentProvider, camera is inaccessible"


    This is my AndroidManifest from the plugins/android folder. Searched on gthub and other forums but unable to find the issue.

    Code (CSharp):
    1. <?xml version="1.0" encoding="utf-8"?>
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    3. package="com.unity3d.player">
    4.  
    5.      <application
    6.     android:icon="@drawable/app_icon"
    7.     android:label="@string/app_name">
    8.         <activity android:name="com.unity3d.player.UnityPlayerNativeActivity"
    9.                   android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
    10.             <intent-filter>
    11.                 <action android:name="android.intent.action.MAIN" />
    12.                 <category android:name="android.intent.category.LAUNCHER" />
    13.             </intent-filter>
    14.             <meta-data android:name="android.app.lib_name" android:value="unity" />
    15.             <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />
    16.         </activity>
    17.   </application>
    18.  
    19.  
    20.   <provider
    21.   android:name="com.yasirkula.unity.NativeCameraContentProvider"
    22.   android:authorities="geekscreative"
    23.   android:exported="false"
    24.   android:grantUriPermissions="true" />
    25.  
    26.   <uses-permission android:name="android.permission.CAMERA" />
    27.     <uses-feature android:name="android.hardware.camera" />
    28.    
    29.     <uses-permission android:name="android.permission.INTERNET" />
    30.     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    31.    
    32.     <uses-permission android:name="android.permission.FLASHLIGHT"/>
    33.  
    34.    
    35. </manifest>
     
  21. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    You need to put the provider inside the
    <application>...</application>
    tags. Other than that, your manifest looks fine.
     
  22. pedro_eloideias

    pedro_eloideias

    Joined:
    Feb 18, 2019
    Posts:
    7
    Hello man, your plugins are something else, let me tell you that, I just found about this one, I'm having a little trouble with it. It's working fine, the problem is, whenever I take a picture, I save the path of this image, so that later, I'll send it to my server, but the problem is that, when the second photo is taken, it will have the save path as the first image, and then it'll send the same image (the second one). There's a way that I can change the path, each time a photo is taken ?
     
    Last edited: May 29, 2019
  23. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    Yes, each photo is saved to the same temporary location. If you want, you can move a photo to another location like Application.persistentDataPath with a unique name so that it won't get overwritten. For example:

    Code (CSharp):
    1. public static string MoveFile( string path )
    2. {
    3.     string saveDir = Application.persistentDataPath;
    4.     string filenameFormatted = "Photo {0}" + Path.GetExtension( path );
    5.    
    6.     int fileIndex = 0;
    7.     string newPath;
    8.     do
    9.     {
    10.         newPath = Path.Combine( saveDir, string.Format( filenameFormatted, ++fileIndex ) );
    11.     } while( File.Exists( newPath ) );
    12.  
    13.     File.Move( path, newPath );
    14.     return newPath;
    15. }
     
  24. BradleyHean1

    BradleyHean1

    Joined:
    Apr 27, 2015
    Posts:
    2
    Really appreciate this plugin. I also use your NativeGallery plugin and both work flawlessly! I tried other plugins before yours and they all failed silently without any debugs being printed, super annoying. yours worked first time and everytime.
     
    yasirkula likes this.
  25. ardevelop

    ardevelop

    Joined:
    Feb 20, 2019
    Posts:
    2
    Hello!
    I cannot get Exif data from photo picked from Ios Camera. Plugin do not save it. Can you help me, which settings, or strokes of codes edit, to make that?
    Thanks!
     
  26. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    Which Exif data is missing? How are you trying to read that data?
     
  27. ardevelop

    ardevelop

    Joined:
    Feb 20, 2019
    Posts:
    2
    All Exif data missing on ios. I am trying do 2 things:
    1. Copy picked photo to Application.persistentDataPath folder an then upload to drive. But when opening in drive photo does not contains any info(only width_height)
    2. Just reading exif data with lib ExifLib(link below), than prints correct data on android, but not prints on ios(maybe no data)
    https://github.com/dxball/TestUnityExif

    Also, you can use online service to view exif data:
    http://metapicz.com/#landing

    There is my simple function:
    Code (CSharp):
    1. public void TakePicture()
    2.     {
    3.         int maxSize = 0;
    4. #if !UNITY_EDITOR && UNITY_ANDROID
    5.         maxSize = UserSettings.MaxPhotoSize;
    6. #elif !UNITY_EDITOR && UNITY_IOS
    7.         maxSize = -1;
    8. #endif
    9.         Debug.Log("TakePicture(" + maxSize + ")");
    10.         if (NativeCamera.IsCameraBusy())
    11.         {
    12.             Debug.Log("Camera is Busy");
    13.             return;
    14.         }
    15.  
    16.  
    17.         NativeCamera.Permission permission = NativeCamera.TakePicture((path) =>
    18.         {
    19.  
    20.             Debug.Log("Image from camera path : " + path);
    21.             if (path != null)
    22.             {
    23.                 // Create a Texture2D from the captured image
    24.                 Texture2D texture = NativeCamera.LoadImageAtPath(path, maxSize, false);
    25.                 if (texture == null)
    26.                 {
    27.                     Debug.Log("Couldn't load texture from " + path);
    28.                     return;
    29.                 }
    30.  
    31.  
    32.                 Debug.LogWarning("---------------------------------------");
    33.                 ExifLib.JpegInfo jpi = ExifLib.ExifReader.ReadJpeg(File.ReadAllBytes(path), "Foo");
    34.  
    35.                 Debug.Log("loaded texture from path - " + path);
    36.                 Debug.Log("jpi.datetime - " + jpi.DateTime);
    37.  
    38.  
    39.                 string imageName = GalleryCongigurations.AppImageBaseName + camPhotoCounter + ".jpg";
    40.                 File.Copy(path, Application.persistentDataPath + "/" + GalleryCongigurations.AppAlbumName + "/" + imageName); //Без AlbumName выдает ошибку доступа
    41.  
    42.                 Debug.LogWarning("---------------------------------------");
    43.                 string fullPath = Application.persistentDataPath + "/" + GalleryCongigurations.AppAlbumName + "/" + imageName;
    44.                 string virtualName = dataController.addPhotoToSession(fullPath);
    45.                 scrollViewController.addImage(fullPath, virtualName, false);
    46.  
    47.  
    48.                 PlayerPrefs.SetInt("CAM_PHOTO_COUNTER", ++camPhotoCounter);
    49.             }
    50.         }, maxSize);
    51.  
    52.         Debug.Log("Permission result: " + permission);
    53.     }
     
  28. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    Seems like the image needs to be saved as JPEG and the code needs to be tweaked a little to preserve the EXIF data. I can't do it myself at the moment but you can check out this solution and apply it here.
     
  29. nonethree

    nonethree

    Joined:
    Nov 21, 2014
    Posts:
    5
    Hello Yasir. I have a problem with NativeCamera and NativeGallery, it appears only on iOS. After I take a photo or select it from the gallery, I upload a photo to the server using File.ReadAllBytes(path) and UnityWebRequest, for the first time sent file is corrupted, but all subsequent ones are fine. The strangest thing is that when loaded into a texture photo is displayed normally, the problem is only with loading to server
     
    Last edited: Jun 8, 2019
  30. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    Can I see your code?
     
  31. nonethree

    nonethree

    Joined:
    Nov 21, 2014
    Posts:
    5
    Of course, here is taking photo
    Code (CSharp):
    1.  
    2. public event Action<bool, Texture2D, string> OnCompleted;
    3.  
    4. public void GetTextureFromCamera()
    5. {
    6.       if(NativeCamera.CheckPermission() == NativeCamera.Permission.Granted)
    7.       {
    8.            NativeCamera.TakePicture(TakePictureCallback);
    9.       }
    10.       else if (NativeCamera.CheckPermission() == NativeCamera.Permission.ShouldAsk &&
    11.               NativeCamera.RequestPermission() == NativeCamera.Permission.Granted)
    12.       {
    13.            NativeCamera.TakePicture(TakePictureCallback);
    14.       }
    15. }
    16. private void TakePictureCallback(string path)
    17. {
    18.     if (path == null)
    19.     {
    20.         OnCompleted?.Invoke(false, null, string.Empty);
    21.     }
    22.     else
    23.     {
    24.         var texture = NativeCamera.LoadImageAtPath(path, 2048, false);
    25.         texture.name = StringsHelper.GetFileName(path);
    26.         OnCompleted?.Invoke(true, texture, path);
    27.      }
    28. }
    29.  
    and then upload to server
    Code (CSharp):
    1.  
    2. public void UploadPhoto(string path, NetworkRequestCallback callback)
    3. {
    4.     string contentType = NativeCamera.GetImageProperties(path).mimeType;
    5.     coroutineService.StartCoroutine(UploadPhotoCoroutine(File.ReadAllBytes(path), contentType, callback));
    6. }
    7.  
    8. private IEnumerator UploadPhotoCoroutine(byte[] bytes, string contentType, NetworkRequestCallback callback)
    9. {
    10.      var requestUrl = string.Concat(URL, ACCOUNT_PATH, UPLOAD_PHOTO);
    11.      string photoName = Guid.NewGuid() + "." + contentType.Substring(contentType.IndexOf('/') + 1, contentType.Length - contentType.IndexOf('/') - 1);
    12.      var data = new List<IMultipartFormSection>
    13.      {
    14.          new MultipartFormFileSection("file", bytes, photoName, contentType)
    15.      };
    16.      RestRequest request = new RestRequest(UnityWebRequest.Post(requestUrl, data));
    17.      request.AddHeader("Authorization", string.Concat(BEARER, saveDataService.Authorization.Token));
    18.      yield return SendRequest(request);
    19.      request.Result(r => DefaultResponseHandler(r, callback));
    20. }
     
  32. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    Thank you for posting your code. I haven't used RestRequest but can you maybe try using other solutions for uploading your photo to the server to see if it is an issue with RestRequest? Or, you can try writing the texture.EncodeToPNG bytes to a temporary file and then uploading that temporary file to the server instead of the original file to see if the issue is related to the image file. You may also check UnityWebRequest's error property to see if there was an error.
     
  33. nonethree

    nonethree

    Joined:
    Nov 21, 2014
    Posts:
    5
    I've tried many ways before, and now without RestRequest and using EncodeToPNG, result is absolutely the same. First is corrupted, others are fine.
    Code (CSharp):
    1.  
    2. public void UploadPhoto(Texture2D texture, NetworkRequestCallback callback)
    3. {          
    4.     coroutineService.StartCoroutine(UploadPhotoCoroutine(texture.EncodeToPNG(), "image/png", callback));
    5. }
    6.  
    7. private IEnumerator UploadPhotoCoroutine(byte[] bytes, string contentType, NetworkRequestCallback callback)
    8. {
    9.     var requestUrl = string.Concat(URL, ACCOUNT_PATH, UPLOAD_PHOTO);
    10.     string photoName = Guid.NewGuid() + "." + contentType.Substring(contentType.IndexOf('/') + 1, contentType.Length - contentType.IndexOf('/') - 1);
    11.      var data = new List<IMultipartFormSection>
    12.     {
    13.         new MultipartFormFileSection("file", bytes, photoName, contentType)
    14.     };
    15.     UnityWebRequest request = UnityWebRequest.Post(requestUrl, data);
    16.     request.SetRequestHeader("Authorization",
    17.                 string.Concat(BEARER, saveDataService.Authorization.Token));
    18.     yield return request.SendWebRequest();
    19.     callback.Invoke(!request.isNetworkError, request.error);
    20. }
    21.  
     
  34. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    In this case, I don't think it is related to NativeCamera as the function fails with EncodeToPNG, as well. You may give EncodeToJPEG a try to see if it related to PNG images, otherwise you may wanna inspect the server's code.

    P.S. What happens when you try to upload an existing image file (independent from NativeCamera) to the server?
     
  35. nonethree

    nonethree

    Joined:
    Nov 21, 2014
    Posts:
    5
    With independent image all is fine. EncodeToJPEG produce corrupted image too.
     
  36. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    What if you wait for 1-2 seconds before uploading the image to the server? You can use coroutines for that. Though, if that works, it will be a weird workaround.
     
  37. nonethree

    nonethree

    Joined:
    Nov 21, 2014
    Posts:
    5
    It not works too.
     
  38. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    925
    I don't know how to resolve this issue, sorry. It shouldn't be related to NativeCamera because EncodeToPNG works independently from NativeCamera.