Unity mobile phone camera and related issues

Note: 5.6 is used, so it is impossible to have a webplayer. The following are all tested on android phones~

One: Use Unity's own WebCamTexture to realize the camera function

    1: First build a simple scene

                A button is pressed to turn on the camera

                

           The camera has a preview of the switch camera button to take a picture button 

                

  2: Encoding

            (1): Under the explanation, I have read a lot of posts, they all say that you need to request authorization first, and then turn on the camera when the authorization is successful. I tried here many times, but it doesn’t have to be so troublesome. For example, you write like the following

public IEnumerator start()  
    {  
        yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);  
        if (Application.HasUserAuthorization(UserAuthorization.WebCam))  
        {  
            WebCamDevice[] devices = WebCamTexture.devices;  
            deviceName= devices[0].name;  
            tex=new WebCamTexture(deviceName,300,300,12);  
            tex.Play();  
        }  
    }  
Actually it’s not necessary, these two sentences have no effect, the second line of code is true no matter what
Application.RequestUserAuthorization(UserAuthorization.WebCam); 
Application.HasUserAuthorization(UserAuthorization.WebCam)

This is the description in the official document. If you don’t believe it, you can comment the above code tex.play(). At this time, there will be no pop-up box showing whether you want to authorize or you can comment the previous two sentences. , Will also display the authorization, the real authorization is the camera play()

    

    You can try it yourself. It is recommended to uninstall the previous installation every time you install, or change the package name

  (2): The difference between PC and mobile phone

        On the PC, it is used to display the photos taken by the camera photoImg, without any changes

        

    However, it was found to be crooked by 90 degrees when it was posted on the mobile phone.

        

When we press the "Switch" button, we will find that the picture is reversed. At this time, we need to add a rotation function where the picture is switched.

       photoImage.transform.Rotate(new Vector3(180, 0, 180));

This is very troublesome, so the photoImg used to render the camera is best to be a square, and then when the start method determines whether the current platform is on the phone, if it is, it is rotated by 90 degrees, and then do not add a rotation function when switching the camera (The code below is not added (because my photoImg is not a square), just to provide an idea)

    (3): Code (note the difference between pc and mobile phone)

        

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
//拍照
public class TakePhotos : MonoBehaviour
{
    public Button startPhotoBtn; //开始拍照
    public Button getPhotoBtn;    //拍照
    public Button changeBtn;    //切换相机
    public RawImage photoImage;    //相机画面
    public RawImage photoPreview;  //预览图

    private string photoPath;  //相机存贮位置

    private WebCamTexture webcam1, webcam2; //这里当作两个摄像机处理
    //   private bool isAndroid;
    void Start()
    {
        startPhotoBtn.onClick.AddListener(InitWebCam);
        getPhotoBtn.onClick.AddListener(GetPhoto);
        changeBtn.onClick.AddListener(ChangeCamera);
        //photoPath = Application.dataPath + "/Texture/";
        //if (!Directory.Exists(photoPath))
        //{ Directory.CreateDirectory(photoPath); }
    }

    private void InitWebCam()
    {
        WebCamDevice[] devices = WebCamTexture.devices;

        int webCamLength = devices.Length;
        if (webCamLength <= 0)
        {
            Debug.Log("没有获取摄像机设备");
            return;
        }
        else if (webCamLength == 1)
        {
            //所选相机可能不支持请求的参数指定的宽度,高度和帧速率。在这种情况下,将使用最接近的可用值
            //根据纹理图片拍摄大小
            Debug.Log("有一个摄像机设备");
            webcam1 = new WebCamTexture(WebCamTexture.devices[0].name,
                (int)photoImage.rectTransform.rect.width,
                (int)photoImage.rectTransform.rect.height, 12);
        }
        else if (webCamLength == 2)
        {
            Debug.Log("有两个摄像机设备");
            webcam1 = new WebCamTexture(WebCamTexture.devices[0].name,
           (int)photoImage.rectTransform.rect.width,
           (int)photoImage.rectTransform.rect.height, 12);
            webcam2 = new WebCamTexture(WebCamTexture.devices[1].name,
               (int)photoImage.rectTransform.rect.width,
               (int)photoImage.rectTransform.rect.height, 12);
        }
        if (webcam1 != null)  //当获取摄像机不为空
        {
            OpenWebCam1();
        }
    }

    /// <summary>
    /// 打开摄像头1
    /// </summary>
    private void OpenWebCam1()
    {
        //当webcam2不为空且在运行的时候
        if (webcam2 != null && webcam2.isPlaying)
        {
            webcam2.Stop();
        }
        webcam1.Play();
        photoImage.texture = webcam1;
    }
    /// <summary>
    /// 打开摄像头2
    /// </summary>
    private void OpenWebCam2()
    {
        if (webcam1 != null && webcam1.isPlaying)
        {
            webcam1.Stop();
        }
        webcam2.Play();
        photoImage.texture = webcam2;
    }
    /// <summary>
    /// 获取正在运行的摄像头
    /// </summary>
    /// <returns></returns>
    private WebCamTexture GetCurrentWebCam()
    {
        return webcam1.isPlaying ? webcam1 : webcam2;
    }
    /// <summary>
    /// 切换相机
    /// </summary>
    private void ChangeCamera()
    {
        //如果web2为空,即只有一个摄像头 返回
        if (webcam2 == null) return;
        //得到另一个相机
        WebCamTexture otherWebCam = GetCurrentWebCam() == webcam1 ? webcam2 : webcam1;
        if (otherWebCam == webcam1)
        {
            OpenWebCam1();
        }
        else
        {
            OpenWebCam2();
        }
        photoImage.transform.Rotate(new Vector3(180, 0, 180));
    }

    /// <summary>
    /// 拍照
    /// </summary>
    private void GetPhoto()
    {
        StartCoroutine(IEGetPhoto());
    }
    private IEnumerator IEGetPhoto()
    {
        //获取当前的摄像头
        WebCamTexture currentWebCam = GetCurrentWebCam();
        currentWebCam.Pause();
        //必须加上这一句yield return,不然没办法ReadPixels
        yield return new WaitForEndOfFrame();
        //根据photoImage   new一个texture2D
        Texture2D texture2D =
            new Texture2D((int)photoImage.rectTransform.rect.width, (int)photoImage.rectTransform.rect.height, TextureFormat.ARGB32, false);
        //读取像素
        texture2D.ReadPixels(new Rect(0, Screen.height - photoImage.rectTransform.rect.height, photoImage.rectTransform.rect.width, photoImage.rectTransform.rect.height), 0, 0, false);

        texture2D.Apply();

        yield return new WaitForEndOfFrame();
        photoPreview.texture = texture2D;  //预览图
        currentWebCam.Play();
        //IO写入
        //byte[] bs = texture2D.EncodeToPNG();
        // string name = DateTime.Now.ToString("yyyyMMdd_HHmmss")+".png";
        // File.WriteAllBytes(photoPath+name, bs);
    }

}

    The above comment is that pictures can be written to disk on the pc platform

Shooting is written on the phone to the album currently no success in accordance with the practice of online connections  possible but will not immediately appear in the album

All possible still have to write plug-ins to achieve

    

Guess you like

Origin blog.csdn.net/K20132014/article/details/79846040