Unity Android Galeri Etkileşimi (Resim/Video Kaydetmek veya Yüklemek)

Yayınlandı: 04 Haziran 2018 yasirkula tarafından Oyun Tasarımı, UNITY 3D içinde

Merhabalar,

Bu Unity dersinde, Android ve iOS platformlarda nasıl cihazın galerisine resim/video kaydedebileceğinizi veya galeriden resim/video çekebileceğinizi göstereceğim. Bu iş için kendi yazdığım NativeGallery plugin’ini kullanacağız.

Hazırsanız başlayalım!

Kurulum

Öncelikle şu adresteki unitypackage‘ı Assets-Import Package yoluyla projenize import edin:  https://github.com/yasirkula/UnityNativeGallery/releases

Alternatif olarak, asset’i Asset Store’dan da import edebilirsiniz: https://assetstore.unity.com/packages/tools/integration/native-gallery-for-android-ios-112630

Eğer Android’e build alacaksanız Edit-Project Settings-Player‘daki Write Permission‘ı External (SDCard) yapın.

Eğer iOS’a build alacaksanız, Plugins/NativeGallery/Editor/NGPostProcessBuild.cs scriptindeki PHOTO_LIBRARY_USAGE_DESCRIPTION‘ın değerini dilerseniz değiştirin. Buraya girdiğiniz yazı, kullanıcıdan galeriye erişim izni isterken gözükecek.

Fonksiyonlar

A) Resim Kaydetmek

Galeriye resim kaydetmek için 3 farklı fonksiyon mevcut:

  • NativeGallery.SaveImageToGallery( byte[] mediaBytes, string album, string filename, MediaSaveCallback callback = null )

Eğer resmi bir byte array‘inde tutuyorsanız bu fonksiyonu kullanın. Bir texture‘un byte array’ine EncodeToPNG veya EncodeToJPG fonksiyonlarıyla erişebilirsiniz.

album: Resmin kaydedileceği albümü belirler.

filename: Resim dosyasının ismini belirler. Dosya ismine uzantıyı da eklemeyi unutmayın.

Resim Android’de DCIM/album/filename konumuna yazılırken iOS’ta ise cihazın galeri için rezerve ettiği özel bir konuma yazılır.

callback: Eğer buraya string parametre alan bir fonksiyon verirseniz, resmin kaydedilmesi bittikten sonra bu fonksiyon çağrılır. Eğer resim başarıyla kaydedildiyse bu string’in değeri null olurken bir hata olduysa hata mesajı bu string’de depolanır.

  • NativeGallery.SaveImageToGallery( string existingMediaPath, string album, string filename, MediaSaveCallback callback = null )

Eğer halihazırda varolan bir resim dosyasını galeriye kaydetmek istiyorsanız bu fonksiyonu kullanın. Bu durumda resim dosyası ilgili albüme kopyalanacaktır.

existingMediaPath: Varolan resim dosyasının konumunu buraya girmelisiniz.

  • NativeGallery.SaveImageToGallery( Texture2D image, string album, string filename, MediaSaveCallback callback = null )

Bir Texture2D objesini galeriye kaydetmek için bu fonksiyonu kullanabilirsiniz. Eğer filename parametresi .jpg veya .jpeg ile biterse texture JPEG formatında, yoksa PNG formatında kaydedilir.

B) Video Kaydetmek

  • NativeGallery.SaveVideoToGallery( byte[] mediaBytes, string album, string filename, MediaSaveCallback callback = null )

Eğer video’yu bir byte array‘inde tutuyorsanız bu fonksiyonu kullanın. Mesela projenizde yer alan bir video asset’ini bu fonksiyon ile galeriye kaydetmek isterseniz, videoyu scriptinizdeki bir TextAsset değişkenine değer olarak verebilir ve mediaBytes‘a değer olarak textAssetDegiskeni.bytes verebilirsiniz.

  • NativeGallery.SaveVideoToGallery( string existingMediaPath, string album, string filename, MediaSaveCallback callback = null )

Eğer halihazırda varolan bir video dosyasını galeriye kaydetmek istiyorsanız bu fonksiyonu kullanın. Bu durumda video dosyası ilgili albüme kopyalanacaktır.

C) Galeriden Resim Çekmek

  • NativeGallery.GetImageFromGallery( MediaPickCallback callback, string title = "", string mime = "image/*" )

callback: Kullanıcı galeriden bir resim seçince veya işlemi iptal edince bu fonksiyon çağrılır. Buraya vereceğiniz fonksiyon bir string parametre almak zorundadır. Eğer işlem iptal edildiyse bu parametrenin değeri null olurken aksi taktirde seçilen resim dosyasının konumu bu string’de depolanır.

title: Kullanıcının karşısına gelen resim seçme diyaloğunun başlığında yazan yazıyı belirler. Bu parametrenin iOS’ta bir etkisi yoktur.

mime: Galerideki resimleri filtrelemeye yarar. Varsayılan olarak tüm resimler gözükürken, mime’ı örneğin “image/jpeg” yaparsanız sadece JPEG resimler görünür. Bu parametrenin iOS’ta bir etkisi yoktur çünkü iOS’ta seçilen resimler daima PNG formatında olur.

D) Galeriden Video Çekmek

  • NativeGallery.GetVideoFromGallery( MediaPickCallback callback, string title = "", string mime = "video/*" )

Bu fonksiyon, GetImageFromGallery fonksiyonuna benzer şekilde çalışır. Galeriden bir video seçilince veya işlem iptal edilince callback fonksiyonu çağrılır.

E) Çalışma Zamanı İzinleri (Runtime Permissions) Hakkında

Android 6.0 sürümü itibariyle artık önemli bir Android fonksiyonuna erişmeden önce, çalışma zamanında bu fonksiyona erişim izni istemek zorundayız. NativeGallery fonksiyonları çalışmadan önce otomatik olarak izin isterler ancak dilerseniz kendi başınıza da izinlerin mevcut durumunu sorgulayabilir veya izin isteyebilirsiniz.

  • NativeGallery.CheckPermission( PermissionType permissionType )

İzinlerin durumunu sorgular ve bir NativeGallery.Permission enum‘u döndürür. Eğer galeriye erişim iznimiz varsa bu enum’un değeri Permission.Granted olurken eğer henüz iznimiz yoksa Permission.ShouldAsk olur. Eğer kullanıcı karşısına gelen izin ekranını “Bir daha sorma” seçili bir şekilde reddederse veya kullanıcının cihazında aktif olan bir ebeveyn kontrol sistemi bu iznin verilmesini engelliyorsa, Permission.Denied döndürülür. Bu durumda kullanıcı izni cihazın ayarlar menüsünden elle vermek zorundadır. Böyle bir durumla baş başa kalırsanız, kullanıcıya ayarlar menüsünden izin vermesini söyleyen bir uyarı penceresi göstermenizi öneririm. permissionType‘ın değeri, GetImage ve GetVideo fonksiyonları için NativeGallery.PermissionType.Read, SaveImage ve SaveVideo fonksiyonları için ise NativeGallery.PermissionType.Write olmalıdır.

  • NativeGallery.RequestPermission( PermissionType permissionType )

Galeriye erişim izni ister ve sonucu bir NativeGallery.Permission enum’unda döndürür. Resim kaydetmeye/çekmeye yarayan NativeGallery fonksiyonları bu fonksiyonu otomatik olarak çağırıp sonucu döndürürler.

F) Seçilen Resim Dosyasını Texture’a Çevirmek

  • NativeGallery.LoadImageAtPath( string imagePath, int maxSize = -1, bool markTextureNonReadable = true, bool generateMipmaps = true, bool linearColorSpace = false )

Bu fonksiyon vasıtasıyla bir resim dosyasını hızlıca bir Texture2D objesine çevirebilirsiniz.

imagePath: Texture2D olmasını istediğiniz resim dosyasının konumunu buraya girmelisiniz.

maxSize: Eğer resmin genişliği veya yüksekliği bu değerden büyük olursa, resmin bu boyuta küçültülmüş bir versiyonu döndürülür. Varsayılan olarak bir büyüklük limiti yoktur ancak resim ne kadar büyük olursa hafızada o kadar çok yer kaplayacağı için bu parametreye 512, 1024 vs. gibi işinizi görmeye yetecek bir değer vermeniz şiddetle önerilir.

markTextureNonReadable: Texture2D objesinin RAM’deki kopyasını silerek hafızayı rahatlatır. Bunun dezavantajı, artık resmin piksellerine elle erişemezsiniz; yani eğer GetPixel veya SetPixel fonksiyonlarını kullanıyorsanız bu parametreyi false yapın.

generateMipmaps: Texture’un mipmap’lerinin olup olmayacağını belirler.

linearColorSpace: Texture’un linear renk uzayını mı yoksa gamma renk uzayını mı (varsayılan) kullanacağını belirler.

Örnek Kod

Aşağıdaki örnek kodun 3 işlevi bulunmaktadır:

  • ekranın soluna tıklarsanız bir screenshot alınır ve bu screenshot galeriye kaydedilir
  • ekranın ortasına tıklarsanız galeriden bir resim seçmeniz istenir ve seçilen resim geçici bir küp objesine texture olarak verilir
  • ekranın sağına tıklarsanız galeriden bir video seçmeniz istenir ve seçilen video oynatılır
void Update()
{
	if( Input.GetMouseButtonDown( 0 ) )
	{
		if( Input.mousePosition.x < Screen.width / 3 )
		{
			// Screenshot al ve galeriye kaydet
			StartCoroutine( ScreenshotAlVeKaydet() );
		}
		else
		{
			// Eğer halihazırda bir resim/video seçme diyaloğu aktifse,
			// o diyalog kapatılana kadar bir şey yapma
			if( NativeGallery.IsMediaPickerBusy() )
				return;
 
			if( Input.mousePosition.x < Screen.width * 2 / 3 )
			{
				// Galeriden bir PNG resim çek
				// Eğer resmin genişliği veya yüksekliği 512 pikselden büyükse, resmi ufalt
				GaleridenResimCek( 512 );
			}
			else
			{
				// Galeriden bir video çek
				GaleridenVideoCek();
			}
		}
	}
}
 
private IEnumerator ScreenshotAlVeKaydet()
{
	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();
 
	// Screenshot'ı galeriye kaydet
	Debug.Log( "İzin durumu: " + NativeGallery.SaveImageToGallery( ss, "Örnek albüm", "Resim.png" ) );
 
	// Artık screenshot'a ihtiyacımız kalmadı
	Destroy( ss );
}
 
private void GaleridenResimCek( int maksimumBuyukluk )
{
	NativeGallery.Permission izin = NativeGallery.GetImageFromGallery( ( konum ) =>
	{
		Debug.Log( "Seçilen resmin konumu: " + konum );
		if( konum != null )
		{
			// Seçilen resmi bir Texture2D'ye çevir
			Texture2D texture = NativeGallery.LoadImageAtPath( konum, maksimumBuyukluk );
			if( texture == null )
			{
				Debug.Log( konum + " konumundaki resimden bir texture oluşturulamadı." );
				return;
			}
 
			// Texture'u geçici bir küp objesine ver
			GameObject kup = GameObject.CreatePrimitive( PrimitiveType.Cube );
			kup.transform.position = Camera.main.transform.position + Camera.main.transform.forward * 5f;
			kup.transform.forward = -Camera.main.transform.forward;
			kup.transform.localScale = new Vector3( 1f, texture.height / (float) texture.width, 1f );
 
			Material material = kup.GetComponent<Renderer>().material;
			if( !material.shader.isSupported ) // eğer Standard shader desteklenmiyorsa Diffuse shader'ı kullan
				material.shader = Shader.Find( "Legacy Shaders/Diffuse" );
 
			material.mainTexture = texture;
 
			// 5 saniye sonra küp objesini yok et
			Destroy( kup, 5f );
 
			// Küp objesi ile birlikte Texture2D objesini de yok et
			// Eğer prosedürel bir objeyi (Texture2D) işiniz bitince yok etmezseniz,
			// mevcut scene'i değiştirene kadar obje hafızada kalmaya devam eder
			Destroy( texture, 5f );
		}
	}, "Bir resim seçin", "image/png" );
 
	Debug.Log( "İzin durumu: " + izin );
}
 
private void GaleridenVideoCek()
{
	NativeGallery.Permission izin = NativeGallery.GetVideoFromGallery( ( konum ) =>
	{
		Debug.Log( "Seçilen videonun konumu: " + konum );
		if( konum != null )
		{
			// Seçilen videoyu oynat
			Handheld.PlayFullScreenMovie( "file://" + konum );
		}
	}, "Bir video seçin" );
 
	Debug.Log( "İzin durumu: " + izin );
}

Böylece bu dersin sonuna geldik. Sonraki derslerde görüşmek üzere!

yorum
  1. Mahmut Can dedi ki:

    Yasir bey merhaba, Native Gallery unity editor de kusursuz çalışmakta ama biz uygulamamızı apk olarak çıktığımızda ve bir telefonda test ettiğimizde resim ekleme butonuna basınca galeriden resim seçince seçtiğimiz resim uygulamaya aktarılmıyor sebebi sizce ne olabilir?

    • yasirkula dedi ki:

      Logcat kullanarak aldığınız hata mesajlarına bakmanız lazım: https://yasirkula.com/2015/10/13/unity-android-oyunlarinizi-debug-etmek/

      • Mahmut Can dedi ki:

        Anladım Yasir bey, hemen denedik ve sonuçta böyle bir hata ile karşılaştık [Error wpa_supplicant IAPP SNAP_HDR Mismatch] bu sizce ne anlama gelmekte?

      • yasirkula dedi ki:

        Daha önce görmediğim bir hata, benim plugin’imle bağlantılı olduğundan emin değilim. Galeriden resim seçtiğiniz andan itibaren birkaç saniye içinde gelen loglara bakın, daha önceki logları göz ardı edin.

      • Mahmut Can dedi ki:

        Resim eklemek için bastığımız butonun Image ne resmi ekletiyoruz ve butonun boyutuda bir dikdörtgen şeklinde acaba ondan dolayı eklememezlik yapıyo olabilir mi? Ya da belki kullanıcının android de bulunan resim path’ine erişemiyo da olabilir bilemedik açıkçası 😦 Teşekkürler bu arada yardımınız için.

      • yasirkula dedi ki:

        Örnek kod çalışıyor mu?

      • Mahmut Can dedi ki:

        Aynen çalışıyor, Unity Editorde çok iyi çalışıyo, resimde geliyo. Andorid cihazda ise test ederken galeriye bağlanıyo ancak resim seçtikten sonra resim gelmiyo. Yani unity editorde çalışıp da android bir cihaz da çalışmaması ilginç değil mi?

      • Mahmut Can dedi ki:

        KOD BU ŞEKİLDE:

        public void pickImage()
        {
        int maxSize = 100000;
        string path_1 = “Assets/profilePhoto.png”;
        NativeGallery.Permission permission = NativeGallery.GetImageFromGallery((path) =>
        {

        Debug.Log(“Image path: ” + path);

        if (path != null)
        {
        string expath = path.ToLower();
        char[] charpath = expath.ToCharArray();

        for (int i = 0; i < charpath.Length; i++) // Blob için pathin içindeki türkçe harfler
        kaldırılmakta
        {
        if (charpath[i] == 'ı')
        {
        charpath[i] = 'i';
        }
        else if (charpath[i] == 'ö')
        {
        charpath[i] = 'o';
        }
        else if (charpath[i] == 'ü')
        {
        charpath[i] = 'u';
        }
        else if (charpath[i] == 'ğ')
        {
        charpath[i] = 'g';
        }
        else if (charpath[i] == 'ş')
        {
        charpath[i] = 's';
        }
        else if (charpath[i] == 'ç')
        {
        charpath[i] = 'c';
        }
        else if (char.IsWhiteSpace(charpath[i]))
        {
        charpath[i] = 'x';
        }
        }

        string realpath = new string(charpath); // değiştirilen path adı
        Debug.Log("Değiştirilen Path: " + realpath);

        Texture2D texture = NativeGallery.LoadImageAtPath(path, maxSize, false);
        Texture2D tex = new Texture2D(texture.width, texture.height, TextureFormat.ARGB32, false);
        tex = texture;
        byte[] bytes = tex.EncodeToPNG();
        File.WriteAllBytes(path_1, bytes);
        // FindObjectOfType().label = GetComponent();
        FindObjectOfType().PutImage(bytes, realpath);
        UpdateAvatarUrlMethod(imageblobURL);

        Debug.Log(imageblobURL); //Resmin blob url’si imageblobURL string de saklı
        if (texture == null)
        {
        Debug.Log(“Couldn’t load texture from ” + path);
        return;
        }

        Sprite sprite = Sprite.Create(texture, new Rect(0.0f, 0.0f, texture.width, texture.height), new Vector2());
        AddImageButton.GetComponent().image.sprite = sprite;
        AddImageButton.GetComponent().image.color = Color.white;
        AddImageButton.GetComponentInChildren().text = “”;

        }
        }, “Select a JPG image”, “image/jpg”);
        }

      • yasirkula dedi ki:

        Build alınan oyunda asset’leri düzenleyemezsiniz, yani File.WriteAllBytes(path_1, bytes); satırı çalışmaz. Logcat’te bu hata eminim gözükmüştür, iki defa logcat’e bakmanızı söylemiştim oysa.

      • Mahmut Can dedi ki:

        Aynen, çok saolun onu kaldırınca sorun da kalktı.

      • Mahmut Can dedi ki:

        Yasir bey kusura bakmayın rahatsız ediyorum bi sorun daha çıktı da şimdi bizim test ettiğimiz android 5.1 sürümlü android cihazda sorunsuz çalıştırdı ancak android sürümü 10 olan cihazda gene resim gelmedi. Bu neyden olabilir?

      • yasirkula dedi ki:

        Maalesef bilmiyorum. Logcat’te bir hata var mı bakmanız lazım.

  2. Tayfun dedi ki:

    Hocam çok güzel bir çalışma olmuş. Böyle açıklayıcı kaynaklar bulmak her zaman kolay olmuyor. Elinize sağlık. Galeriden seçtiğim fotoğrafı kısaca default olan fotoğraf ile değiştirmek istiyorum. Ancak fotoğrafı galeriden aldıktan sonrasını yapamadım. Yukarıda puzzle yapan arkadaş da tıpkı benim gibi galeriden aldığı fotoğrafı display etmek istemiş ve siz bir link bırakmışsınız ancak link kapatılmış. Yardımcı olabilirseniz çok mutlu olurum. İyi çalışmalar.

    • yasirkula dedi ki:

      Orada linkini attığım plugin bu: https://github.com/yasirkula/UnityTextureOps/releases. Bununla işiniz olduğunu sanmıyorum. Siz galeriden aldığınız resmi Application.persistentDataPath’e “DefaultImage.png” ismiyle kaydetmeli (File.Copy ve Path.Combine) ve oyun tekrar açıldığında bu dosya var ise (File.Exists) direkt o dosyayı default resim olarak yüklemelisiniz (NativeGallery.LoadImageAtPath).

  3. Ömer dedi ki:

    Merhabalar bu güzel eklenti için çok teşekkür ederiz. Galeriden çekmiş olduğum resmin sahne değiştirince kaybolmaması için nasıl bir yol izleyebilirim ? Kullanıcıya sadece bir defa resim seçtirip onu profil fotoğrafı yapması ve bu fotoğrafın sonuna kadar kalmasını istiyorum.

    • yasirkula dedi ki:

      Önce çekilen resmi File.Copy ile Application.persistentDataPath’e “profile.png” adıyla kaydetmeli, ardından bu konumda bu dosya varsa (File.Exists) her oyunun başında onu oradan yüklemelisiniz. Resmin sahneler arası kaybolmaması için onu bir static değişkende tutabilirsiniz.

      • Ömer dedi ki:

        İlgilendiğiniz için çok teşekkür ederim, biraz araştırma yaptım nasıl yapabilirim bunu diye fakat tam olarak beceremedim sanırım 🙂 şöyle birşey denedim:
        static void CopyImage(){
        File.Copy(“Application.persistentDataPath”,”profile.png”);
        if (!File.Exists (Application.persistentDataPath + “/profile.png”));
        }

      • yasirkula dedi ki:

        İhtiyacınız olan bilgiler:

        – string profilResmiKonum = Path.Combine(Application.persistentDataPath, “profile.png”); // Resmin depolanacağı konum
        – bool resimDosyasiMevcut = File.Exists(profilResimKonum); // Resim var mı yok mu
        – File.Copy(galeridenSecilenResminKonumu, profilResmiKonum); // Resmi kopyalamak

  4. efsane dedi ki:

    event trigger de update selectedi sadece basılı tuttuğum sürece kullanmasını istiyorum android de düğmeye basınca veya baslılı tutunca hareket etsin düğmeyi bıraktığımda dursun olduğu yerde bunu nasıl yapabilirim

  5. Enes dedi ki:

    Hocam Merhabalar,
    Video kaydetme kısmı çok güzel fakat mobilde butona basılı tutup videoyu nasıl byte array içinde tutabilirim. Eğer bunu yapabilirsem sizin yazdığınız methoda direk verebilirim videoyu galeriye kaydetme kısmında.

    • yasirkula dedi ki:

      Butona basılı tutunca ekran kaydı mı yapacaksınız? Bunun için ücretsiz bildiğim tek asset Everyplay. Onun haricinde Asset Store’daki ücretli plugin’lere bakabilirsiniz.

      • Enes dedi ki:

        Evet hocam. Basılı tutma fonksiyonunu nasıl halledebilirim onu soracaktım.

      • Enes dedi ki:

        Asseti indirdim de start recording gibi bir method göremedim sanırım save etmek için bir asset bu everyplay. Butona bastığımda kayıt etmeye başlayacak methodu hangisi acaba benimle paylaşırsanız çok memnun olurum.

      • Enes dedi ki:

        Hocam şimdi yaptım video ekranı açılıyor fakat ben AR uygulaması üzerinde çalışıyorum telefonun kamerasını değilde halihazırda açık ola AR kamerası üzernde video kaydı yapıcaktım. Onu nasıl kullanabilirim. Durum acil olmasa sizi rahatsız etmezdim hocam bu şekilde . Teşekkür ederim

      • yasirkula dedi ki:

        Everyplay ile AR ekran kaydı alınıyor olması lazım. İhtiyacınız olan tüm fonksiyonlar şurada: https://github.com/Everyplay/everyplay-unity-sdk/blob/master/USAGE.md. Bir butona basınca ve basmayı bitirince ayrı ayrı bildirimler almak için, Event Trigger component’i kullanıp Pointer Down ve Pointer Up event’lerine kaydolabilirsiniz.

      • Enes dedi ki:

        Hocam Gradle problemi almaya başladım unity de platform olarak androidi seçtikten sonra. Önerdiğiniz bir çözüm yöntemi varmıdır acaba ?

      • yasirkula dedi ki:

        Aldığınız hatayı Google’da aratmanızı öneririm. Çoğu hatanın çözümü Unity forumlarında veya başka yerlerde yazıyor.

  6. Can dedi ki:

    Hocam merhaba ben bu plugin ile beraber imagecropper plugininizide kullanıyorum, şimdi galeriden resim çekip imagecropperda crop ediyorum androidde veya ios’te benim crop ettiğim fotoğrafı telefona kaydedip kaydettiğim yerin konumunu almam lazım firebase storage’e yüklemek için.

    NativeGallery.SaveImageToGallery(croppedImage, “Album1”, “Resim”);

    Debug.Log(“benim save yerim: ” + Application.persistentDataPath);

    bu şekilde kaydediyorum ancak kaydedilen yerin tam adresini alamıyorum, SaveImageToGallery kodunu incelediğim zaman Application.persistentDataPath kısmına yüklendiğini gösteriyor yanlış anlamadıysam ancak orada öyle bir dosya yok, şimdi sizin burda yazdığınızı okuduğumdada DCIM/Album1/Resim.png şeklinde kaydettiğini görüyorum ancak bana string şeklinde full konumu vermesi gerek bunu nasıl alabilirim?

    Teşekkürler.

    • yasirkula dedi ki:

      Bu path’i almak iOS’ta mümkün değil, Android’de ise %100 çalışan bir yöntem yok. Texture’u önce Application.persistentDataPath’e kaydetmenizi (texture.EncodeToPNG ve File.WriteAllBytes ile) ardından bu konumu SaveImageToGallery fonksiyonuna ve Firebase’e vermenizi öneririm.

  7. Mahmutcan ZAMAN dedi ki:

    Merhaba hocam dediğiniz işlemleri yaptım resimi sprite a atadım. Bu resmi resources kısmına kaydetmek istiyorum.(Oyun dosyalarında kayıtlı kalmasını istiyorum sürekli kullanabilmek için) nasıl project kısmına kayıt alabilirim aldığımız resimi?

    • yasirkula dedi ki:

      Bunu sadece editörde yapmak istiyorsanız mümkün ama anladığım kadarıyla build aldığınız oyunda yapmak istiyorsunuz, oyunu build aldıktan sonra Resources klasörünü değiştiremezsiniz. Dosyayı sadece Application.persistentDataPath veya Application.temporaryCachePath klasörlerine kaydedebilirsiniz.

  8. Ahmet Gül dedi ki:

    Hocam çok rahatsız ettim ama gelen fotoğrafı kodlarla otomatik 16 parçaya slice etme şansım var mı

  9. Mahmutcan zaman dedi ki:

    Hocam texture olarak resmi galeriden aldığımız da unity içerisinde bir image içine tam oturacak şekilde nasıl tanımlayabilirim.Yada gelen resmi hiyerarşiye nasıl kaydedebilirim.

    • yasirkula dedi ki:

      Resmi Hierarchy’e kaydetmeyi anlayamadım ama resmi Image’ın sprite’ına atayabilmek için önce LoadImageAtPath ile Texture oluşturmalı, sonra Sprite.Create ile o Texture’dan Sprite oluşturmalısınız: imageObj.sprite = Sprite.Create(texture, new Rect(0f, 0f, texture.width, texture.height), new Vector2(0.5f, 0.5f), 100.0f);

      • Mahmutcan zaman dedi ki:

        Hocam kusura bakmayın yeni başladım. Rahatsız ediyorum sürekli. The name ‘sprite’ does not exist in the current context diye bir hata aldım, dediğinizi yaparak. Bu konuda ki gördüğüm tek kaynak da sizsiniz bu konuda elinize sağlık.

      • yasirkula dedi ki:

        public Image imageObj; değişkeni oluşturup Inspector’dan değer vermeniz lazım.

  10. Ahmet Gül dedi ki:

    Hocam galeriden aldığım fotoğrafı kırpmak ve çözünürlüğünü değiştirmek istiyorum. Örneğin 1920*1080 bir fotoğrafı seçtikten sonra kare şekilde kırpıp sonradan çözünürlüğü 1000*1000 şeklinde sabit ayarlamak istiyorum. Mümkün müdür ?

    • yasirkula dedi ki:

      Resmi oyuncu elle istediği yerden mi kırpacak yoksa kod ile resmin orta kısmı otomatik mi kırpılacak?

      • Ahmet Gül dedi ki:

        Oyuncu 1000*1000 piksel
        bir kare alanın içinde sürükleyerek kırpacak. En son kendi istediği yeri seçmiş olacak ama çözünürlük 1000*1000 olacak

      • yasirkula dedi ki:

        Şu plugin ile kırpma işlemini yapabilirsiniz: https://github.com/yasirkula/UnityImageCropper. Şu örnek koddaki croppedImageResizePolicy içerisinde width ve height değerlerini 1000 yaparsanız, oyuncu ne kadar büyük veya ne kadar küçük bir alan seçmiş olursa olsun en son Texture 1000×1000 çözünürlüğünde olur. selectionMinAspectRatio ve selectionMaxAspectRatio’ya değer olarak 1f verirseniz, oyuncunun seçimi daima kare şeklinde olur.

  11. Ali dedi ki:

    Merhaba
    ResimSec.cs(56,49): error CS1501: No overload for method ‘GetImageFromGallery’ takes 4 arguments

    eklentiyi projeye aktadım fakat bu şekilde bir hata alıyorum. Nasıl çözülebilir ?

    Unity 2019.3.15f1

    • Ali dedi ki:

      Hocam githubda eklentiyi yeniledim bu sefer bu şekilde bir konsol hatası alıyorum..

      Copying assembly from ‘Temp/com.unity.multiplayer-hlapi.Runtime.dll’ to ‘Library/ScriptAssemblies/com.unity.multiplayer-hlapi.Runtime.dll’ failed

    • yasirkula dedi ki:

      O fonksiyonun dokümantasyonu eski kalmış, şimdi güncelledim. Aldığınız diğer hata NativeGallery ile alakalı değil; eğer konsolu Clear yapınca hata gidiyorsa, hatayı yoksayabilirsiniz. Aksi taktirde bir şekilde Unity’nin HLAPI multiplayer package’ı sıkıntı çıkarıyordur. Multiplayer oyun yapmıyorsanız Package Manager’dan HLAPI/Multiplayer’ı çıkarabilirsiniz.

  12. Furkan Çalışkan dedi ki:

    Hocam merhabalar,
    Kullanıcı, resim seçme menüsüne girdiğinde ana sunucuyla olan bağlantısı direk kesiliyor.
    Uygulamayı arkaplana alınca da direkt timeout hatası veriyor.
    Bunu nasıl engelleyebilirim?

    • Furkan Çalışkan dedi ki:

      Sorunu çözdüm. Aynı sorunu yaşayan arkadaşlar için yazıyorum. Telefonunuz güç tasarruf modunda ise yaptığınız uygulamayı arkaplana alır almaz görevi sonlandırıyor. Bunun için telefon ayarlarından güç tasarrufunu kapatabilir veya uygulama profiline girip yaptığınız uygulamaya özel güç tasarrufunu kapatabilirsiniz. Kod ile izin alınarak yapılabilse güzel olurdu, bilen arkadaşlar varsa yazabilirlerse memnun olurum.

  13. Saffet dedi ki:

    merhabalar. emeğiniz için çok teşekkürler..
    acemi olduğum için tam çözemedim. bu dersin finalinde bu linkteki uygulamaya benzer bir sonuç
    alabilir miyim.. yani istediğim sadede uygulamayı kullanan bilgisayarından yada android’ inden
    materyal üzerine dokusunu kendi atabilsin
    Link

  14. Faruk dedi ki:

    hocam firebase ile ilgili bir eğitim yazarmısınız

    • yasirkula dedi ki:

      Şu anda Firebase veya Google Play Services gibi servisler için ders planlamıyorum. Halihazırda yazmayı planladığım başka dersler var ama onlara bile zaman bulamıyorum şu anda.

  15. Merhabalar,
    Öncelikle paylaşımınız için çok teşekkür ederim ancak ufak bir sorum olacak:
    Kullanıcının seçtiği resmi firebase stroge’ye upload etmek istiyorum. Teoride her şey düzgün ancak android cihazımda deneyince upload işlemi işe yaramıyor.
    Android’de /storage/emulated/0/… şekilde bir konum alıyorum, konum alma işlemi çalışıyor ancak firebaseye bu konumdaki dosyayı yüklemesini söyleyince işe yaramıyor. Aynı şeyi bilgisayarda C:/user/Downloads/… tarzı bir konum ile deniyorum ve bilgisayarda sıkıntısız çalışıyor. Yine de Android’de hatayı ve sebebini çözemedim.
    Bu konuda yardımcı olabilir misiniz? Şimdiden teşekkürler

  16. Furkan Çalışkan dedi ki:

    Selamlar hocam, kullanıcıdan resim yükletip profil resmi olarak veritabanına kaydetmek istiyorum. Fakat yazdığınız konum değişkeninden ve callback fonksiyonundan pek bir şey anlayamadım.

    public string deneme;

    NativeGallery.GetImageFromGallery(deneme, “Profil Resmi”, “image/*”, 512);

    deneme kısmı hata veriyor.

    Kullanıcının, eklediğim butona bastığında galerisinin açılmasını ve oradan resim seçmesini nasıl yapabilirim?

    • yasirkula dedi ki:

      Örnek koddaki GaleridenResimCek fonksiyonunu inceleyebilirsiniz. Oradaki “// Texture’u geçici bir küp objesine ver” comment’inden sonrasını, resmi veritabanına kaydetme kodunuzla değiştirebilirsiniz.

      • Furkan Çalışkan dedi ki:

        GaleridenResimCek fonksiyonundaki konum değişkeninin türü nedir?

      • Furkan Çalışkan dedi ki:

        Yazdığınız kodu kopyala yapıştır yapınca düzeldi hocam. Sanırım ileri düzey bir kod olduğundan anlamakta zorlandım 🙂 Teşekkür ederim.

    • nur dedi ki:

      İyi günler Firebase resim yükleme konusunda bir kaynak bulamadığım için size sormak istedim acaba Firebase ekleme işlemini nasıl gerçekleştirdiniz ?

  17. enes beser dedi ki:

    çok saolun hocam peki 10 tane resim seçtirmek istesem max galeriden bunları 2d imageler içerisine atmak istiyorum nasıl olur texture ı image e dönüştürmeyi birtaz araştırdım kafam karıştı yardımcı olursanız sevinirim 2 konuda da

    • enes beser dedi ki:

      ios ve android için

    • yasirkula dedi ki:

      Texture oluşturmak için “Seçilen Resim Dosyasını Texture’a Çevirmek” kısmındaki fonksiyonu kullanabilirsiniz. Birden çok resim seçtirmek için ekranda bir + tuşunuz olabilir ve kullanıcı buna her bastığında yeniden NativeGallery.GetImageFromGallery fonksiyonunu çağırırsınız.

  18. Erol ŞIVKIN dedi ki:

    Çok teşekkürler hocam sağolun. Keşke UDEMY’de kapsamlı bir eğitim hazırlasanız.

  19. Erol Şıvkın dedi ki:

    Hocam çok yararlı bir ders olmuş. Teşekkürler. Ben basit bir puzzle yaptım da android için. Galeriden resim seçtirdim sizin metodunuzla. Seçtiğim resmi sahneye alabilir miyim? Sahnede hazır bir resim var ve ben sprite editor ile 6 ya böldüm. Kodlar şöyle;

    // Use this for initialization

    [SerializeField]
    private Transform[] pictures;

    [SerializeField]
    private GameObject winText;

    public static bool youWin;

    private void Start()
    {

    winText.SetActive(false);
    youWin = false;
    }

    private void Update()
    {

    if (pictures[0].rotation.z == 0 &&
    pictures[1].rotation.z == 0 &&
    pictures[2].rotation.z == 0 &&
    pictures[3].rotation.z == 0 &&
    pictures[4].rotation.z == 0 &&
    pictures[5].rotation.z == 0)

    {
    winText.SetActive(true);
    youWin = true;
    }
    }

    public void Kapat()
    {

    Application.Quit();

    }
    public void GaleridenResimCek()
    {
    // ÖRNEK KOD
    }

    İyi çalışmalar.

    • yasirkula dedi ki:

      Resmi kaç satır kaç sütun olacak şekilde böldünüz (örneğin 2×3)? Ayrıca, rotation.z yerine eulerAngles.z yapmanız gerekebilir.

      • Erol ŞIVKIN dedi ki:

        Hocam 6 hücre yani 2 satır 3 sütun olacak şekilde.

      • yasirkula dedi ki:

        Öncelikle projenize şu plugin’i import edin: https://github.com/yasirkula/UnityTextureOps/releases

        Ardından NativeGallery’den elde ettiğiniz resmi bir Texture’a çevirip bu Texture’u şu fonksiyon vasıtasıyla 6 parçaya bölebilirsiniz:

        public Sprite[] ResmiParcalaraBol( Texture2D resim )
        {
        	Texture2D[] parcalar = TextureOps.Slice( resim, resim.width / 3, resim.height / 2, TextureFormat.RGB24 ); // 2 satır 3 sütun
        	
        	Sprite[] sonuc = new Texture2D[parcalar.Length];
        	for( int i = 0; i &lt; parcalar.Length; i++ )
        		sonuc[i] = Sprite.Create( parcalar[i], new Rect( 0.0f, 0.0f, parcalar[i].width, parcalar[i].height ), new Vector2( 0.5f, 0.5f ), 100.0f );
        	
        	return sonuc;
        }
        

Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Google fotoğrafı

Google hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.