Search Unity

Native Camera for Android & iOS [Open Source]

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

  1. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    @unitystefan I think I've resolved the issue on S8 but couldn't test it on other devices since I don't have any other. Could you please import the attached unitypackage to your project and see if images are rotated correctly on both S8+ and Xiaomi?

    P.S. Updated the package on GitHub.
     

    Attached Files:

    Last edited: Nov 2, 2019
  2. dixitabhi

    dixitabhi

    Joined:
    May 21, 2018
    Posts:
    7
    Hi, @yasirkula I'm using your plugin and it works like it is advertised but sometimes, the camera just doesn't open, I don't even see any logs. It seems as if unity is ignoring it. Does this behavior seem familiar to you?
     
  3. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Are your camera calls getting ignored indefinitely or only for a couple of seconds? Honestly, I am unaware of this issue and I don't think I can do much without deterministic repro steps or some sort of error message that gives a clue about the cause of the issue.
     
  4. unitystefan

    unitystefan

    Joined:
    Mar 16, 2018
    Posts:
    9
    Sorry for little late reply, I'm so busy that I didn't checked the forum.
    I tried package that you sent, now it works on both Samsung S8+ and Xaomi. :)
     
    yasirkula likes this.
  5. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    There are no video materials, unfortunately :/ There should be a number of code snippets in this thread, maybe you can check them out, as well?
     
    anthonyjamesgirdler likes this.
  6. anthonyjamesgirdler

    anthonyjamesgirdler

    Joined:
    Mar 15, 2018
    Posts:
    25
    Hi, @yasirkula, total noob here.
    I'm trying to make a UI Button that will an open my android mobile phone camera and record a video.

    So far:
    • Made a new Unity 3D project.
    • Searched for Native Camera on Asset Store - Download - Install. It makes a folder in Projects > Assets > Plugins
    • Made a new UI Button.
    • Added Component to the button, C# script, called ButtonHandler.
    • Copied and pasted your RecordVideo() method into the script.
    • Linked ButtonHander script to the On Click () section of the Button and selected the RecordVideo() Method.
    • Ran the project using Unity Remote. (That app is a nightmare - 6hrs of messing around to make it work poorly)
    • Tapped button on my Android device.
    • Nothing happens except a bunch of meaningless words go to the Console.
    Here's my ButtonHandler Script:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6.  
    7. public class ButtonHandler : MonoBehaviour
    8. {
    9.     public void RecordVideo()
    10.     {
    11.         NativeCamera.Permission permission = NativeCamera.RecordVideo((path) =>
    12.         {
    13.             Debug.Log("Video path: " + path);
    14.             if (path != null)
    15.             {
    16.                 // Play the recorded video
    17.                 Handheld.PlayFullScreenMovie("file://" + path);
    18.             }
    19.         });
    20.         Debug.Log("Permission result: " + permission);
    21.     }
    22. }
    23.  
    I have no idea what any of the lines of code mean. It's all gibberish to me.
    How do I make the button open the phones camera ?
     
    mcjhow90 likes this.
  7. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Please try Build&Run, I don't think you can test native features with Unity Remote.
     
  8. anthonyjamesgirdler

    anthonyjamesgirdler

    Joined:
    Mar 15, 2018
    Posts:
    25
    Build and Run doesn't work with my setup (currently trying to diagnose why)...but I managed to manually install the build on my phone and run it.
    It worked...switched to the video app and I recorded some video.
     
  9. anthonyjamesgirdler

    anthonyjamesgirdler

    Joined:
    Mar 15, 2018
    Posts:
    25
    Is there a way to make the video record at a higher frame rate ?
    Some phones have a slow motion function that records more frames.
    Using Native Camera I can't see the normal video options to change to slow motion and time lapse.
     
  10. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    There is an optional quality setting that is passed to RecordVideo which may help but other than that, there are no options :/
     
  11. dixitabhi

    dixitabhi

    Joined:
    May 21, 2018
    Posts:
    7
    Hi @yasirkula, thank you for this amazing plugin.
    I am facing some issues on how to load the image back into the application after it has been saved, I'm facing issues with the path for the image. could you help or share some code?
     
  12. boyrazemre01

    boyrazemre01

    Joined:
    Mar 8, 2019
    Posts:
    4
    In IOS, rotated 90 degree too.
     
  13. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
  14. boyrazemre01

    boyrazemre01

    Joined:
    Mar 8, 2019
    Posts:
    4

    @yasirkula I used NativeCamera.LoadImageAtPath with latest version of the plugin.
    PickImage() uses native gallery, TakePicture() uses native camera. I Picked portrait image from gallery it is okey but when i get image from camera it rotates. I added ss. Can you check what am i doing wrong?
     

    Attached Files:

  15. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    boyrazemre01 likes this.
  16. boyrazemre01

    boyrazemre01

    Joined:
    Mar 8, 2019
    Posts:
    4
  17. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    This also happens on Android?
     
  18. petersanken

    petersanken

    Joined:
    Nov 7, 2019
    Posts:
    2
    Hi yasirkula,

    I have a question. I have created a measurement AR-app, and i was hoping to take a picture (using this plugin) after i have done the measurement. Im trying out the examplecode, is it supposed to open the camera when touching the left side of the screen, not taking a picture? Cause my measurements in my app disappear when the camera start.

    Maybe a stupid question, kind of new to Unity, but is there a way to just create a button, and use that button to take a picture, without it opens the camera? More like a screenshot? Lets say i have my measurements right in the app, then i just want to press a "Take Photo" button or something, and then i will take a photo of that scene. Do you understand what i mean, and is that possible?
     
  19. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    You don't need a plugin to take screenshots. You can use the built-in functions. For example: https://docs.unity3d.com/ScriptReference/ScreenCapture.CaptureScreenshot.html

    Alternatively, you can run this coroutine with StartCoroutine:

    Code (CSharp):
    1. private IEnumerator TakeSSAndShare( string savePath )
    2. {
    3.     yield return new WaitForEndOfFrame();
    4.  
    5.     Texture2D ss = new Texture2D( Screen.width, Screen.height, TextureFormat.RGB24, false );
    6.     ss.ReadPixels( new Rect( 0, 0, Screen.width, Screen.height ), 0, 0 );
    7.     ss.Apply();
    8.  
    9.     File.WriteAllBytes( savePath, ss.EncodeToPNG() );
    10.    
    11.     // To avoid memory leaks
    12.     Destroy( ss );
    13. }
     
  20. petersanken

    petersanken

    Joined:
    Nov 7, 2019
    Posts:
    2
    Thank you for your answer. Lets say that i use the ScreenCapture.CaptureScreenshot, is there any easy way to save the screenshot in my android mobile, in perhaps Gallery?
     
  21. dixitabhi

    dixitabhi

    Joined:
    May 21, 2018
    Posts:
    7
    Thank you @yasirkula , that worked, and i'm using your native gallery plugin to save the image in the gallery, how can i get the path,it is being saved to so that i can retrieve it
     
  22. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
  23. dixitabhi

    dixitabhi

    Joined:
    May 21, 2018
    Posts:
    7
    @yasirkula Is there any other way to do it? I want this functionality in my application.
     
  24. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    The only way is to keep a separate copy of the image in Application.persistentDataPath via System.IO.File.Copy and store its path.
     
  25. princemawan33

    princemawan33

    Joined:
    Jan 30, 2019
    Posts:
    2
    Greetings sir,
    Thank you so much for creating this plugin. Can you please tell me where it stores the image that it take??
     
  26. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    dixitabhi likes this.
  27. dixitabhi

    dixitabhi

    Joined:
    May 21, 2018
    Posts:
    7
    Hey @yasirkula , I tried encoding the texture to jpg and saving it to persistent data path, but i keep on getting an error in the logcat that texture isn't readable. Can you share some code on how to do it?
     
  28. dixitabhi

    dixitabhi

    Joined:
    May 21, 2018
    Posts:
    7
    I managed to do it, The TakePicture method has a boolean parameter maketextureNonReadable which is set to true by default. Your plugin works great
     
    yasirkula likes this.
  29. princemawan33

    princemawan33

    Joined:
    Jan 30, 2019
    Posts:
    2
    yasirkula likes this.
  30. ctykaya

    ctykaya

    Joined:
    Sep 23, 2015
    Posts:
    12
    Hi @yasirkula Thanks for plugin it is very useful. Is there a way of editing retry and ok buttons after taking a photo ?Where are they come from ? On both Android and iOS is it customizable ?
     
  31. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Unfortunately not, they are part of the native UI/behaviour.
     
  32. Immerse_Enterprise

    Immerse_Enterprise

    Joined:
    Jun 20, 2017
    Posts:
    2
    Hi, I'm having some trouble getting permissions correctly on Android.

    This is the method I'm using to manage permissions
    Code (CSharp):
    1. private IEnumerator GetPermissions(PermissionType permissionToAskFor)
    2.     {
    3.         //Doozy needs a frame before receiving a new event
    4.         yield return null;
    5.         DebugStats.Message("About to check permissions: " + NativeCamera.CheckPermission() );
    6.         if (NativeCamera.CheckPermission() == NativeCamera.Permission.ShouldAsk)
    7.         {
    8.             DebugStats.Message("We Needs to ask");
    9.             NativeCamera.RequestPermission();
    10.             DebugStats.Message("We Asked: " + NativeCamera.CheckPermission());
    11.             if(NativeCamera.CheckPermission() == NativeCamera.Permission.Granted)
    12.             {
    13.                 DebugStats.Message("Granted");
    14.                 GameEventMessage.SendEvent("PermissionGranted");
    15.             }
    16.             else if(NativeCamera.CheckPermission() == NativeCamera.Permission.Denied)
    17.             {
    18.                 DebugStats.Message("Denied");
    19.                 GameEventMessage.SendEvent("PermissionDenied");
    20.             }
    21.             else if(NativeCamera.CheckPermission() == NativeCamera.Permission.ShouldAsk)
    22.             {
    23.                 DebugStats.Message("Shoukd Ask");
    24.                 GameEventMessage.SendEvent("PermissionShouldAsk");
    25.             }
    26.         }
    27.         else if(NativeCamera.CheckPermission() == NativeCamera.Permission.Granted)
    28.         {
    29.             DebugStats.Message("Already Granted");
    30.             GameEventMessage.SendEvent("PermissionGranted");
    31.         }
    32.         else if (NativeCamera.CheckPermission() == NativeCamera.Permission.Denied)
    33.         {
    34.             DebugStats.Message("Already Denied");
    35.             GameEventMessage.SendEvent("PermissionDenied");
    36.         }
    37.  
    38.         yield return null;
    39.     }
    This works a treat on iOS.

    However on Android, if the app is freshly installed NativeCamera.CheckPermission() will return Permission.ShouldAsk. NativeCamera.RequestPermission() will then successfully trigger the dialog box, however regardless of the users answer NativeCamera.CheckPermission() always returns false after this. Including if the user has gone into settings and change the camera permission manually.

    I'm testing on
    Model: Pixel 3
    Android Version: 10
    Unity Version: 2019.2.6f1

    If you have any tips on why I'm always getting a Permission.Denied response or need any more information please let me know.
     
    ryanclark_unity likes this.
  33. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Can you Debug.Log the result of NativeCamera.RequestPermission (it also returns a NativeCamera.Permission object)? If it returns Permission.Granted but the following CheckPermission line returns Permission.Denied, then we will know how to reproduce the issue.
     
  34. Immerse_Enterprise

    Immerse_Enterprise

    Joined:
    Jun 20, 2017
    Posts:
    2
    NativeCamera.RequestPermission also returns Permission.Denied when the user selects Allow on the system popup.

    Code (CSharp):
    1.  DebugStats.Message("About to check permissions: " + NativeCamera.CheckPermission() );
    2.         if (NativeCamera.CheckPermission() == NativeCamera.Permission.ShouldAsk)
    3.         {
    4.             DebugStats.Message("We Needs to ask");
    5.             DebugStats.Message(NativeCamera.RequestPermission().ToString());
    6.             DebugStats.Message("We Asked: " + NativeCamera.CheckPermission());
    Gives the output:
    About to check permissions: ShouldAsk
    We Needs to ask
    Denied
    We Asked: Denied
    Denied
     
  35. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    I'm sorry to hear that. I'll test the plugin again on my S8 soon but I didn't have any issues so far so I'm not very optimistic. There doesn't seem to be any hints about the source of the issue either, so I may not be able to resolve this issue. You can try testing the app on another Android device to see if this is a device-specific or OS-specific issue, if you like.
     
  36. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    185
    Great Asset. I am able to upload images and video into my app from my S10+. But when i click to take a picture or record I get nothing. These are my manifest and native scripts.


    Code (CSharp):
    1. using System;
    2. using System.IO;
    3. using UnityEngine;
    4. using Object = UnityEngine.Object;
    5. #if !UNITY_EDITOR && ( UNITY_ANDROID || UNITY_IOS )
    6. using NativeCameraNamespace;
    7. #endif
    8.  
    9. public static class NativeCamera
    10. {
    11.     public struct ImageProperties
    12.     {
    13.         public readonly int width;
    14.         public readonly int height;
    15.         public readonly string mimeType;
    16.         public readonly ImageOrientation orientation;
    17.  
    18.         public ImageProperties( int width, int height, string mimeType, ImageOrientation orientation )
    19.         {
    20.             this.width = width;
    21.             this.height = height;
    22.             this.mimeType = mimeType;
    23.             this.orientation = orientation;
    24.         }
    25.     }
    26.  
    27.     public struct VideoProperties
    28.     {
    29.         public readonly int width;
    30.         public readonly int height;
    31.         public readonly long duration;
    32.         public readonly float rotation;
    33.  
    34.         public VideoProperties( int width, int height, long duration, float rotation )
    35.         {
    36.             this.width = width;
    37.             this.height = height;
    38.             this.duration = duration;
    39.             this.rotation = rotation;
    40.         }
    41.     }
    42.  
    43.     public enum Permission { Denied = 0, Granted = 1, ShouldAsk = 2 };
    44.     public enum Quality { Default = -1, Low = 0, Medium = 1, High = 2 };
    45.  
    46.     // EXIF orientation: http://sylvana.net/jpegcrop/exif_orientation.html (indices are reordered)
    47.     public enum ImageOrientation { Unknown = -1, Normal = 0, Rotate90 = 1, Rotate180 = 2, Rotate270 = 3, FlipHorizontal = 4, Transpose = 5, FlipVertical = 6, Transverse = 7 };
    48.  
    49.     public delegate void CameraCallback( string path );
    50.  
    51.     #region Platform Specific Elements
    52. #if !UNITY_EDITOR && UNITY_ANDROID
    53.     private static AndroidJavaClass m_ajc = null;
    54.     private static AndroidJavaClass AJC
    55.     {
    56.         get
    57.         {
    58.             if( m_ajc == null )
    59.                 m_ajc = new AndroidJavaClass( "com.yasirkula.unity.NativeCamera" );
    60.  
    61.             return m_ajc;
    62.         }
    63.     }
    64.  
    65.     private static AndroidJavaObject m_context = null;
    66.     private static AndroidJavaObject Context
    67.     {
    68.         get
    69.         {
    70.             if( m_context == null )
    71.             {
    72.                 using( AndroidJavaObject unityClass = new AndroidJavaClass( "com.unity3d.player.UnityPlayer" ) )
    73.                 {
    74.                     m_context = unityClass.GetStatic<AndroidJavaObject>( "currentActivity" );
    75.                 }
    76.             }
    77.  
    78.             return m_context;
    79.         }
    80.     }
    81. #elif !UNITY_EDITOR && UNITY_IOS
    82.     [System.Runtime.InteropServices.DllImport( "__Internal" )]
    83.     private static extern int _NativeCamera_CheckPermission();
    84.  
    85.     [System.Runtime.InteropServices.DllImport( "__Internal" )]
    86.     private static extern int _NativeCamera_RequestPermission();
    87.  
    88.     [System.Runtime.InteropServices.DllImport( "__Internal" )]
    89.     private static extern int _NativeCamera_CanOpenSettings();
    90.  
    91.     [System.Runtime.InteropServices.DllImport( "__Internal" )]
    92.     private static extern void _NativeCamera_OpenSettings();
    93.  
    94.     [System.Runtime.InteropServices.DllImport( "__Internal" )]
    95.     private static extern int _NativeCamera_HasCamera();
    96.    
    97.     [System.Runtime.InteropServices.DllImport( "__Internal" )]
    98.     private static extern void _NativeCamera_TakePicture( string imageSavePath, int maxSize );
    99.  
    100.     [System.Runtime.InteropServices.DllImport( "__Internal" )]
    101.     private static extern void _NativeCamera_RecordVideo( int quality, int maxDuration );
    102.  
    103.     [System.Runtime.InteropServices.DllImport( "__Internal" )]
    104.     private static extern string _NativeCamera_GetImageProperties( string path );
    105.  
    106.     [System.Runtime.InteropServices.DllImport( "__Internal" )]
    107.     private static extern string _NativeCamera_GetVideoProperties( string path );
    108.  
    109.     [System.Runtime.InteropServices.DllImport( "__Internal" )]
    110.     private static extern string _NativeCamera_LoadImageAtPath( string path, string temporaryFilePath, int maxSize );
    111. #endif
    112.  
    113. #if !UNITY_EDITOR && ( UNITY_ANDROID || UNITY_IOS )
    114.     private static string m_temporaryImagePath = null;
    115.     private static string TemporaryImagePath
    116.     {
    117.         get
    118.         {
    119.             if( m_temporaryImagePath == null )
    120.             {
    121.                 m_temporaryImagePath = Path.Combine( Application.temporaryCachePath, "__tmpImG" );
    122.                 Directory.CreateDirectory( Application.temporaryCachePath );
    123.             }
    124.  
    125.             return m_temporaryImagePath;
    126.         }
    127.     }
    128. #endif
    129.  
    130. #if !UNITY_EDITOR && UNITY_IOS
    131.     private static string m_iOSSelectedImagePath = null;
    132.     private static string IOSSelectedImagePath
    133.     {
    134.         get
    135.         {
    136.             if( m_iOSSelectedImagePath == null )
    137.             {
    138.                 m_iOSSelectedImagePath = Path.Combine( Application.temporaryCachePath, "tmp.png" );
    139.                 Directory.CreateDirectory( Application.temporaryCachePath );
    140.             }
    141.  
    142.             return m_iOSSelectedImagePath;
    143.         }
    144.     }
    145. #endif
    146.     #endregion
    147.  
    148.     #region Runtime Permissions
    149.     public static Permission CheckPermission()
    150.     {
    151. #if !UNITY_EDITOR && UNITY_ANDROID
    152.         Permission result = (Permission) AJC.CallStatic<int>( "CheckPermission", Context );
    153.         if( result == Permission.Denied && (Permission) PlayerPrefs.GetInt( "NativeCameraPermission", (int) Permission.ShouldAsk ) == Permission.ShouldAsk )
    154.             result = Permission.ShouldAsk;
    155.  
    156.         return result;
    157. #elif !UNITY_EDITOR && UNITY_IOS
    158.         return (Permission) _NativeCamera_CheckPermission();
    159. #else
    160.         return Permission.Granted;
    161. #endif
    162.     }
    163.  
    164.     public static Permission RequestPermission()
    165.     {
    166.      
    167. #if !UNITY_EDITOR && UNITY_ANDROID
    168.         object threadLock = new object();
    169.         lock( threadLock )
    170.         {
    171.             NCPermissionCallbackAndroid nativeCallback = new NCPermissionCallbackAndroid( threadLock );
    172.  
    173.             AJC.CallStatic( "RequestPermission", Context, nativeCallback, PlayerPrefs.GetInt( "NativeCameraPermission", (int) Permission.ShouldAsk ) );
    174.  
    175.             if( nativeCallback.Result == -1 )
    176.                 System.Threading.Monitor.Wait( threadLock );
    177.  
    178.             if( (Permission) nativeCallback.Result != Permission.ShouldAsk && PlayerPrefs.GetInt( "NativeCameraPermission", -1 ) != nativeCallback.Result )
    179.             {
    180.                 PlayerPrefs.SetInt( "NativeCameraPermission", nativeCallback.Result );
    181.                 PlayerPrefs.Save();
    182.             }
    183.  
    184.             return (Permission) nativeCallback.Result;
    185.         }
    186. #elif !UNITY_EDITOR && UNITY_IOS
    187.         return (Permission) _NativeCamera_RequestPermission();
    188. #else
    189.         return Permission.Granted;
    190. #endif
    191.     }
    192.  
    193.     public static bool CanOpenSettings()
    194.     {
    195. #if !UNITY_EDITOR && UNITY_IOS
    196.         return _NativeCamera_CanOpenSettings() == 1;
    197. #else
    198.         return true;
    199. #endif
    200.     }
    201.  
    202.     public static void OpenSettings()
    203.     {
    204. #if !UNITY_EDITOR && UNITY_ANDROID
    205.         AJC.CallStatic( "OpenSettings", Context );
    206. #elif !UNITY_EDITOR && UNITY_IOS
    207.         _NativeCamera_OpenSettings();
    208. #endif
    209.     }
    210.     #endregion
    211.  
    212.     #region Camera Functions
    213.     public static Permission TakePicture( CameraCallback callback, int maxSize = -1 )
    214.     {
    215.         Permission result = RequestPermission();
    216.         if( result == Permission.Granted && !IsCameraBusy() )
    217.         {
    218. #if !UNITY_EDITOR && UNITY_ANDROID
    219.             AJC.CallStatic( "TakePicture", Context, new NCCameraCallbackAndroid( callback ) );
    220. #elif !UNITY_EDITOR && UNITY_IOS
    221.             if( maxSize <= 0 )
    222.                 maxSize = SystemInfo.maxTextureSize;
    223.  
    224.             NCCameraCallbackiOS.Initialize( callback );
    225.             _NativeCamera_TakePicture( IOSSelectedImagePath, maxSize );
    226. #else
    227.             if( callback != null )
    228.                 callback( null );
    229. #endif
    230.         }
    231.  
    232.         return result;
    233.     }
    234.  
    235.     public static Permission RecordVideo( CameraCallback callback, Quality quality = Quality.Default, int maxDuration = 0, long maxSizeBytes = 0L )
    236.     {
    237.         Permission result = RequestPermission();
    238.         if( result == Permission.Granted && !IsCameraBusy() )
    239.         {
    240. #if !UNITY_EDITOR && UNITY_ANDROID
    241.             AJC.CallStatic( "RecordVideo", Context, new NCCameraCallbackAndroid( callback ), (int) quality, maxDuration, maxSizeBytes );
    242. #elif !UNITY_EDITOR && UNITY_IOS
    243.             NCCameraCallbackiOS.Initialize( callback );
    244.             _NativeCamera_RecordVideo( (int) quality, maxDuration );
    245. #else
    246.             if( callback != null )
    247.                 callback( null );
    248. #endif
    249.         }
    250.  
    251.         return result;
    252.     }
    253.  
    254.     public static bool DeviceHasCamera()
    255.     {
    256. #if !UNITY_EDITOR && UNITY_ANDROID
    257.         return AJC.CallStatic<bool>( "HasCamera", Context );
    258. #elif !UNITY_EDITOR && UNITY_IOS
    259.         return _NativeCamera_HasCamera() == 1;
    260. #else
    261.         return true;
    262. #endif
    263.     }
    264.  
    265.     public static bool IsCameraBusy()
    266.     {
    267. #if !UNITY_EDITOR && UNITY_IOS
    268.         return NCCameraCallbackiOS.IsBusy;
    269. #else
    270.         return false;
    271. #endif
    272.     }
    273.     #endregion
    274.  
    275.     #region Utility Functions
    276.     public static Texture2D LoadImageAtPath( string imagePath, int maxSize = -1, bool markTextureNonReadable = true,
    277.         bool generateMipmaps = true, bool linearColorSpace = false )
    278.     {
    279.         if( string.IsNullOrEmpty( imagePath ) )
    280.             throw new ArgumentException( "Parameter 'imagePath' is null or empty!" );
    281.  
    282.         if( !File.Exists( imagePath ) )
    283.             throw new FileNotFoundException( "File not found at " + imagePath );
    284.  
    285.         if( maxSize <= 0 )
    286.             maxSize = SystemInfo.maxTextureSize;
    287.  
    288. #if !UNITY_EDITOR && UNITY_ANDROID
    289.         string loadPath = AJC.CallStatic<string>( "LoadImageAtPath", Context, imagePath, TemporaryImagePath, maxSize );
    290. #elif !UNITY_EDITOR && UNITY_IOS
    291.         string loadPath = _NativeCamera_LoadImageAtPath( imagePath, TemporaryImagePath, maxSize );
    292. #else
    293.         string loadPath = imagePath;
    294. #endif
    295.  
    296.         String extension = Path.GetExtension( imagePath ).ToLowerInvariant();
    297.         TextureFormat format = ( extension == ".jpg" || extension == ".jpeg" ) ? TextureFormat.RGB24 : TextureFormat.RGBA32;
    298.  
    299.         Texture2D result = new Texture2D( 2, 2, format, generateMipmaps, linearColorSpace );
    300.  
    301.         try
    302.         {
    303.             if( !result.LoadImage( File.ReadAllBytes( loadPath ), markTextureNonReadable ) )
    304.             {
    305.                 Object.DestroyImmediate( result );
    306.                 return null;
    307.             }
    308.         }
    309.         catch( Exception e )
    310.         {
    311.             Debug.LogException( e );
    312.  
    313.             Object.DestroyImmediate( result );
    314.             return null;
    315.         }
    316.         finally
    317.         {
    318.             if( loadPath != imagePath )
    319.             {
    320.                 try
    321.                 {
    322.                     File.Delete( loadPath );
    323.                 }
    324.                 catch { }
    325.             }
    326.         }
    327.  
    328.         return result;
    329.     }
    330.  
    331.     public static ImageProperties GetImageProperties( string imagePath )
    332.     {
    333.         if( !File.Exists( imagePath ) )
    334.             throw new FileNotFoundException( "File not found at " + imagePath );
    335.  
    336. #if !UNITY_EDITOR && UNITY_ANDROID
    337.         string value = AJC.CallStatic<string>( "GetImageProperties", Context, imagePath );
    338. #elif !UNITY_EDITOR && UNITY_IOS
    339.         string value = _NativeCamera_GetImageProperties( imagePath );
    340. #else
    341.         string value = null;
    342. #endif
    343.  
    344.         int width = 0, height = 0;
    345.         string mimeType = null;
    346.         ImageOrientation orientation = ImageOrientation.Unknown;
    347.         if( !string.IsNullOrEmpty( value ) )
    348.         {
    349.             string[] properties = value.Split( '>' );
    350.             if( properties != null && properties.Length >= 4 )
    351.             {
    352.                 if( !int.TryParse( properties[0].Trim(), out width ) )
    353.                     width = 0;
    354.                 if( !int.TryParse( properties[1].Trim(), out height ) )
    355.                     height = 0;
    356.  
    357.                 mimeType = properties[2].Trim();
    358.                 if( mimeType.Length == 0 )
    359.                 {
    360.                     String extension = Path.GetExtension( imagePath ).ToLowerInvariant();
    361.                     if( extension == ".png" )
    362.                         mimeType = "image/png";
    363.                     else if( extension == ".jpg" || extension == ".jpeg" )
    364.                         mimeType = "image/jpeg";
    365.                     else if( extension == ".gif" )
    366.                         mimeType = "image/gif";
    367.                     else if( extension == ".bmp" )
    368.                         mimeType = "image/bmp";
    369.                     else
    370.                         mimeType = null;
    371.                 }
    372.  
    373.                 int orientationInt;
    374.                 if( int.TryParse( properties[3].Trim(), out orientationInt ) )
    375.                     orientation = (ImageOrientation) orientationInt;
    376.  
    377. #if !UNITY_EDITOR && UNITY_IOS
    378.                 if( orientation == ImageOrientation.Unknown ) // captured media is saved in correct orientation on iOS
    379.                     orientation = ImageOrientation.Normal;
    380. #endif
    381.             }
    382.         }
    383.  
    384.         return new ImageProperties( width, height, mimeType, orientation );
    385.     }
    386.  
    387.     public static VideoProperties GetVideoProperties( string videoPath )
    388.     {
    389.         if( !File.Exists( videoPath ) )
    390.             throw new FileNotFoundException( "File not found at " + videoPath );
    391.  
    392. #if !UNITY_EDITOR && UNITY_ANDROID
    393.         string value = AJC.CallStatic<string>( "GetVideoProperties", Context, videoPath );
    394. #elif !UNITY_EDITOR && UNITY_IOS
    395.         string value = _NativeCamera_GetVideoProperties( videoPath );
    396. #else
    397.         string value = null;
    398. #endif
    399.  
    400.         int width = 0, height = 0;
    401.         long duration = 0L;
    402.         float rotation = 0f;
    403.         if( !string.IsNullOrEmpty( value ) )
    404.         {
    405.             string[] properties = value.Split( '>' );
    406.             if( properties != null && properties.Length >= 4 )
    407.             {
    408.                 if( !int.TryParse( properties[0].Trim(), out width ) )
    409.                     width = 0;
    410.                 if( !int.TryParse( properties[1].Trim(), out height ) )
    411.                     height = 0;
    412.                 if( !long.TryParse( properties[2].Trim(), out duration ) )
    413.                     duration = 0L;
    414.                 if( !float.TryParse( properties[3].Trim(), out rotation ) )
    415.                     rotation = 0f;
    416.             }
    417.         }
    418.  
    419.         if( rotation == -90f )
    420.             rotation = 270f;
    421.  
    422.         return new VideoProperties( width, height, duration, rotation );
    423.     }
    424.     #endregion
    425. }



    And My Manifest Script.

    Code (CSharp):
    1. <?xml version="1.0" encoding="utf-8"?>
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.gaglabs.squadron" android:versionCode="1" android:versionName="1.0">
    3.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    4.     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    5.   <uses-permission android:name="android.permission.RECORD_AUDIO" />
    6.   <uses-permission android:name="android.permission.CAMERA" />
    7.   <uses-feature android:name="android.hardware.camera" />
    8.   <uses-feature android:name="android.hardware.camera.autofocus" />
    9.   <application android:label="@string/app_name" android:icon="@drawable/app_icon" android:theme="@style/UnityThemeSelector" >
    10.       <provider
    11.           android:name="com.yasirkula.unity.NativeCameraContentProvider"
    12.           android:authorities="MY_UNIQUE_AUTHORITY"
    13.           android:exported="false"
    14.           android:grantUriPermissions="true"/>
    15.    
    16.     <!-- The MessagingUnityPlayerActivity is a class that extends
    17.          UnityPlayerActivity to work around a known issue when receiving
    18.          notification data payloads in the background. -->
    19.     <activity android:name="com.google.firebase.MessagingUnityPlayerActivity"
    20.               android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
    21.       <intent-filter>
    22.         <action android:name="android.intent.action.MAIN" />
    23.         <category android:name="android.intent.category.LAUNCHER" />
    24.       </intent-filter>
    25.       <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
    26.     </activity>
    27.     <service android:name="com.google.firebase.messaging.MessageForwardingService" android:exported="false" />
    28.   </application>
    29. </manifest>
     
  37. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    185
    And the Script that returns these calls looks like this..

    Code (CSharp):
    1.  public void SelectPhotoFromCamera()
    2.         {
    3.             NativeCamera.TakePicture(OnImagePicked);
    4.         }
    5.  
    6. ///This calls to NativeCam to take a photo..
    7.  
    8.  
    9. private void OnImagePicked(string _path)
    10.         {
    11.          
    12.                 if (string.IsNullOrEmpty(_path))
    13.                     return;
    14.                 FeedIndex = 1;
    15.  
    16.             UploadFileToWhatEver(_path, true);
    17.          
    18.  
    19.  
    20.         }
    21.  
    22. ////Then once callback is received we call this..
    23.  
    24. public void UploadFileToWhatEver(string _url, bool _showPreview)
    25.         {
    26.             AppManager.VIEW_CONTROLLER.ShowLoading();
    27.             StartCoroutine(GetFilrWhereEver(_url, _showPreview));
    28.         }
    29.  
    30.  
    31. /// Then This..
    32.  
    33.  
    34.  
    35.   private IEnumerator GetFilrWhereEver(string _url, bool _showPreview)
    36.         {
    37.             FeedType _type = GetFeedType();
    38.             Feed _feed = new Feed();
    39.             _feed.Type = _type;
    40.             _feed.OwnerID = AppManager.USER_PROFILE.FIREBASE_USER.UserId;
    41.             _feed.ToUserID = feedDadaLoader.GetUserID();
    42.             byte[] imageBytes = null;
    43.             byte[] videoBytes = null;
    44.             string fileName = System.Guid.NewGuid().ToString();
    45.             Texture2D previewTexure = new Texture2D(2, 2);
    46.  
    47.  
    48.  
    49.  
    50.             if (_type == FeedType.Image || _type == FeedType.Video)
    51.             {
    52.                 _textbutt.SetActive(false);
    53.                 _textureButt.SetActive(true);
    54.                 byte[] fileBytes = System.IO.File.ReadAllBytes(_url);
    55.  
    56.                 if (_type == FeedType.Video)
    57.                 {
    58.  
    59.                     Debug.Log("First Video");
    60.                     if (!CheckVideoSize(fileBytes))
    61.                     {
    62.                         Debug.Log("checing size");
    63.                         AppManager.VIEW_CONTROLLER.ShowPopupMSG(MessageCode.MaxVideoSize);
    64.                         yield break;
    65.                     }
    66.                     PreviewPlayer.url = "file://" + _url;
    67.                     PreviewPlayer.Prepare();
    68.                     while (!PreviewPlayer.isPrepared)
    69.                     {
    70.                         yield return null;
    71.                     }
    72.                     PreviewPlayer.time = 1f;
    73.                     //Plays the video for one frame
    74.                     PreviewPlayer.Play();
    75.  
    76.                     PreviewPlayer.Pause();
    77.                     videoBytes = fileBytes;
    78.                     while (PreviewPlayer.frame < 2)
    79.                     {
    80.                         Debug.Log("player frame is < 2");
    81.                         yield return null;
    82.                     }
    83.                     Texture2D _texture = ReadExternalTexture(PreviewPlayer.texture);
    84.  
    85.                     // rotate image 90 degrees
    86.                     // _texture = rotateTexture(_texture);
    87.  
    88.                     ResizeTexture(_texture);
    89.                     imageBytes = _texture.EncodeToJPG(AppManager.APP_SETTINGS.UploadImageQuality);
    90.                     _feed.MediaWidth = _texture.width;
    91.                     _feed.MeidaHeight = _texture.height;
    92.                     _feed.VideoFileName = fileName;
    93.  
    94.                     previewTexure = _texture;
    95.  
    96.                 }
    97.  
    98.                 if (_type == FeedType.Image)
    99.                 {
    100.  
    101.                     Debug.Log("First Image");
    102.                     Texture2D _texture = new Texture2D(2, 2);
    103.                     _texture.LoadImage(fileBytes);
    104.                     yield return new WaitForEndOfFrame();
    105.  
    106.                     ResizeTexture(_texture);
    107.                     imageBytes = _texture.EncodeToJPG(AppManager.APP_SETTINGS.UploadImageQuality);
    108.                     _feed.MediaWidth = _texture.width;
    109.                     _feed.MeidaHeight = _texture.height;
    110.  
    111.                     previewTexure = _texture;
    112.                 }
    113.  
    114.             }
    115.  
    116.             if (_type == FeedType.Image || _type == FeedType.Video)
    117.             {
    118.                 if (_showPreview)
    119.                 {
    120.                     AppManager.VIEW_CONTROLLER.HideLoading();
    121.                     if (_type == FeedType.Image)
    122.                     {
    123.  
    124.                         Debug.Log("Preview Image");
    125.                         FeedPreviewRequest _previreRequest = new FeedPreviewRequest();
    126.                         _posterImge.texture = previewTexure;
    127.                         float _bodyWidth = 770;
    128.                         float _imageWidth = _feed.MediaWidth;
    129.                         float _imageHeight = _feed.MeidaHeight;
    130.                         float _ratio = _imageWidth / _imageHeight;
    131.                         float _expectedHeight = _bodyWidth / _ratio;
    132.                         _posterImge.rectTransform.sizeDelta = new Vector2(_bodyWidth, _expectedHeight);
    133.  
    134.  
    135.  
    136.                         _posterHolder.sizeDelta = _posterImge.rectTransform.sizeDelta;
    137.                         AppManager.VIEW_CONTROLLER.GetReq(_previreRequest);
    138.                         while (!_previreRequest.IsComplete)
    139.                         {
    140.                             yield return null;
    141.                         }
    142.                         if (!_previreRequest.IsSuccess)
    143.                         {
    144.                             yield break;
    145.                         }
    146.                         _feed.BodyTXT = _previreRequest.BodyText;
    147.                     }
    148.                     else if (_type == FeedType.Video)
    149.                     {
    150.  
    151.                         Debug.Log("Preview Video");
    152.                         FeedPreviewRequest _previreRequest = new FeedPreviewRequest();
    153.                         _posterImge.texture = PreviewPlayer.texture;
    154.                         float _bodyWidth = 770;
    155.                         float _imageWidth = _feed.MediaWidth;
    156.                         float _imageHeight = _feed.MeidaHeight;
    157.                         float _ratio = _imageWidth / _imageHeight;
    158.                         float _expectedHeight = _bodyWidth / _ratio;
    159.                         _posterImge.rectTransform.sizeDelta = new Vector2(_bodyWidth, _expectedHeight);
    160.  
    161.  
    162.  
    163.                         _posterHolder.sizeDelta = _posterImge.rectTransform.sizeDelta;
    164.                         ShowPlayBtn();
    165.  
    166.                         AppManager.VIEW_CONTROLLER.GetReq(_previreRequest);
    167.                         while (!_previreRequest.IsComplete)
    168.                         {
    169.                             Debug.Log("Preview request not complete");
    170.                             yield return null;
    171.                         }
    172.                         if (!_previreRequest.IsSuccess)
    173.                         {
    174.                             Debug.Log("Preview request not success");
    175.                             yield break;
    176.                         }
    177.                         _feed.BodyTXT = _previreRequest.BodyText;
    178.  
    179.                     }
    180.  
    181.  
    182.                 }
    183.             }
    184.             else
    185.             {
    186.                 _feed.BodyTXT = BodyTextInput.text;
    187.             }
    188.  
    189.             AppManager.VIEW_CONTROLLER.ShowLoading();
    190.  
    191.             // wait for preview callback
    192.             if (_type == FeedType.Image)
    193.             {
    194.                 Debug.Log("is image");
    195.                 // upload image
    196.                 FileUploadRequset _imageUploadRequest = new FileUploadRequset();
    197.                 _imageUploadRequest.FeedType = _type;
    198.                 _imageUploadRequest.FileName = fileName + "." + GetFileExtension(_url);
    199.                 _imageUploadRequest.UploadBytes = imageBytes;
    200.  
    201.                 FileUploadCallback _callBack = new FileUploadCallback();
    202.                 AppManager.FIREBASE_CONTROLLER.UploadFile(_imageUploadRequest, callback =>
    203.                 {
    204.                     _callBack = callback;
    205.                 }
    206.                 );
    207.                 while (!_callBack.IsComplete)
    208.                 {
    209.                     Debug.Log("Callback not complete image");
    210.                     yield return null;
    211.                 }
    212.                 if (!_callBack.IsSuccess)
    213.                 {
    214.                     Debug.Log("Callback not success image");
    215.                     AppManager.VIEW_CONTROLLER.HideLoading();
    216.                     AppManager.VIEW_CONTROLLER.ShowPopupMSG(MessageCode.FailedUploadFeed);
    217.                     yield break;
    218.                 }
    219.                 _feed.ImageURL = _callBack.DownloadUrl;
    220.             }
    221.             if (_type == FeedType.Video)
    222.             {
    223.                 Debug.Log("is video");
    224.                 // upload video
    225.                 FileUploadRequset _videoUploadRequest = new FileUploadRequset();
    226.                 _videoUploadRequest.FeedType = _type;
    227.                 _videoUploadRequest.FileName = fileName + "." + GetFileExtension(_url);
    228.                 _videoUploadRequest.UploadBytes = videoBytes;
    229.  
    230.                 FileUploadCallback _callBack = new FileUploadCallback();
    231.                 AppManager.FIREBASE_CONTROLLER.UploadFile(_videoUploadRequest, callback =>
    232.                 {
    233.                     Debug.Log("upload file");
    234.                     _callBack = callback;
    235.                 }
    236.                 );
    237.                 while (!_callBack.IsComplete)
    238.                 {
    239.                     Debug.Log("Callback not complete video");
    240.                     yield return null;
    241.                 }
    242.                 if (!_callBack.IsSuccess)
    243.                 {
    244.                     Debug.Log("Callback not success video");
    245.                     AppManager.VIEW_CONTROLLER.HideLoading();
    246.                     AppManager.VIEW_CONTROLLER.ShowPopupMSG(MessageCode.FailedUploadFeed);
    247.                     yield break;
    248.                 }
    249.                 // upload video preview
    250.                 FileUploadRequset _imageUploadRequest = new FileUploadRequset();
    251.                 _imageUploadRequest.FeedType = FeedType.Image;
    252.                 _imageUploadRequest.FileName = System.Guid.NewGuid() + ".jpg";
    253.                 _imageUploadRequest.UploadBytes = imageBytes;
    254.  
    255.                 FileUploadCallback _callBack2 = new FileUploadCallback();
    256.                 AppManager.FIREBASE_CONTROLLER.UploadFile(_imageUploadRequest, callback =>
    257.                 {
    258.                     _callBack2 = callback;
    259.                 }
    260.                 );
    261.                 while (!_callBack2.IsComplete)
    262.                 {
    263.                     yield return null;
    264.                 }
    265.                 if (!_callBack2.IsSuccess)
    266.                 {
    267.                     AppManager.VIEW_CONTROLLER.HideLoading();
    268.                     AppManager.VIEW_CONTROLLER.ShowPopupMSG(MessageCode.FailedUploadFeed);
    269.                     yield break;
    270.                 }
    271.  
    272.                 //_feed.VideoURL = _callBack.DownloadUrl;
    273.                 _feed.ImageURL = _callBack2.DownloadUrl;
    274.             }
    275.  
    276.             _feed.DateCreated = GetDate();
    277.             FeedUploadCallback _feedCallback = null;
    278.             if (_dropDownValue == 0)
    279.             {
    280.  
    281.                 AppManager.FIREBASE_CONTROLLER.AddNewWorldPost(_feed, callback =>
    282.                 {
    283.                     _feedCallback = callback;
    284.                 });
    285.  
    286.             }
    287.             else if (_dropDownValue == 1)
    288.             {
    289.  
    290.                 AppManager.FIREBASE_CONTROLLER.AddNewFriendPost(_feed, callback =>
    291.                 {
    292.                     _feedCallback = callback;
    293.                 });
    294.             }
    295.             else if (_dropDownValue == 2)
    296.             {
    297.  
    298.                 AppManager.FIREBASE_CONTROLLER.AddNewAllPost(_feed, callback =>
    299.                 {
    300.                     _feedCallback = callback;
    301.                 });
    302.  
    303.             }
    304.            
    305.             while (_feedCallback == null)
    306.             {
    307.                 Debug.Log("callback request null");
    308.                 yield return null;
    309.             }
    310.             if (!_feedCallback.IsSuccess)
    311.             {
    312.                 AppManager.VIEW_CONTROLLER.HideLoading();
    313.                 AppManager.VIEW_CONTROLLER.ShowPopupMSG(MessageCode.FailedUploadFeed);
    314.                 yield break;
    315.             }
    316.             if (_type == FeedType.Video)
    317.             {
    318.                 Debug.Log("uploaded to allpostkeys");
    319.                 string databasePath = AppSettings.AllPostsKey + "/" + _feed.Key + "/VideoURL";
    320.                 AppManager.Instance.Firebase.UploadAndCompressVideo(AppSettings.FeedUploadVideoPath + fileName + "." + GetFileExtension(_url), databasePath);
    321.             }
    322.             BodyTextInput.text = string.Empty;
    323.             // upload finish
    324.             AppManager.VIEW_CONTROLLER.ShowPopupMSG(MessageCode.SuccessPost);
    325.             AppManager.VIEW_CONTROLLER.HidePoster();
    326.             AppManager.VIEW_CONTROLLER.HideLoading();
    327.  
    328.             feedDadaLoader.ResetLoader();
    329.             Debug.Log("finished");
    330.  
    331.             yield return new WaitForSeconds(1.5f);
    332.             GetScene();
    333.  
    334.  
    335.         }
    336.  
     
  38. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    First, I'd recommend you to update the plugin to the latest version and then remove the provider from your AndroidManifest, plugin automatically inserts the provider now. If it still doesn't work after these steps, try putting Debug.Log lines to critical code paths like OnImagePicked to see whether or not NativeCamera returns a path and at which line the execution of your code stops.
     
  39. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    185
    Updating the plugin worked thanks. The other issue im facing is when i record a video and it uploads to a preview texture so that the user can review it and play it before they upload it to the app, it rotates the video -90. Then when they upload it and my code resizes it it then rotates it back and now the video is smooshed. Any clue how to get orientation after the video is recorded and then rotate it to be correct?
     
  40. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    I think NativeCamera.GetVideoProperties(videoPath).rotation is what you are looking for. From the documentation:
     
    gaglabs likes this.
  41. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    185
    Thanks bud. I figured that out after i sent that lol
     
  42. Krodon

    Krodon

    Joined:
    Dec 19, 2015
    Posts:
    4
    Hello,

    I'm using the plugin and it's work perfectly, but in one device, when I record a video and configure the camera quality or set a timeout, the return path of the video is always null. If I don`t set any parameter, the path return ok.
    Can someone help me? The device whats have this bugs is Samsung T290 and Android is 9.

    Thanks in advance.
     
  43. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    It is sad to hear, I wish I could help but I don't think there is anything I can do about it. Android camera apps (even preinstalled ones) can ignore some parameters or, somehow in this case, stop working at all when a parameter is passed. I'm passing all the parameters in the standard format (see native code), which is why I don't think this issue can be resolved. You should unfortunately omit all parameters from your function to get rid of this issue.

    P.S. If you find any meaningful camera-related error messages in logcat, feel free to post them here. You can also try factory resetting the device to see if it changes anything.
     
  44. Krodon

    Krodon

    Joined:
    Dec 19, 2015
    Posts:
    4
    When I apply any parameter, the Media URI return this path: Media uri: content://com.sec.android.app.camera.files/my_cache/Video-VDO_20191208_133043.mp4

    When i didn't apply any parameter, the Media URI return: Media uri: content://media/external/video/media/695

    Does it's help in anything? Maybe applying in possible return path?
     
  45. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Yes that can definitely be helpful, thanks. Are there any other logs, for example "Trying to delete duplicate gallery item"?
     
  46. Krodon

    Krodon

    Joined:
    Dec 19, 2015
    Posts:
    4
    No, the return is just that. Also, when I apply the time on camera, he is not respected. For example, I set 10 seconds but the recording is past 10.
     
  47. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Yes, some camera apps may not respect the passed parameters. Unfortunately, that's something we have no control over.

    At the moment, I didn't make any progress over the original issue, googling "com.sec.android.app.camera.files" returned only one hit and it was irrelevant. Somehow, this code can't convert that path to an actual path. Please don't expect a bugfix in the near future; in the worst case, I may get rid of the camera parameters altogether to fix this issue. I'd again recommend you to not use any of the camera parameters as a workaround.
     
  48. Krodon

    Krodon

    Joined:
    Dec 19, 2015
    Posts:
    4
    Got it, I'll keep researching to see if I can find any solution. Thank you for your attention and quick responses!
     
    yasirkula likes this.
  49. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    185
    Has anyone figured out why loaded Images loaded from www or a server gets rotated?? I have searched and searched and cant find anything. When i take a portrait photo and upload it to my server it uploads fine.. When i load the image texture from the web it load rotated -90. not all do this, only portrait ones..
     
  50. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    185
    This is my code snippet that handles the image import...


    Code (CSharp):
    1.  private IEnumerator OnLoadGraphic()
    2.         {
    3.             _url = LoadedFeed.ImageURL;
    4.             if (!string.IsNullOrEmpty(_url))
    5.             {
    6.                 UnityWebRequest www = UnityWebRequestTexture.GetTexture(_url);
    7.                 yield return www.SendWebRequest();
    8.  
    9.                 if (www.isNetworkError || www.isHttpError)
    10.                 {
    11.  
    12.                 }
    13.                 else
    14.                 {
    15.                     Texture2D _texture = ((DownloadHandlerTexture)www.downloadHandler).texture;
    16.                  
    17.                  
    18.                  
    19.  
    20.                    
    21.  
    22.                     if (_texture != null)
    23.                     {
    24.                         rotateTexture(_texture);
    25.                         //ImageBody.sprite = Sprite.Create(_texture, new Rect(0.0f, 0.0f, _texture.width, _texture.height), new Vector2(0.5f, 0.5f), 100.0f);
    26.                        
    27.                        
    28.                      
    29.                     }
    30.                 }
    31.             }
    32.         }
    33.         public Texture2D rotateTexture(Texture2D image)
    34.         {
    35.  
    36.             Texture2D target = new Texture2D(image.height, image.width, image.format, false);    //flip image width<>height, as we rotated the image, it might be a rect. not a square image
    37.  
    38.             Color32[] pixels = image.GetPixels32(0);
    39.             pixels = rotateTextureGrid(pixels, image.width, image.height);
    40.             target.SetPixels32(pixels);
    41.          
    42.  
    43.             //flip image width<>height, as we rotated the image, it might be a rect. not a square image
    44.             ImageBody.texture = target;
    45.             float _bodyWidth = 800;
    46.             float _imageWidth = ImageBody.texture.width;
    47.             float _imageHeight = ImageBody.texture.height;
    48.             float _ratio = _imageWidth / _imageHeight;
    49.             float _expectedHeight = _imageHeight * _bodyWidth / _imageWidth;
    50.  
    51.             ImageRect.sizeDelta = new Vector2(_bodyWidth, _expectedHeight);
    52.             target.Apply();
    53.             UpdateUIRect();
    54.             return target;
    55.         }
    56.  
    57.  
    58.         public Color32[] rotateTextureGrid(Color32[] tex, int wid, int hi)
    59.         {
    60.             Color32[] ret = new Color32[wid * hi];      //reminder we are flipping these in the target
    61.  
    62.             for (int y = 0; y < hi; y++)
    63.             {
    64.                 for (int x = 0; x < wid; x++)
    65.                 {
    66.                     ret[y + (wid - 1 - x) * hi] = tex[x + y * wid];          //juggle the pixels around
    67.  
    68.                 }
    69.             }
    70.  
    71.             return ret;
    72.         }