Search Unity

Question Save image in VR Quest 2 - Screenshot cam

Discussion in 'VR' started by c4stor, Oct 19, 2022.

  1. c4stor

    c4stor

    Joined:
    Mar 16, 2019
    Posts:
    5
    I need to take a picture from the game camera (screenshot) and save the image in VR.

    Take a screenshot I got it in several ways.

    The biggest problem is saving the image in VR.

    A screenshot only appears when I run it in Unity game mode.

    I did a test in Start() and passing a sprite just to try to save in VR based on this tutorial but without success:

    https://forums.oculusvr.com/t5/Unit...ard-Oculus-Screenshots-on-Quest-2/td-p/952686

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. using System;
    6.  
    7. public class ScreenAndroid : MonoBehaviour
    8. {
    9.     //public AndroidExtensions Screen1 = new AndroidExtensions();
    10.  
    11.     public Texture2D Imagem;
    12.     public string title;
    13.     public string description;
    14.  
    15.  
    16.  
    17.     private void Start()
    18.     {
    19.         AndroidExtensions.SaveImageToGallery(Imagem, title, description);
    20.  
    21.         var appName = Application.identifier;
    22.         var fileName = $"{appName}-{DateTime.Now:yyMMdd-hhmmss}";
    23.  
    24.  
    25.  
    26. #if UNITY_ANDROID
    27.         AndroidExtensions.SaveImageToGallery(Imagem, fileName, "Some description");
    28. #endif
    29.     }
    30. }
    upload_2022-10-19_0-39-43.png

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. [SerializeField]
    6. public class AndroidExtensions
    7. {
    8.     private static AndroidJavaObject _activity;
    9.  
    10.     private static AndroidJavaObject Activity
    11.     {
    12.         get
    13.         {
    14.             if (_activity != null) return _activity;
    15.             var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    16.             _activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
    17.             return _activity;
    18.         }
    19.     }
    20.  
    21.     private const string MediaStoreImagesMediaClass = "android.provider.MediaStore$Images$Media";
    22.  
    23.     public static string SaveImageToGallery(Texture2D texture2D, string title, string description)
    24.     {
    25.         using var mediaClass = new AndroidJavaClass(MediaStoreImagesMediaClass);
    26.         using var cr = Activity.Call<AndroidJavaObject>("getContentResolver");
    27.         var image = Texture2DToAndroidBitmap(texture2D);
    28.         var imageUrl = mediaClass.CallStatic<string>("insertImage", cr, image, title, description);
    29.        
    30.         Debug.Log("imageUrl");
    31.         return imageUrl;
    32.     }
    33.  
    34.     private static AndroidJavaObject Texture2DToAndroidBitmap(Texture2D texture2D)
    35.     {
    36.         var encoded = texture2D.EncodeToPNG();
    37.         using var bf = new AndroidJavaClass("android.graphics.BitmapFactory");
    38.         return bf.CallStatic<AndroidJavaObject>("decodeByteArray", encoded, 0, encoded.Length);
    39.     }
    40. }
    Android manifest:
    upload_2022-10-19_0-40-30.png
    Code (CSharp):
    1. <?xml version="1.0" encoding="utf-8"?>
    2. <manifest
    3.     xmlns:android="http://schemas.android.com/apk/res/android"
    4.     package="com.unity3d.player"
    5.     xmlns:tools="http://schemas.android.com/tools">
    6.  
    7.   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    8.   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    9.  
    10.     <application android:requestLegacyExternalStorage="true">
    11.         <activity android:name="com.unity3d.player.UnityPlayerActivity"
    12.                   android:theme="@style/UnityThemeSelector">
    13.             <intent-filter>
    14.                 <action android:name="android.intent.action.MAIN" />
    15.                 <category android:name="android.intent.category.LAUNCHER" />
    16.             </intent-filter>
    17.             <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
    18.         </activity>
    19.     </application >
    20. </manifest>
     
  2. DevDunk

    DevDunk

    Joined:
    Feb 13, 2020
    Posts:
    5,048
  3. c4stor

    c4stor

    Joined:
    Mar 16, 2019
    Posts:
    5
    Saving it locally wasn't working

    In the previous script I'm trying to pass a sprite to Quest 2 for testing.

    I changed, I will test
    upload_2022-10-19_8-47-49.png
     
  4. c4stor

    c4stor

    Joined:
    Mar 16, 2019
    Posts:
    5
    I solved the doubts. I made a different code.


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PictureCam : MonoBehaviour
    6. {
    7.     public Camera eyedropperCamera;
    8.  
    9.     private Texture2D eyedropperTexture;
    10.     private Rect eyeRect;
    11.     private bool firstGetPixel = true;
    12.     private RenderTexture eyedropperRenderTexture;
    13.  
    14.     public void Trigger1()
    15.     {
    16.         StartCoroutine(TriggerTimeX());
    17.     }
    18.  
    19.     public IEnumerator TriggerTimeX()
    20.     {
    21.         yield return new WaitForSeconds(2);
    22.         StartCoroutine(GetPixel(true));
    23.         yield return new WaitForSeconds(1);
    24.         StartCoroutine(GetPixel(true));
    25.     }
    26.  
    27.     public IEnumerator GetPixel(bool saveImage)
    28.     {
    29.         yield return new WaitForEndOfFrame();
    30.  
    31.         if (firstGetPixel)
    32.         {
    33.             firstGetPixel = false;
    34.  
    35.             eyedropperTexture = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false);
    36.             eyeRect = new Rect(0, 0, Screen.width, Screen.height);
    37.  
    38.             eyedropperRenderTexture = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.ARGB32);
    39.             eyedropperRenderTexture.Create();
    40.  
    41.             eyedropperCamera.targetTexture = eyedropperRenderTexture;
    42.             eyedropperCamera.enabled = false;
    43.         }
    44.  
    45.         RenderTexture currentRT = RenderTexture.active;
    46.         try
    47.         {
    48.             RenderTexture.active = eyedropperCamera.targetTexture;
    49.             eyedropperCamera.backgroundColor = eyedropperCamera.backgroundColor;
    50.             eyedropperCamera.transform.position = eyedropperCamera.transform.position;
    51.             eyedropperCamera.transform.rotation = eyedropperCamera.transform.rotation;
    52.             eyedropperCamera.Render();
    53.             eyedropperTexture.ReadPixels(new Rect(0, 0, eyedropperCamera.targetTexture.width, eyedropperCamera.targetTexture.height), 0, 0);
    54.         }
    55.         finally
    56.         {
    57.             RenderTexture.active = currentRT;
    58.         }
    59.  
    60.         string name = "Screenshot_EpicApp" + System.DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") + ".png";
    61.  
    62.         NativeGallery.SaveImageToGallery(eyedropperTexture, "Myapp pictures", name);
    63.     }
    64.  
    65. }
    66.  
     
  5. fengyuan2022

    fengyuan2022

    Joined:
    Dec 8, 2022
    Posts:
    1
    i got try your function
     
  6. vj8109505

    vj8109505

    Joined:
    Apr 16, 2023
    Posts:
    1
    hi I put in your code its working in oculus quest2 but, if i take a screenshot app screen was lagged