unity调用IOS设备的相机拍照并保存到相册

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

public class OpenCamera : MonoBehaviour {
    //传入一个RawImage用来显示相机捕获到的实时画面
    public RawImage rawImage;
    //RawImage2用来显示拍到的图像
    public RawImage rawImage2;

    public Button openBtn;

    public Button closeBtn;
    //一个Int值用来为拍到的照片命名
    public int ID=0;

    //public Texture2D texture2D;
    private WebCamTexture webCamTexture;

	// Use this for initialization
	void Start () {
        StartCoroutine(CallWebCam());

        openBtn.onClick.AddListener(OpenWebCam);

        closeBtn.onClick.AddListener(closeWebCam);

	}
	




    IEnumerator CallWebCam()
    {

        yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);

        if (Application.HasUserAuthorization(UserAuthorization.WebCam))
        {
            //为相机捕获的图像设置分辨率和帧率
            webCamTexture = new WebCamTexture(2000,2000,30);

            WebCamDevice[] devices = WebCamTexture.devices;
            //这里devices[0]是后摄像头,前摄像头为[1];
            webCamTexture.deviceName = devices[0].name;


            //将相机捕获到的图像渲染到rawimage上
            rawImage.texture = webCamTexture;

        }

    }

    private void OpenWebCam()
    {

        webCamTexture.Play();
    }

    private void closeWebCam()

    {

        webCamTexture.Stop();

    }

    //将拍到的照片经过渲染后显示在rawimage2上,并转码存在本地缓存
    public void Save(){
        ID++;
        int width = webCamTexture.width;
        int height = webCamTexture.height;

        Texture2D t2d = new Texture2D(webCamTexture.width, webCamTexture.height, TextureFormat.ARGB32, true);

        //Texture2D t2d = new Texture2D(webCamTexture.width, webCamTexture.height);


        t2d.SetPixels(webCamTexture.GetPixels(0, 0, webCamTexture.width, webCamTexture.height));
        //t2d.SetPixels(webCamTexture.GetPixels(0, 0, webCamTexture.height, webCamTexture.width));
        t2d.Apply();

        t2d = rotatePic(t2d);
        t2d = verticalFlipPic(t2d);



        Debug.Log(rawImage.texture);
        rawImage2.texture = t2d;
        Debug.Log(rawImage2.texture);
        rawImage2.SetNativeSize();
        //编码
        byte[] imageTytes = t2d.EncodeToPNG();
        Debug.Log(imageTytes.ToString());
       // Sprite sprite = Sprite.Create(t2d, new Rect(0, 0, 6, 64), Vector2.zero);
        //rawImage2.texture=t2d;


       


        //string image_text = imageTytes.ToString();
    
        File.WriteAllBytes(Application.streamingAssetsPath + "/" + ID + ".png", imageTytes);
    }
    private Texture2D verticalFlipPic(Texture2D texture2d)
    {
        int width = texture2d.width;
        int height = texture2d.height;
        Texture2D newTexture2d = new Texture2D(width, height);
        int i = 0;
        while (i < height)
        {
            newTexture2d.SetPixels(0, i, width, 1, texture2d.GetPixels(0, height - i - 1, width, 1));
            //newTexture2d.SetPixels(0, i, width, 1, texture2d.GetPixels(1, height - i - 1, width, 0));
            i++;
        }
        newTexture2d.Apply();

        return newTexture2d;
    }
    private Texture2D rotatePic(Texture2D texture2d)
    {
        int width = texture2d.width;
        int height = texture2d.height;
        Texture2D newTexture2d = new Texture2D(height, width);
        for (int i = 0; i < width; i++)
        {
            for (int j = 0; j < height; j++)
            {
                newTexture2d.SetPixel(j, i, texture2d.GetPixel(i,j));
                //newTexture2d.SetPixel();
            }
        }
        // int i = 0;
        // while (i < height) {
        //     newTexture2d.SetPixels(0, i, width, 1, texture2d.GetPixels(0, height - i - 1, width, 1));
        //     i++;
        // }
        newTexture2d.Apply();

        return newTexture2d;
    }
}

这一步我们完成的是拍照并保存到我们应用的缓存中。

然后我们需要把照片从我们的应用缓存路径中拿出来保存到设备的系统相册。代码如下:

using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using System.Runtime.InteropServices;

public class SaveToPhoto : MonoBehaviour
{
    [DllImport("__Internal")]
    private static extern void _SavePhoto(string readAddr);


    public void Save_photo()
    {
        int id = gameObject.GetComponent<OpenCamera>().ID;
        //string read_addr = Application.streamingAssetsPath + "/" + "myself.png";
        string read_addr = Application.streamingAssetsPath + "/" + id + ".png";
        //从前面保存的路径中拿到保存的图片并转为byte编码
        byte[] buffers = ImageToBytes(read_addr);
        if (Application.platform == RuntimePlatform.IPhonePlayer)
        {
            
            Debug.Log(Application.streamingAssetsPath);
            string path_read = Application.streamingAssetsPath + "/" + id + ".png";
            //根据图片的byte编码将此图片存入到本地相册
            File.WriteAllBytes(path_read, buffers);
            _SavePhoto(path_read);
        }
    }
    private byte[] ImageToBytes(string imageFileName)
    {
        return File.ReadAllBytes(imageFileName);
    }
}

在这里需要注意几点:

  1. verticalFlipPic和rotatePic是把拍到的图像经过一定的旋转操作之后渲染出来,因为我在调试的时候发现图像的旋转角度不对所以写了这两个来进行调整,如果也有类似问题可以根据情况参照这个方法进行调整;
  2. Application.streamingAssetsPath是我在unity编辑器中调试时使用的路径,使用这个路径时要注意自己在工程目录下自己创建streamingAssets文件夹。在实际导出时建议使用Application.persistentDataPath路径;
  3. 导出IOS时需要在playersetting中设置相机权限,还需要在Xcode中添加相册的访问和增加照片权限;
  4. 设置分辨率和帧数时,根据各种设备的配置,分辨率会有上限,当所设分辨率超过设备上限时会自动设为设备的最高分辨率;

由于本文是直接把做的Demo的代码拷上来的,所以写的稍微有些乱,大家见谅。

欢迎各路大神的指教,欢迎各位同仁一起交流技术。

猜你喜欢

转载自blog.csdn.net/weixin_43818160/article/details/85099527