U3D之WebCamTexture实现前后相机的拍照功能

1、简述和效果图

有拍照取景功能、有前后相机切换功能、取景框、有预览小框、只是个demo没有做照片存储功能,可以自行扩展。UI使用的是官方的UGUI.

这里写图片描述

2、话不多说上直接下代码

//[lzh]
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;

public class test : MonoBehaviour
{    
    private WebCamTexture mWebcamTexBack;
    private WebCamTexture mWebcamTexFront;
    int back = -1, front = -1, current = -1;

    public RawImage rawImg_CamTexture;
    public Button btn_Photo;
    public Button btn_Change;
    public Image img_Preview;
    public Text txtInfos;
    public Text txtInfos2;

    // Use this for initialization
    void Start ()
    {
        btn_Photo.onClick.AddListener(() => { OnBtn_Photo(); });
        btn_Change.onClick.AddListener(() => { OnBtn_Change(); });
        StartCoroutine(InitAndOpenCamera());
        PrintInfo();
    }

    void Update()
    {
        if(Time.frameCount%10==0)
        {
            PrintInfo();
        }
    }


    IEnumerator InitAndOpenCamera()
    {
        yield return StartCoroutine(ApplyCamera());
        OpenBackCam();
    }

    /// <summary>
    /// 申请相机
    /// </summary>
    /// <returns></returns>
    IEnumerator ApplyCamera()
    {
        if (!Application.HasUserAuthorization(UserAuthorization.WebCam))
        {
            yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);//授权
        }
        if (Application.HasUserAuthorization(UserAuthorization.WebCam))
        {
            int length = WebCamTexture.devices.Length;
            if (length <= 0)
            {
                Debug.Log("你的设备没有摄像头!!!");
                enabled = false;
                yield break;
            }
            else if(length == 1)
            {
                mWebcamTexBack = new WebCamTexture(WebCamTexture.devices[0].name, (int)(Screen.width), (int)(Screen.height), 12);
            }
            else
            {                
                for(int i= 0; i < length; i++)
                {
                    if(WebCamTexture.devices[i].isFrontFacing)
                    {
                        front = i;
                    }
                    else
                    {
                        if(back==-1)
                        {
                            back = i;
                        }
                    }
                }
                if(front==-1)
                {
                    front = back + 1;
                }
            }
        }
        {
            enabled = false;
        }
    }

    void OpenBackCam()
    {
        if (back == -1)
        {
            Debug.Log("你的设备没有摄像头!!!");
            return;
        }

        current = back;
        if (mWebcamTexFront!=null && mWebcamTexFront.isPlaying)
        {
            mWebcamTexFront.Stop();
        }
        //if(mWebcamTexBack!=null)
        //{
        //    if (mWebcamTexBack.isPlaying)
        //    {
        //        return;
        //    }
        //    mWebcamTexBack.Play();
        //    return;
        //}

        mWebcamTexBack = new WebCamTexture(WebCamTexture.devices[current].name, (int)(Screen.height), (int)(Screen.width), 20);
        mWebcamTexBack.Play();
        rawImg_CamTexture.texture = mWebcamTexBack;
    }

    void OpenFrontCam()
    {
        if(front==-1)
        {
            OpenBackCam();
            return;
        }

        current = front; 
        if (mWebcamTexBack != null && mWebcamTexBack.isPlaying)
        {
            mWebcamTexBack.Stop();
        }
        //if (mWebcamTexFront != null)
        //{
        //    if (mWebcamTexFront.isPlaying)
        //    {
        //        return;
        //    }
        //    mWebcamTexFront.Play();
        //    return;
        //}

        mWebcamTexFront = new WebCamTexture(WebCamTexture.devices[front].name, (int)(Screen.height), (int)(Screen.width), 20);
        mWebcamTexFront.Play();
        rawImg_CamTexture.texture = mWebcamTexFront;
    }

    private void OnBtn_Photo()
    {
        StartCoroutine(GetTexture());
    }

    private void OnBtn_Change()
    {
        ChangeCamera();
    }

    public void ChangeCamera()
    {
        if(current==back)
        {
            OpenFrontCam();
        }
        else
        {
            OpenBackCam();
        }

        WebCamTexture _webCamTexture = GetCurrent_WebCamTexture();
        int videoRotationAngle = _webCamTexture.videoRotationAngle;
        rawImg_CamTexture.transform.rotation = Quaternion.Euler(0, 0, -videoRotationAngle);
    }

    public WebCamTexture GetCurrent_WebCamTexture()
    {
        WebCamTexture _webCamTexture;
        if (current == back) _webCamTexture = mWebcamTexBack;
        else _webCamTexture = mWebcamTexFront;
        return _webCamTexture;
    }

    public IEnumerator GetTexture()
    {
        WebCamTexture _webCamTexture = GetCurrent_WebCamTexture();
        _webCamTexture.Pause();
        yield return new WaitForEndOfFrame();

        // 旋转预览精灵
        int videoRotationAngle = _webCamTexture.videoRotationAngle;
        img_Preview.transform.parent.rotation = Quaternion.Euler(0, 0, -videoRotationAngle);

        // 确定预览图,要截取镜头的大小
        int w = _webCamTexture.width;
        w = _webCamTexture.height > w ? w : _webCamTexture.height;
        Vector2 offset = new Vector2((_webCamTexture.width - w) / 2, (_webCamTexture.height - w) / 2);

        //Texture2D mTexture = new Texture2D(_webCamTexture.width, _webCamTexture.height, TextureFormat.ARGB32, false);
        //mTexture.SetPixels32(_webCamTexture.GetPixels32());
        Texture2D mTexture = new Texture2D(w, w, TextureFormat.ARGB32, false);
        mTexture.SetPixels(_webCamTexture.GetPixels((int)offset.x,(int)offset.y, w, w));
        mTexture.Apply();        

        img_Preview.sprite = Sprite.Create(mTexture, new Rect(0, 0, w, w),Vector2.zero);
        _webCamTexture.Play();

        //byte[] bt = mtexture.EncodeToPNG();
        //string mPhotoName = DateTime.Now.ToString("yyyyMMddHHmmss") + ".png";
        //mPhotoPath = Application.persistentDataPath + "/" + mPhotoName;
        //System.IO.File.WriteAllBytes(mPhotoPath, bt);
        //Debug.LogError("照片路径  " + mPhotoPath);
        //if (callback != null) callback();
    }

    void PrintInfo()
    {
        if (txtInfos == null || !txtInfos.isActiveAndEnabled) return;

        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        sb.AppendLine("screen: w = " + Screen.width + " h = " + Screen.height);
        sb.AppendLine("backCamText: " + mWebcamTexBack.width + ", " + mWebcamTexBack.height);
        sb.AppendLine("frontCamText: " + mWebcamTexFront.width + ", " + mWebcamTexFront.height);
        sb.Append("current: " + current);
        sb.Append("  back: " + back);
        sb.AppendLine("  front: " + front);
        sb.AppendLine("back videoRotationAngle:" + mWebcamTexBack.videoRotationAngle);
        sb.AppendLine("front videoRotationAngle:" + mWebcamTexFront.videoRotationAngle);
        txtInfos.text = sb.ToString();
    }
}

3、Demo工程

点击下载

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿海-程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值