戯言日記

ホロレンジャーの戦いの記録

【ネタ枠】HoloLensでキャプチャすると何かが映り込む

完全にネタ枠の記事です
(※ HoloToolKitを使用しています。別になくてもできる)

HoloLensでAirTapするとキャプチャができるだけのスクリプトです。(保存機能は特になし)

ただし何かが写り込む

f:id:haikage1755:20170730163946p:plain

using UnityEngine;
using System.Linq;
using UnityEngine.VR.WSA.WebCam;
using HoloToolkit.Unity.InputModule;

public class CustomPhotoCapture : MonoBehaviour, IInputClickHandler
{
    public Texture2D tex2; //Texture u wanna add
    public Vector2 texPosition = Vector2.zero;

    PhotoCapture photoCaptureObject = null;
    Texture2D targetTexture = null;    // Use this for initialization
    CameraParameters cameraParameters;

    void Start()
    {
        InputManager.Instance.AddGlobalListener(gameObject);
        OnCreatePhotoObj();
    }

    public void OnTakePhoto()
    {
        if(photoCaptureObject == null)
        {
            OnCreatePhotoObj();
            return;
        }

        photoCaptureObject.StartPhotoModeAsync(cameraParameters, delegate (PhotoCapture.PhotoCaptureResult result) {
            photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
        });
    }

    void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
    {
        // Copy the raw image data into our target texture
        photoCaptureFrame.UploadImageDataToTexture(targetTexture);        // Create a gameobject that we can apply our texture to
        targetTexture = MergeTexture(targetTexture, tex2);
        GameObject quad = GameObject.CreatePrimitive(PrimitiveType.Quad);
        quad.transform.transform.position = Camera.main.transform.position + Camera.main.transform.forward * 5f;
        quad.transform.LookAt(Camera.main.transform);
        quad.transform.eulerAngles += new Vector3(0, 180, 0);
        quad.transform.localScale = new Vector3(1.98f, 1.2f, 1);
        Renderer quadRenderer = quad.GetComponent<Renderer>() as Renderer;
        quadRenderer.material = new Material(Shader.Find("Unlit/Texture")); quad.transform.parent = this.transform;
        quadRenderer.material.SetTexture("_MainTex", targetTexture);        // Deactivate our camera

        photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);   
    }

    void OnCreatePhotoObj()
    {
        Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
        targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);        // Create a PhotoCapture object
        PhotoCapture.CreateAsync(false, delegate (PhotoCapture captureObject) {
            photoCaptureObject = captureObject;
            cameraParameters = new CameraParameters();
            cameraParameters.hologramOpacity = 0.0f;
            cameraParameters.cameraResolutionWidth = cameraResolution.width;
            cameraParameters.cameraResolutionHeight = cameraResolution.height;
            cameraParameters.pixelFormat = CapturePixelFormat.BGRA32;                // Activate the camera
        });
    }

    void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
    {
        // Shutdown our photo capture resource
        photoCaptureObject.Dispose();
        photoCaptureObject = null;
    }

    public Texture2D MergeTexture(Texture2D main, Texture2D addedTex) 
    {
        var startX = (int)texPosition.x;
        var startY = (int)texPosition.y;

        for (var x = startX; x < main.width; x++)
        {
            for(var y = startY; y < main.height; y++)
            {
                Color mainColor = main.GetPixel(x,y);
                Color addedColor = addedTex.GetPixel(x - startX, y - startY);

                Color final_color = Color.Lerp(mainColor, addedColor, addedColor.a / 1.0f);

                main.SetPixel(x,y,final_color);
            }            
        }

        main.Apply();
        return main;
    }

    public void OnInputClicked(InputClickedEventData eventData)
    {
        if (!GazeManager.Instance.HitObject)
        {
            OnTakePhoto();
        }
    }
}

f:id:haikage1755:20170730164052p:plain

てきとーなオブジェクトにアタッチして、tex2に追加したい画像を入れてください
注意点としては追加する画像のRead/Writeにチェックを入れる、WrapModeをclampにするのを忘れないでください

サンプル用のフリー素材貼っておきます

f:id:haikage1755:20170730164315p:plain

[研究者になりたかった青二才の戯言日記]は、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、Amazonアソシエイト・プログラムの参加者です。」