Unity(유니티)

[UnityAndroid] NativeCamera API 사진 촬영하고 내부저장소에 저장하기

알통몬_ 2023. 1. 11. 15:25
반응형

Native Camera for Android & iOS | Integration | Unity Asset Store

 

 

Native Camera for Android & iOS | 기능 통합 | Unity Asset Store

Use the Native Camera for Android & iOS from yasirkula on your next project. Find this integration tool & more on the Unity Asset Store.

assetstore.unity.com

유니티에는 위처럼 Android, iOS 진영의 네이티브 카메라를 쉽게 호출하고 사진촬영하고, 영상촬영할 수 있는 무료 에셋이 존재합니다.

위 에셋을 사용해 UnityAndroid 에서 카메라를 열고, 사진을 찍고, 내부 저장소에 저장하는 코드를 알아보겠습니다.

 

순서

0. 2D 프로젝트를 생성합니다.

1. 프로젝트에 위 에셋을 추가합니다.

2. 간단하게 UI를 구성합니다.

3. NativeCameraManager.cs 스크립트 파일을 만들고, Canvas에 추가합니다.

4. NativeCameraManager.cs 스크립트를 아래와 같이 작성합니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Android;
using System;
using System.IO;

public class NativeCameraManager : MonoBehaviour
{
    public Button camOnBtn;
    public Image captureImage;
    public Texture2D captureTexture;

    int CaptureCounter = 0;

    // Start is called before the first frame update
    void Start()
    {
        camOnBtn.onClick.AddListener(NativeCameraOpen);

    }

    public void NativeCameraOpen()
    {
        if (NativeCamera.IsCameraBusy())
        {
            return;
        }
        TakePicture();

    }

    void TakePicture()
    {

        string SavePath = Application.persistentDataPath;

        NativeCamera.Permission permission = NativeCamera.TakePicture((path) =>
        {
            string galaryPath = SavePath.Substring(0, SavePath.IndexOf("Android")) + "/DCIM/원하는 폴더이름/";
            if (false == string.IsNullOrEmpty("원하는 폴더이름") && false == Directory.Exists("원하는 폴더이름"))
            {
            // 해당 디렉토리 없을 시 생성.
                Directory.CreateDirectory(galaryPath);
            }
            Debug.Log("Image path : " + galaryPath);
            if (path != null)
            {
                Texture2D texture = NativeCamera.LoadImageAtPath(path, 2048);
                if (texture == null)
                {
                    Debug.Log("Couldn't load texture from " + path);
                    return;
                }

                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)
                {
                    material.shader = Shader.Find("Legacy Shaders/Diffuse");
                }
                material.mainTexture = texture;
                captureTexture = texture;
                var rect = new Rect(0, 0, captureTexture.width, captureTexture.height);
                captureImage.sprite = Sprite.Create(captureTexture, rect, new Vector2(0.5f, 0.5f));


				// texture.GetPixels(); 사용 시 texture is not readable error 발생하여
                // GetReadableTexture(texture); 로 readable한 Texture 만들어야 함.
                Texture2D readableTexture = GetReadableTexture(texture);
                Texture2D snap = new Texture2D(readableTexture.width, readableTexture.height);
                snap.SetPixels(readableTexture.GetPixels());
                snap.Apply();

                string time = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                File.WriteAllBytes(
                    galaryPath + "원하는 폴더이름" + time + CaptureCounter.ToString() + ".png", snap.EncodeToPNG()
                    );
                ++CaptureCounter;
                Destroy(quad, 5f);
                //Destroy(texture, 5f);
            }
        }, 2048, true, NativeCamera.PreferredCamera.Front);
    }

    private Texture2D GetReadableTexture(Texture2D source)
    {

        RenderTexture renderTex = RenderTexture.GetTemporary(
            source.width,
            source.height,
            0,
            RenderTextureFormat.Default,
            RenderTextureReadWrite.Linear
        );

        Graphics.Blit(source, renderTex);
        RenderTexture previous = RenderTexture.active;
        RenderTexture.active = renderTex;
        Texture2D readableTexture = new Texture2D(source.width, source.height);
        readableTexture.ReadPixels(new Rect(0, 0, renderTex.width, renderTex.height), 0, 0);
        readableTexture.Apply();
        RenderTexture.active = previous;
        RenderTexture.ReleaseTemporary(renderTex);
        return readableTexture;
    }

}

 

 

반응형

'Unity(유니티)' 카테고리의 다른 글

유니티 게임 일시정지, 게임 재개 Time.timeScale  (0) 2021.08.11