반응형
Native Camera for Android & iOS | Integration | Unity Asset Store
유니티에는 위처럼 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 |
---|