Not getting image from Persistant path in Android using unity3d - c#

I have a script to take screenshot and save that image and to show that image in a plane.
But not getting that texture.
private string path;
void Start () {
path = Application.persistentDataPath;
}
void captureScreeshot(){
Application.CaptureScreenshot(path + "/Screenshot.png");
alert.text = "saved";
StartCoroutine(saveScreenshot());
onetimeBool = false;
}
IEnumerator saveScreenshot(){
WWW imgfile = new WWW("file://" + path+ "/Screenshot.png");
yield return imgfile;
if(imgfile.error==null){
img = new Texture2D(200, 200, TextureFormat.RGB24, false);
imgfile.LoadImageIntoTexture(img);
alert.text = "got image";
GameObject.Find("plane").renderer.material.mainTexture = img;
}else{
print(imgfile.error);
}
}
Images gets saved.
But I cannot open (load) image in system and android.
Getting error in system :
Couldn't open file /Users/ether/AppData/LocalLow/Company/Project/Screenshot.png
How to get it ???

This is because your path is wrong, you should use: application.dataPath, instead of Application.persistentDataPath.

Related

I want to make a png image of StreamingAssets a texture of material

I want to make an image existing in Streaming Assets a texture for a 3D object.
However, the texture of _Material becomes a red "Interrogation mark".
Interrogation mark
This is incorrect.
How can I get the correct image?
Material _Material;
IEnumerator LoadPlayerTexture()
{
string url = Path.Combine(Application.streamingAssetsPath, "front.png");
#if UNITY_EDITOR
url = "file://" + url;
#endif
byte[] imgData;
Texture2D tex = new Texture2D(2, 2);
//Check if we should use UnityWebRequest or File.ReadAllBytes
if (url.Contains("://") || url.Contains(":///"))
{
UnityWebRequest www = UnityWebRequest.Get(url);
yield return www.SendWebRequest();
imgData = www.downloadHandler.data;
}
else
{
imgData = File.ReadAllBytes(url);
}
//Load raw Data into Texture2D
tex.LoadImage(imgData);
_Material.SetTexture("_MainTex", tex);
}
Why don't you use UnityWebRequestTexture.GetTexture instead?
Note that UnityWebRequest can also be used for local files and is even the recommended way.
Little limit (that doesn't affect your use case)
Note: Only JPG and PNG formats are supported.
Material _Material;
IEnumerator LoadPlayerTexture()
{
var url = Path.Combine(Application.streamingAssetsPath, "front.png");
// UnityWebRequest can also be used for reading local files
// also from streaming assets
using(var uwr = UnityWebRequestTexture.GetTexture(url))
{
yield return uwr.SendWebRequest();
if (uwr.isNetworkError || uwr.isHttpError)
{
Debug.Log(uwr.error);
}
else
{
// Get downloaded texture
var texture = DownloadHandlerTexture.GetContent(uwr);
_Material.SetTexture("_MainTex", texture);
}
}
}
I created the texture with standard Windows software, "Paint".
This was the problem.
The problem was solved by exporting the texture created by "paint" with "GIMP".

How to save a captured photo from unity in Android Image Gallery?

I have a valid script that takes a photo with the AR camera and saves it in data files of Android, like so :
screenShotName = "Dorot" + System.DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".png";
File.WriteAllBytes(Application.persistentDataPath + "/" + screenShotName, screenshot.EncodeToPNG());
GameObject.Find("MainCanvas").GetComponent<Canvas>().enabled = true;
How can I change the persistentDataPath with the right path of Android Image Gallery.
Thanks.
I am using Unity Native Gallery Plugin to do the same exact thing.
This is my code
public class ScreenshotTaker : MonoBehaviour
{
public bool takingScreenshot = false;
public void CaptureScreenshot()
{
StartCoroutine(TakeScreenshotAndSave());
}
private IEnumerator TakeScreenshotAndSave()
{
takingScreenshot = true;
yield return new WaitForEndOfFrame();
Texture2D ss = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
ss.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
ss.Apply();
// Save the screenshot to Gallery/Photos
string name = string.Format("{0}_Capture{1}_{2}.png", Application.productName, "{0}", System.DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
Debug.Log("Permission result: " + NativeGallery.SaveImageToGallery(ss, Application.productName + " Captures", name));
takingScreenshot = false;
}
}
You can do it as JackMini36 said in his answer by using the plugin. Or you can write you piece of code do that.
But the challenging part will be to make it cross platform and permission issues on Android devices. Here is nicely describe article where you can learn different way to save screenshot in gallery in unity applications.
http://unitydevelopers.blogspot.com/2018/09/save-screenshot-in-unity3d.html

Screen Captures Using Unity and ARKit

I'm taking a screenshot in a Unity application using
ScreenCapture.CaptureScreenshot ("screenshot.png", 2);
But the AR background being rendered by ARKit ends up being completely black with other GameObjects rendering correctly (floating in black space).
Have others encountered this issue?
Is there a known workaround?
There are too many bugs with ScreenCapture.CaptureScreenshot. Do not use this function to preform any screenshot in Unity at this moment. It's not just on iOS, there are also bug on with this function in the Editor.
Here is a remake of that function that can take screenshot in png, jpeg or exr format.
IEnumerator CaptureScreenshot(string filename, ScreenshotFormat screenshotFormat)
{
//Wait for end of frame
yield return new WaitForEndOfFrame();
Texture2D screenImage = new Texture2D(Screen.width, Screen.height);
//Get Image from screen
screenImage.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
screenImage.Apply();
string filePath = Path.Combine(Application.persistentDataPath, "images");
byte[] imageBytes = null;
//Convert to png/jpeg/exr
if (screenshotFormat == ScreenshotFormat.PNG)
{
filePath = Path.Combine(filePath, filename + ".png");
createDir(filePath);
imageBytes = screenImage.EncodeToPNG();
}
else if (screenshotFormat == ScreenshotFormat.JPEG)
{
filePath = Path.Combine(filePath, filename + ".jpeg");
createDir(filePath);
imageBytes = screenImage.EncodeToJPG();
}
else if (screenshotFormat == ScreenshotFormat.EXR)
{
filePath = Path.Combine(filePath, filename + ".exr");
createDir(filePath);
imageBytes = screenImage.EncodeToEXR();
}
//Save image to file
System.IO.File.WriteAllBytes(filePath, imageBytes);
Debug.Log("Saved Data to: " + filePath.Replace("/", "\\"));
}
void createDir(string dir)
{
//Create Directory if it does not exist
if (!Directory.Exists(Path.GetDirectoryName(dir)))
{
Directory.CreateDirectory(Path.GetDirectoryName(dir));
}
}
public enum ScreenshotFormat
{
PNG, JPEG, EXR
}
USAGE:
void Start()
{
StartCoroutine(CaptureScreenshot("screenshot", ScreenshotFormat.PNG));
}

Picture appears only after restart the device

I have an Android-App that takes pictures and saves them in an external storage ("DCIM/Cameras"). But the pictures appear only after restarting my handy.
Is there some kind of Update or a way around this?
My source-code from saving my image:
var dir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDcim);
var pictures = dir.AbsolutePath + "/Camera";
string name = System.DateTime.Now.ToString("yyyyMMdd_HHmmssfff") + ".jpg";
string filePath = System.IO.Path.Combine(pictures, name);
FileStream output;
Bitmap bitmap = BitmapFactory.DecodeByteArray(imageData, 0, imageData.Length);
try
{
output = new FileStream(filePath, FileMode.Create);
bitmap.Compress(Bitmap.CompressFormat.Jpeg, 100, output);
output.Close();
//Static Class that contains an methode for MediaScannerConnection.ScanFile
MediaGalleryHelper.AddFileToGallery(name);
}
catch (System.Exception ex)
{
System.Console.WriteLine(ex.ToString());
}
You have to let the photo gallery know that a new photo has been added. You can use below code for that:
this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + filePath)));
Where 'this' is an activity.

Why Unity3D Application.CaptureScreenshot for Android doesn't work?

I have tried all this links bellow:
Not getting image from Persistant path in Android using unity3d
https://developer.vuforia.com/forum/unity-3-extension-technical-discussion/capture-screen-problem-androidhelp
http://answers.unity3d.com/questions/731509/applicationcapturescreenshot-doesnt-save-anything.html
I need to set the path for saving the pictures with an application for Android and IOS with UNITY
http://answers.unity3d.com/questions/200173/android-how-to-refresh-the-gallery-.html#answer-893069
Every time i build an apk, install it on Android device, nothing happend.
Log doesn't exists, so i tryed all this links and then go to /DCIM/Camera/ to see if is it saved, no, nothing...
On iOS i did that, and work perfectly.
Here is some code where i stuck... or the things on Android wont work...
I don't know why no error appear or some file strange in folder
void saveImage()
{
#if UNITY_ANDROID
string theFileName = "Screenshot_" + System.DateTime.Now.ToString("MM_dd_yyyy") +"_"+ System.DateTime.Now.ToString("hh_mm_ss") +".png";
// Many different test, trying to discovery witch will work...
Application.CaptureScreenshot( Application.dataPath + "_" + theFileName );
Application.CaptureScreenshot( "../../../../DCIM/Camera/pathroot_" + theFileName );
Application.CaptureScreenshot( "/storage/emulated/0/DCIM/Camera/" + theFileName );
Application.CaptureScreenshot( "file:///storage/emulated/0/DCIM/Camera/" + theFileName );
StartCoroutine(TakeScreenshot()); // Different test
#endif
#if UNITY_IPHONE
// This work... so, does not need to be here...
#endif
}
This is the method that "Coroutine" calls ( copy from one of those links above ):
private IEnumerator TakeScreenshot()
{
yield return new WaitForEndOfFrame();
//INITIAL SETUP
string myFilename = "Screenshot_" + System.DateTime.Now.ToString("MM_dd_yyyy") +"_"+ System.DateTime.Now.ToString("hh_mm_ss") +".png";
string myDefaultLocation = Application.dataPath + "/" + myFilename;
//EXAMPLE OF DIRECTLY ACCESSING THE Camera FOLDER OF THE GALLERY
//string myFolderLocation = "/storage/emulated/0/DCIM/Camera/";
//EXAMPLE OF BACKING INTO THE Camera FOLDER OF THE GALLERY
//string myFolderLocation = Application.persistentDataPath + "/../../../../DCIM/Camera/";
//EXAMPLE OF DIRECTLY ACCESSING A CUSTOM FOLDER OF THE GALLERY
string myFolderLocation = "/storage/emulated/0/DCIM/Camera/";
string myScreenshotLocation = myFolderLocation + myFilename;
//ENSURE THAT FOLDER LOCATION EXISTS
if(!System.IO.Directory.Exists(myFolderLocation)){
System.IO.Directory.CreateDirectory(myFolderLocation);
}
//TAKE THE SCREENSHOT AND AUTOMATICALLY SAVE IT TO THE DEFAULT LOCATION.
Application.CaptureScreenshot(myFilename);
//MOVE THE SCREENSHOT WHERE WE WANT IT TO BE STORED
System.IO.File.Move(myDefaultLocation, myScreenshotLocation);
//REFRESHING THE ANDROID PHONE PHOTO GALLERY IS BEGUN
AndroidJavaClass classPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject objActivity = classPlayer.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaClass classUri = new AndroidJavaClass("android.net.Uri");
AndroidJavaObject objIntent = new AndroidJavaObject("android.content.Intent", new object[2]{"android.intent.action.MEDIA_MOUNTED", classUri.CallStatic<AndroidJavaObject>("parse", "file://" + myScreenshotLocation)});
objActivity.Call ("sendBroadcast", objIntent);
//REFRESHING THE ANDROID PHONE PHOTO GALLERY IS COMPLETE
//AUTO LAUNCH/VIEW THE SCREENSHOT IN THE PHOTO GALLERY
Application.OpenURL(myScreenshotLocation);
//AFTERWARDS IF YOU MANUALLY GO TO YOUR PHOTO GALLERY,
//YOU WILL SEE THE FOLDER WE CREATED CALLED "myFolder"
}
Try This: (Tested & Works):
Application.CaptureScreenshot ("screenshot.png");
store screenshot at:
Application.persistentDataPath, "screenshot.png" i.e data/data/package_name/files
void captureScreenshot(string result){
if (result == "true") {
StartCoroutine(CaptureScreen());
}
}
void OnGUI(){
if (GUI.Button (new Rect (20, 70, 100, 45), "Click"))
captureScreenshot ("true");
}
public IEnumerator CaptureScreen()
{
// Wait for screen rendering to complete
yield return new WaitForEndOfFrame();
Application.CaptureScreenshot ("screenshot.png");
string Origin_Path = System.IO.Path.Combine (Application.persistentDataPath, "screenshot.png");
Debug.Log ("Origin_Path save is " + Origin_Path);
// This is the path of my folder.
string Path = "/mnt/sdcard/" + "screenshot.png";
Debug.Log ("Path save is " + Path);
if (System.IO.File.Exists (Origin_Path)) {
System.IO.File.Move (Origin_Path, Path);
Debug.Log ("Path_move save is " + Path);
}
jo.Call<bool> ("screenshotHandler", "screenshot.png");
}
If you want to store in gallery without Move again then you can use:
Application.CaptureScreenshot ("../../../../DCIM/screenshot.png");
If Error: System.IO.File.Exists (Origin_Path)
//returns FALSE even though file exists at Origin_Path.
Please try this:
public IEnumerator CaptureScreen()
{
Application.CaptureScreenshot ("../../../../DCIM/"+fileName);
Debug.Log ("Sanky: Screen Captured");
while (!File.Exists (filePath)) {
Debug.Log ("Sanky: File exist at location"+filePath);
yield return 0;
}
/////// do whatever you want
}

Categories