Git Product home page Git Product logo

unitynativegallery's Introduction

Unity Native Gallery Plugin

Available on Asset Store: https://assetstore.unity.com/packages/tools/integration/native-gallery-for-android-ios-112630

Forum Thread: https://forum.unity.com/threads/native-gallery-for-android-ios-open-source.519619/

Discord: https://discord.gg/UJJt549AaV

GitHub Sponsors ☕

This plugin helps you save your images and/or videos to device Gallery on Android and Photos on iOS (other platforms aren't supported). It is also possible to pick an image or video from Gallery/Photos.

INSTALLATION

There are 5 ways to install this plugin:

  • import NativeGallery.unitypackage via Assets-Import Package
  • clone/download this repository and move the Plugins folder to your Unity project's Assets folder
  • import it from Asset Store
  • (via Package Manager) add the following line to Packages/manifest.json:
    • "com.yasirkula.nativegallery": "https://github.com/yasirkula/UnityNativeGallery.git",
  • (via OpenUPM) after installing openupm-cli, run the following command:
    • openupm add com.yasirkula.nativegallery

Android Setup

NativeGallery no longer requires any manual setup on Android.

iOS Setup

IMPORTANT: If you are targeting iOS 14 or later, you need to build your app with Xcode 12 or later to avoid any permission issues.

There are two ways to set up the plugin on iOS:

a. Automated Setup for iOS

  • (optional) change the values of Photo Library Usage Description and Photo Library Additions Usage Description at Project Settings/yasirkula/Native Gallery
  • (Unity 2017.4 or earlier) if your minimum Deployment Target (iOS Version) is at least 8.0, set the value of Deployment Target Is 8.0 Or Above to true at Project Settings/yasirkula/Native Gallery

b. Manual Setup for iOS

FAQ

  • How can I fetch the path of the saved image or the original path of the picked image on iOS?

You can't. On iOS, these files are stored in an internal directory that we have no access to (I don't think there is even a way to fetch that internal path).

  • Plugin doesn't work in a Windows/Mac/Linux build

Only Android & iOS platforms are supported. Editor functionality is for preview purposes only and uses Unity's Editor-only API.

  • Can't access the Gallery, it says "java.lang.ClassNotFoundException: com.yasirkula.unity.NativeGallery" in Logcat

If you are sure that your plugin is up-to-date, then enable Custom Proguard File option from Player Settings and add the following line to that file: -keep class com.yasirkula.unity.* { *; }

  • Android build fails, it says "error: attribute android:requestLegacyExternalStorage not found" in Console

android:requestLegacyExternalStorage attribute in AndroidManifest.xml fixes a rare UnauthorizedAccessException on Android 10 but requires you to update your Android SDK to at least SDK 29. If this isn't possible for you, you should open NativeGallery.aar with WinRAR or 7-Zip and then remove the <application ... /> tag from AndroidManifest.xml.

  • Nothing happens when I try to access the Gallery on Android

Make sure that you've set the Write Permission to External (SDCard) in Player Settings.

  • NativeGallery functions return Permission.Denied even though I've set "Write Permission" to "External (SDCard)"

Declare the WRITE_EXTERNAL_STORAGE permission manually in your Plugins/Android/AndroidManifest.xml file with the tools:node="replace" attribute as follows: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace"/> (you'll need to add the xmlns:tools="http://schemas.android.com/tools" attribute to the <manifest ...> element).

  • Saving image/video doesn't work properly

Make sure that the filename parameter of the Save function includes the file's extension, as well

HOW TO

A. Saving Media To Gallery/Photos

NativeGallery.SaveImageToGallery( byte[] mediaBytes, string album, string filename, MediaSaveCallback callback = null ): use this function if you have the raw bytes of the image.

  • On Android, your images/videos are saved at DCIM/album/filename. On iOS 14+, the image/video will be saved to the default Photos album (i.e. album parameter will be ignored). On earlier iOS versions, the image/video will be saved to the target album. Make sure that the filename parameter includes the file's extension, as well
  • MediaSaveCallback takes bool success and string path parameters. If the image/video is saved successfully, success becomes true. On Android, path stores where the image/video was saved to (is null on iOS). If the raw filepath can't be determined, an abstract Storage Access Framework path will be returned (File.Exists returns false for that path)

IMPORTANT: NativeGallery will never overwrite existing media on the Gallery. If there is a name conflict, NativeGallery will ensure a unique filename. So don't put {0} in filename anymore (for new users, putting {0} in filename was recommended in order to ensure unique filenames in earlier versions, this is no longer necessary).

NativeGallery.SaveImageToGallery( string existingMediaPath, string album, string filename, MediaSaveCallback callback = null ): use this function if the image is already saved on disk. Enter the file's path to existingMediaPath.

NativeGallery.SaveImageToGallery( Texture2D image, string album, string filename, MediaSaveCallback callback = null ): use this function to easily save a Texture2D to Gallery/Photos. If filename ends with ".jpeg" or ".jpg", texture will be saved as JPEG; otherwise, it will be saved as PNG.

NativeGallery.SaveVideoToGallery( byte[] mediaBytes, string album, string filename, MediaSaveCallback callback = null ): use this function if you have the raw bytes of the video. This function works similar to its SaveImageToGallery equivalent.

NativeGallery.SaveVideoToGallery( string existingMediaPath, string album, string filename, MediaSaveCallback callback = null ): use this function if the video is already saved on disk. This function works similar to its SaveImageToGallery equivalent.

B. Retrieving Media From Gallery/Photos

NativeGallery.GetImageFromGallery( MediaPickCallback callback, string title = "", string mime = "image/*" ): prompts the user to select an image from Gallery/Photos.

  • This operation is asynchronous! After user selects an image or cancels the operation, the callback is called (on main thread). MediaPickCallback takes a string parameter which stores the path of the selected image, or null if nothing is selected
  • title determines the title of the image picker dialog on Android. Has no effect on iOS
  • mime filters the available images on Android. For example, to request a JPEG image from the user, mime can be set as "image/jpeg". Setting multiple mime types is not possible (in that case, you should leave mime as "image/*"). Has no effect on iOS

NativeGallery.GetVideoFromGallery( MediaPickCallback callback, string title = "", string mime = "video/*" ): prompts the user to select a video from Gallery/Photos. This function works similar to its GetImageFromGallery equivalent.

NativeGallery.GetAudioFromGallery( MediaPickCallback callback, string title = "", string mime = "audio/*" ): prompts the user to select an audio file. This function works similar to its GetImageFromGallery equivalent. Works on Android only.

NativeGallery.GetMixedMediaFromGallery( MediaPickCallback callback, MediaType mediaTypes, string title = "" ): prompts the user to select an image/video/audio file. This function is available on Android 19 and later and all iOS versions. Selecting audio files is not supported on iOS.

  • mediaTypes is the bitwise OR'ed media types that will be displayed in the file picker dialog (e.g. to pick an image or video, use MediaType.Image | MediaType.Video)

NativeGallery.GetImagesFromGallery( MediaPickMultipleCallback callback, string title = "", string mime = "image/*" ): prompts the user to select one or more images from Gallery/Photos. MediaPickMultipleCallback takes a string[] parameter which stores the path(s) of the selected image(s)/video(s), or null if nothing is selected. Selecting multiple files from gallery is only available on Android 18 and later and iOS 14 and later. Call CanSelectMultipleFilesFromGallery() to see if this feature is available.

NativeGallery.GetVideosFromGallery( MediaPickMultipleCallback callback, string title = "", string mime = "video/*" ): prompts the user to select one or more videos from Gallery/Photos. This function works similar to its GetImagesFromGallery equivalent.

NativeGallery.GetAudiosFromGallery( MediaPickMultipleCallback callback, string title = "", string mime = "audio/*" ): prompts the user to select one or more audio files. This function works similar to its GetImagesFromGallery equivalent. Works on Android only.

NativeGallery.GetMixedMediasFromGallery( MediaPickMultipleCallback callback, MediaType mediaTypes, string title = "" ): prompts the user to select one or more image/video/audio files. Selecting audio files is not supported on iOS.

NativeGallery.CanSelectMultipleFilesFromGallery(): returns true if selecting multiple images/videos from Gallery/Photos is possible on this device.

NativeGallery.CanSelectMultipleMediaTypesFromGallery(): returns true if GetMixedMediaFromGallery/GetMixedMediasFromGallery functions are supported on this device.

NativeGallery.IsMediaPickerBusy(): returns true if the user is currently picking media from Gallery/Photos. In that case, another GetImageFromGallery, GetVideoFromGallery or GetAudioFromGallery request will simply be ignored.

Almost all of these functions return a NativeGallery.Permission value. More details about it is available below.

C. Runtime Permissions

Beginning with 6.0 Marshmallow, Android apps must request runtime permissions before accessing certain services, similar to iOS. Note that NativeGallery doesn't require any permissions for picking images/videos from Photos on iOS 11+, picking images/videos from Gallery on Android 34+ and saving images/videos to Gallery on Android 29+, so no permission dialog will be shown in these cases and the permission functions will return Permission.Granted.

There are two functions to handle permissions with this plugin:

NativeGallery.Permission NativeGallery.CheckPermission( PermissionType permissionType, MediaType mediaTypes ): checks whether the app has access to Gallery/Photos or not. PermissionType can be either Read (for GetImageFromGallery/GetVideoFromGallery functions) or Write (for SaveImageToGallery/SaveVideoToGallery functions).

  • mediaTypes determines for which media type(s) we're checking the permission for. Has no effect on iOS

NativeGallery.Permission is an enum that can take 3 values:

  • Granted: we have the permission to access Gallery/Photos
  • ShouldAsk: we don't have permission yet, but we can ask the user for permission via RequestPermission function (see below). On Android, as long as the user doesn't select "Don't ask again" while denying the permission, ShouldAsk is returned
  • Denied: we don't have permission and we can't ask the user for permission. In this case, user has to give the permission from Settings. This happens when user denies the permission on iOS (can't request permission again on iOS), when user selects "Don't ask again" while denying the permission on Android or when user is not allowed to give that permission (parental controls etc.)

NativeGallery.Permission NativeGallery.RequestPermission( PermissionType permissionType, MediaType mediaTypes ): requests permission to access Gallery/Photos from the user and returns the result. It is recommended to show a brief explanation before asking the permission so that user understands why the permission is needed and doesn't click Deny or worse, "Don't ask again". Note that the SaveImageToGallery/SaveVideoToGallery and GetImageFromGallery/GetVideoFromGallery functions call RequestPermission internally and execute only if the permission is granted (the result of RequestPermission is also returned).

void NativeGallery.RequestPermissionAsync( PermissionCallback callback, PermissionType permissionType, MediaType mediaTypes ): Asynchronous variant of RequestPermission. Unlike RequestPermission, this function doesn't freeze the app unnecessarily before the permission dialog is displayed. So it's recommended to call this function instead.

  • PermissionCallback takes NativeGallery.Permission permission parameter

Task<NativeGallery.Permission> NativeGallery.RequestPermissionAsync( PermissionType permissionType, MediaType mediaTypes ): Another asynchronous variant of RequestPermission (requires Unity 2018.4 or later).

NativeGallery.OpenSettings(): opens the settings for this app, from where the user can manually grant permission in case current permission state is Permission.Denied (on Android, the necessary permission is named Storage and on iOS, the necessary permission is named Photos).

bool NativeGallery.CanOpenSettings(): on iOS versions prior to 8.0, opening settings from within app is not possible and in this case, this function returns false. Otherwise, it returns true.

D. Utility Functions

NativeGallery.ImageProperties NativeGallery.GetImageProperties( string imagePath ): returns an ImageProperties instance that holds the width, height, mime type and EXIF orientation information of an image file without creating a Texture2D object. Mime type will be null, if it can't be determined

NativeGallery.VideoProperties NativeGallery.GetVideoProperties( string videoPath ): returns a VideoProperties instance that holds the width, height, duration (in milliseconds) and rotation information of a video file. To play a video in correct orientation, you should rotate it by rotation degrees clockwise. For a 90-degree or 270-degree rotated video, values of width and height should be swapped to get the display size of the video.

NativeGallery.MediaType NativeGallery.GetMediaTypeOfFile( string path ): returns the media type of the file at the specified path: Image, Video, Audio or neither of these (if media type can't be determined)

Texture2D NativeGallery.LoadImageAtPath( string imagePath, int maxSize = -1, bool markTextureNonReadable = true, bool generateMipmaps = true, bool linearColorSpace = false ): creates a Texture2D from the specified image file in correct orientation and returns it. Returns null, if something goes wrong.

  • maxSize determines the maximum size of the returned Texture2D in pixels. Larger textures will be down-scaled. If untouched, its value will be set to SystemInfo.maxTextureSize. It is recommended to set a proper maxSize for better performance
  • markTextureNonReadable marks the generated texture as non-readable for better memory usage. If you plan to modify the texture later (e.g. GetPixels/SetPixels), set its value to false
  • generateMipmaps determines whether texture should have mipmaps or not
  • linearColorSpace determines whether texture should be in linear color space or sRGB color space

async Task<Texture2D> NativeGallery.LoadImageAtPathAsync( string imagePath, int maxSize = -1, bool markTextureNonReadable = true ): asynchronous variant of LoadImageAtPath (requires Unity 2018.4 or later). Whether or not the returned Texture2D has mipmaps enabled depends on UnityWebRequestTexture's implementation on the target Unity version. Note that it isn't possible to load multiple images simultaneously using this function.

Texture2D NativeGallery.GetVideoThumbnail( string videoPath, int maxSize = -1, double captureTimeInSeconds = -1.0, bool markTextureNonReadable = true, bool generateMipmaps = true, bool linearColorSpace = false ): creates a Texture2D thumbnail from a video file and returns it. Returns null, if something goes wrong.

  • maxSize determines the maximum size of the returned Texture2D in pixels. Larger thumbnails will be down-scaled. If untouched, its value will be set to SystemInfo.maxTextureSize. It is recommended to set a proper maxSize for better performance
  • captureTimeInSeconds determines the frame of the video that the thumbnail is captured from. If untouched, OS will decide this value
  • markTextureNonReadable (see LoadImageAtPath)

async Task<Texture2D> NativeGallery.GetVideoThumbnailAsync( string videoPath, int maxSize = -1, double captureTimeInSeconds = -1.0, bool markTextureNonReadable = true ): asynchronous variant of GetVideoThumbnail (requires Unity 2018.4 or later). Whether or not the returned Texture2D has mipmaps enabled depends on UnityWebRequestTexture's implementation on the target Unity version. Note that it isn't possible to generate multiple video thumbnails simultaneously using this function.

EXAMPLE CODE

The following code has three functions:

  • if you click the left one-third of the screen, it captures the screenshot of the game and saves it to Gallery/Photos
  • if you click the middle one-third of the screen, it picks an image from Gallery/Photos and puts it on a temporary quad that is placed in front of the camera
  • if you click the right one-third of the screen, it picks a video from Gallery/Photos and plays it
void Update()
{
	if( Input.GetMouseButtonDown( 0 ) )
	{
		if( Input.mousePosition.x < Screen.width / 3 )
		{
			// Take a screenshot and save it to Gallery/Photos
			StartCoroutine( TakeScreenshotAndSave() );
		}
		else
		{
			// Don't attempt to pick media from Gallery/Photos if
			// another media pick operation is already in progress
			if( NativeGallery.IsMediaPickerBusy() )
				return;

			if( Input.mousePosition.x < Screen.width * 2 / 3 )
			{
				// Pick a PNG image from Gallery/Photos
				// If the selected image's width and/or height is greater than 512px, down-scale the image
				PickImage( 512 );
			}
			else
			{
				// Pick a video from Gallery/Photos
				PickVideo();
			}
		}
	}
}

// Example code doesn't use this function but it is here for reference. It's recommended to ask for permissions manually using the
// RequestPermissionAsync methods prior to calling NativeGallery functions
private async void RequestPermissionAsynchronously( NativeGallery.PermissionType permissionType, NativeGallery.MediaType mediaTypes )
{
	NativeGallery.Permission permission = await NativeGallery.RequestPermissionAsync( permissionType, mediaTypes );
	Debug.Log( "Permission result: " + permission );
}

private IEnumerator TakeScreenshotAndSave()
{
	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
	NativeGallery.Permission permission = NativeGallery.SaveImageToGallery( ss, "GalleryTest", "Image.png", ( success, path ) => Debug.Log( "Media save result: " + success + " " + path ) );

	Debug.Log( "Permission result: " + permission );

	// To avoid memory leaks
	Destroy( ss );
}

private void PickImage( int maxSize )
{
	NativeGallery.Permission permission = NativeGallery.GetImageFromGallery( ( path ) =>
	{
		Debug.Log( "Image path: " + path );
		if( path != null )
		{
			// Create Texture from selected image
			Texture2D texture = NativeGallery.LoadImageAtPath( path, maxSize );
			if( texture == null )
			{
				Debug.Log( "Couldn't load texture from " + path );
				return;
			}

			// Assign texture to a temporary quad and destroy it after 5 seconds
			GameObject quad = GameObject.CreatePrimitive( PrimitiveType.Quad );
			quad.transform.position = Camera.main.transform.position + Camera.main.transform.forward * 2.5f;
			quad.transform.forward = Camera.main.transform.forward;
			quad.transform.localScale = new Vector3( 1f, texture.height / (float) texture.width, 1f );

			Material material = quad.GetComponent<Renderer>().material;
			if( !material.shader.isSupported ) // happens when Standard shader is not included in the build
				material.shader = Shader.Find( "Legacy Shaders/Diffuse" );

			material.mainTexture = texture;

			Destroy( quad, 5f );

			// If a procedural texture is not destroyed manually, 
			// it will only be freed after a scene change
			Destroy( texture, 5f );
		}
	} );

	Debug.Log( "Permission result: " + permission );
}

private void PickVideo()
{
	NativeGallery.Permission permission = NativeGallery.GetVideoFromGallery( ( path ) =>
	{
		Debug.Log( "Video path: " + path );
		if( path != null )
		{
			// Play the selected video
			Handheld.PlayFullScreenMovie( "file://" + path );
		}
	}, "Select a video" );

	Debug.Log( "Permission result: " + permission );
}

// Example code doesn't use this function but it is here for reference
private void PickImageOrVideo()
{
	if( NativeGallery.CanSelectMultipleMediaTypesFromGallery() )
	{
		NativeGallery.Permission permission = NativeGallery.GetMixedMediaFromGallery( ( path ) =>
		{
			Debug.Log( "Media path: " + path );
			if( path != null )
			{
				// Determine if user has picked an image, video or neither of these
				switch( NativeGallery.GetMediaTypeOfFile( path ) )
				{
					case NativeGallery.MediaType.Image: Debug.Log( "Picked image" ); break;
					case NativeGallery.MediaType.Video: Debug.Log( "Picked video" ); break;
					default: Debug.Log( "Probably picked something else" ); break;
				}
			}
		}, NativeGallery.MediaType.Image | NativeGallery.MediaType.Video, "Select an image or video" );

		Debug.Log( "Permission result: " + permission );
	}
}

unitynativegallery's People

Contributors

bakwc avatar borod4r avatar fegabe avatar yasirkula avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

unitynativegallery's Issues

Unity iPhone photo saved is rotated, and, ratio is a bit different

I want to save a photo as:

  1. Portrait mode but its gets landscape
  2. When I rotate the photo, I feel its a bit zoomed in & a bit having a different ratio than iPhones photos taken with the iPhone camera.

Side question: is there is a way to save a video buffer (YCbCR) into a photo instead of using webCamTexture?

Cannot load texture(iOS)

Hi,

thank you very much for the package and apologies for perhaps a slightly dumb question :)

I'm working on iOS and having trouble on the
texture.LoadImage(File.ReadAllBytes(path));
line in PickImage() function. For some reason it is unable to go beyond that line. I checked the path and it showed only "/Asset.PNG". I'm suspecting the issue might be that the path is actually other than simply the file name but am unable to get it working.

I used the sample code provided with no changes other than adding "using System.IO;"

Thank you!

Getting saved images on PC

Hi! This issue doesn't relate to your plugin, but maybe you've got an experience with it.
The problem is when I'm saving new images on Android I want to connect my phone to PC and get them (see/copy/delete). But it seems Android refresh file cache not very frequently, anyway I can't see new files on PC right away. Have to wait a few minutes, some people have reported that images become available on PC in a few days. On the other side, if I make a screenshot (using default button combination), it appears on PC right away, I just need to open screenshots folder again.

Issue Take pictures

Friend this is an excellent plugin thank you, I have a question, in this plugin, can I take pictures with the camera an put the picture in my texture, and if not, it will be great that you implement this too in the plugin. Thank you for all

Could not share image in temporary path (cache folder)

Hello,

Thanks for the greate plugin!
I am using it and noticed that for the image files saved in temporary path Application.temporaryCachePath
It seemes the images cannot be loaded onto other apps when sharing!
Thank you!

Can't find the photos while working with the editor

Is there a way to see the saved files while working with Unity editor?
The package works great on Android, but I'd like to have a way to see the saved files while working with the editor for easier debugging

Video capture

This is a really nice plugin, thanks a lot! How would you recommend doing video capture (with audio) to generate the byte stream for NativeGallery.SaveVideoToGallery()?

I've seen some different solutions such as using the native android.media.projection or using FFMPEG bindings, or even construct it manually by capturing a lot of screenshots using Texture2D.ReadPixels(). What do you think would be the best solution?

Moving GIF on iOS

Hi!
First I'd like to thank you for your work. Awesome!
Is ti possible or there is any workaround to save gif files to the gallery on iOS?
On Android it works fine, but on iOS I get the following error:

Error Domain=AVFoundationErrorDomain Code=-11828 "Cannot Open" UserInfo={NSUnderlyingError=0x1c0658810 {Error Domain=NSOSStatusErrorDomain Code=-12847 "(null)"}, NSLocalizedFailureReason=This media format is not supported.

See the photo before save it

Hello There,

I am working on an app thats should take a photo and, before save it, show it and then the users can decide if they want to keep and share or delete.

For do this using NativeGallery.GetImageFromGallery I should know the name of the last photo taken, am I right?

Do you have any tips for how can I do this? Is there a function that show the photo after take it?

Thanks in advance for your help.

!!! Best Regards !!!

Lauro Paixão

Select uncompressed video on iOS

When choosing a video on iOS it appears to recompress (even videos captured directly on iOS device). Is it possible to access the video without recompression?

DeleteFromGallery

How to delete file? Why method DeleteFromGallery cant work in new version?

Freeze when canceling gallery

Hi! My app freezes (hangs) if I cancel gallery (by pressing cancel button or android back button).
Reproduced on 2 devices with Android 7 (Xiaomi Mi5 and ZUK Z2). Build with Unity 2018.
My manifest:
image

video play option is available in selection tab itself

Dear Developer,
Thanks for the wonderful script, it's helps a lot. In video selection process i tried to select the video from gallery the selected video ll play on gamescreen using unity video player. but in selection page itself there is an option to play the video. why the user want to play the video in 2 location? can you please tell me how to skip the video play option in selection screen. Thanks in advance

Regards
M Manoj Balaji

Please add Assembly Definition Files support.

It's currently compiled to firstpass dll. It's unable to use without a lot modification with Assembly Definition Files. Could you please rearrange your code to support Assembly Definition Files?

Just move the csharp files outside the Plugins folder. It will be ok.

Camera recorded video shows only colors

When I grab any video that is recorded with the camera of the device, it is not playing properly and it shows only colors and sound but the actual video is not coming.

Undefined symbols for architecture arm64:

Undefined symbols for architecture arm64:
"__ScreenshotWriteToAlbum", referenced from:
_NativeGallery__ScreenshotWriteToAlbum_m1836878830 in Bulk_Assembly-CSharp-firstpass_0.o
_NativeGallery_SaveToGallery_m178977206 in Bulk_Assembly-CSharp-firstpass_0.o
(maybe you meant: _NativeGallery__ScreenshotWriteToAlbum_m1836878830)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

UnauthorizedAccessException on some cases in Android

Hi, love the plugin, thanks for the effort!

On my game I'm getting some random "UnauthorizedAccessException" in production when some people select the photo on his gallery (Android) and I try to read it. I can't reproduce it on my end, Im getting the stacktraces on Unity analytics for a small percentage of my players.

I check the permission before calling GetImageFromGallery, and from what I see on the code of the method your plugin also checks for the permission, so I have no clue why is the exception happening, thought I should share here as an issue. If it's something I'm doing wrong I'm sorry, and please let me know how to fix :)

Exception:
UnauthorizedAccessException: Access to the path "/storage/6665-3432/DCIM/Camera/20180515_093426.jpg" is denied.

Stacktrace (edited a bit to simplify):
System.IO.File.Open (System.String path, FileMode mode) <-- exception here
(CALLBACK) MyGameScene.ProcessSelectedFilePath (System.String selectedFilePath)
(CALLBACK) MyGameScene.PhotoSelectionCallback (System.String selectedPhotoPath)
NativeGallery.GetMediaFromGallery (.MediaPickCallback callback, Boolean imageMode, System.String mime, System.String title, Int32 maxSize)
NativeGallery.GetImageFromGallery (.MediaPickCallback callback, System.String title, System.String mime, Int32 maxSize)

[Android] Saved image not showing in gallery

I can see the image being saved to the correct folder in DCIM/{folder}, but it is not showing up as an album or as a viewable picture in the gallery on device. Tested on the S6 and the OnePlus 3 and neither of them showed it.

Crash while fetching image from gallery in iOs

I am using this plugin for android and it works like a charm. Thanks for this plugin. But now when i am trying yo use for ios it allows me to select image but after that it is crashing everytime. I have tried different device and latest os. Also i am seeing the photo gallery which means there is no issue related to peemission. I am not sure what's the exact issue. Can you please look into this?

Prompt for only add permission on iOS

First of all love the plugin was just what I needed.

Would it be possible to be able to distinguish between NSPhotoLibraryUsageDescription and NSPhotoLibraryAddUsageDescription so that an app that only needs add access doesn't need to fill out NSPhotoLibraryUsageDescription and prompts with NSPhotoLibraryAddUsageDescription?

I couldn't seem to find any way to do this and NativeGallery.SaveImageToGallery prompts with NSPhotoLibraryUsageDescription as does NativeGallery.RequestPermission.

File Metadata

Kindly can you make

  • a function which returns the file (image & video) size
  • a function to return image width and height

Currently, it is just returning the file path, that's good. It would be much better if you return above-mentioned data as Metadata in the callback when picked/selected an image/video.

Looking forward to your help! :)

Problem in saving the image or screenshot using "SaveImageToGallery" function

Actually I am trying to take a screenshot and save it into the Android gallery, my code is following:

    NativeGallery.Permission permission = NativeGallery.CheckPermission();
    if (permission == NativeGallery.Permission.Granted) {
         Debug.Log("May proceed");
     }
    else {
         Debug.Log("Not allowed");
    }

         Debug.Log("Path is "+NativeGallery.GetSavePath("GalleryTest","My_img_{0}.png"));
         //Output ==>  /storage/emulated/0/DCIM/GalleryTest/My_img_1.png

    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();
    Debug.Log("Secondlast");
    permission = NativeGallery.SaveImageToGallery( ss, "GalleryTest", "My_img_{0}.png" ) ;
    Debug.Log("Done screenshot");

but my it never save the screenshot, when i see the console, I get 2 important logs
1.My Debug log "SecondLast" was print on the console but not the last one "Done screenshot"
2.There is an exception printed "UnauthorizedAccessException: Access to the path "/storage/emulated/0/DCIM/GalleryTest/My_img_1.png" is denied."

Important point :- I already already set the Write permissions to External (SDCard) in unity player settings. (actually I try with both settings "Internal" and "External")

Having problem loading texture

Hi, @yasirkula

i'm using your example code and after picking the image the quad appears with a full color of violet, seems it loaded wrong? And i'm trying to retrieve the texture to pass it to a string64. Not sure what it is or if i'm doing something wrong. What i do is to put it into memory and pass it to string64 but zero results. I believe it is null, that is why load all in a color of violet. A little hand?

iOS permission setting problem

The key should be Privacy - Photo Library Additions Usage Description instead of Privacy - Photo Library Usage Description.

By the way, thanks for the plugin! It's exactly what I need.

Cropping Image Support?

Dear @yasirkula ,

Is it possible "easy" to add cropping feature after selecting the image?
I want a squared resolution image that can be used as a profile picture.

Any guidelines for this?
Is there a way to integrate it with the "Android Image Cropper" plugin by ArthurHub?

Thanks in advance

How to run SaveVideoToGallery

Thank you for your amazing script!

In your script there are..

public static Permission SaveVideoToGallery( byte[] mediaBytes, string album, string filenameFormatted, MediaSaveCallback callback = null )
{
return SaveToGallery( mediaBytes, album, filenameFormatted, false, callback );
}

Is this screen recording? Can you give me an example?
I need help :(

iOS not Loading picture

Hello!

First I'd like to thank you for the incredible work!

On android it works perfectly although I'm facing an issue on iOS. The first time I call my gallery method it asks for permission, opens the gallery, but does nothing after that. It looks like it doesn't catch the path on the first attempt, but on my second try, it doesn't matter which picture I choose, it brings the previous picture instead. Something like if it holds the picture somewhere, but never uses it, and brings it back later, on the next call.

I'm using it together with the ImageCrop made yourself, but not sure if I did something wrong! :(
Would be able to help me on this?

Thanks in advance.

Video not working on iOS

I imported your asset from unity asset store, image gallery is working perfectly fine. But I am having issue displaying video. After I select the video from gallery, it starts compressing it and after compression the video is not getting displayed on the RawImage.

Kindly help I am getting following problem in my Xcode:

UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
UnityEngine.Logger:Log(LogType, Object)
UnityEngine.Debug:Log(Object)
ImageGallery:m__0(String)
MediaPickCallback:Invoke(String)
NativeGalleryNamespace.NGMediaReceiveCallbackiOS:OnMediaReceived(String)

(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)

2018-04-11 13:10:33.353399+0500 ar[375:53933] [] <<<< AVOutputDeviceDiscoverySession (FigRouteDiscoverer) >>>> -[AVFigRouteDiscovererOutputDeviceDiscoverySessionImpl outputDeviceDiscoverySessionDidChangeDiscoveryMode:]: Setting device discovery mode to DiscoveryMode_None (client: ar)
2018-04-11 13:10:33.746004+0500 ar[375:53933] Warning: Attempt to present <AVPlayerViewController: 0x13c2d6e00> on <UIImagePickerController: 0x13c275000> whose view is not in the window hierarchy!
2018-04-11 13:10:33.750622+0500 ar[375:54387] [discovery] errors encountered while discovering extensions: Error Domain=PlugInKit Code=13 "query cancelled" UserInfo={NSLocalizedDescription=query cancelled}

Replacing files

Hi! I know your plugin can handle the situation when a file with the same name exists. It performs action automatically by developer's descision. But general behaviour is to ask a user to overwrite or not.
My suggestion is to make GetSavePath public so developer could check if file exists and promt user to overwrite an image.

Undefined symbols for architecture arm64

Hello,
I am using latest Xcode and unity versions and getting the following error:
Undefined symbols for architecture arm64:
"OBJC_CLASS$_ALAssetsLibrary", referenced from:
objc-class-ref in NativeGallery.o
"_ALAssetsGroupPropertyName", referenced from:
___49+[UNativeGallery saveMediaOld:albumName:isImage:]_block_invoke.94 in NativeGallery.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Gallery Open

  • Can you implement a feature to open the native Gallery for Android and iOS and allow pick/select just 1 image or video and return it respectively according to the separate function call of image or video?
  • Also, if image function is called show only images, and if video function is called show only videos.

It's an urgent request. So looking forward to your reply soon

image rotation after opening from gallery

Hello,
I am using iOS 11.3 and iphone7+ . I open an image and the rotation of it is normally either 90 or 180 degrees different to the original image.
I am putting the image into a material like in your example and using in ARKit . Any idea why?

Material material = frame1.GetComponent<Renderer>().material;
if( !material.shader.isSupported ) // happens when Standard shader is not included in the build
material.shader = Shader.Find( "Legacy Shaders/Diffuse" );
if(material.mainTexture!=null) Destroy(material.mainTexture);
material.mainTexture = texture;

Screen shot was not saving when use from android studio to unity3d

Hai iam using UnityNativeGallery for taking screen shot in Unity3D.After Exporting my unity project into android studio i have use UnitySendMessage in android to communicate C# Script in Unity3d.In that way i was used to take a screenshot when android native button click but screen shot not saved in this method.

Gif support

is animated gif save to gallery supported

iOS 12 NSCocoaErrorDomain

Have tried passing bytes and just the file path. (The file is definitely written to the internal path, juts not passing to photo gallery) Receive this error when trying to write to the photo gallery.

Error creating asset: Error Domain=NSCocoaErrorDomain Code=-1 "(null)"

Google Drive support on Android?

My game was originally made on native Android, and my gallery integration was a bit messy but it would allow the user to select photos from his Google Drive account (besides local photos).

Now I migrated my game to Unity and found your awesome plugin which saved me a lot of time, but some players are complaining that they lost the ability to read the photos from their Google Drive account.

So here is my suggestion, and I believe a lot of your users would be happy with this feature as well.

Thanks again for such a great plugin!

Black Image Saving in Photos

I have tried to take a screenshot with button action. It saves only the black image under photos directory. Did I miss anything?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.