Unity で撮影したスクリーンショットを Node-RED で受け取って画像保存するメモ

Unity で撮影したスクリーンショットを Node-RED で受け取って画像保存するメモです。

Unity に Cube を準備

image

Unity に Cube を準備します。

Cube に CubeEvent.cs を割り当て

Cube に CubeEvent.cs を割り当てます。

Unity で CaptureScreenshotAsTexture を使って後加工しやすいスクリーンショットをするメモ

スクリーンショットのコード DoScreenShot に、multipart/form-data で撮影したデータとして送信するコード PostData が加わっています。

コードは以下の通りです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class CubeEvent : MonoBehaviour
{
    // キャプチャされた画像データ
    byte[] dataImage;

    void Start()
    {
        StartCoroutine(DoScreenShot());
    }

    IEnumerator DoScreenShot()
    {
        Debug.Log($"DoScreenShot");

        // レンダリング後に処理を開始
        yield return new WaitForEndOfFrame();

        // Texture2D でスクリーンショットを取得
        Texture2D textureScreenCapture = ScreenCapture.CaptureScreenshotAsTexture();

        // EncodeToJPG で JPEG に変換する。EncodeToPNG なら PNG に変換できる
        dataImage = textureScreenCapture.EncodeToJPG();

        Debug.Log($"撮影完了");
        Debug.Log($"{dataImage}");

        // textureScreenCapture を削除
        Destroy(textureScreenCapture);

        // 画像送信
        StartCoroutine(PostData());
    }

    IEnumerator PostData()
    {
        // IMultipartFormSection で multipart/form-data のデータとして送れます
        // https://docs.unity3d.com/ja/2018.4/Manual/UnityWebRequest-SendingForm.html
        // https://docs.unity3d.com/ja/2019.4/ScriptReference/Networking.IMultipartFormSection.html
        // https://docs.unity3d.com/ja/2020.3/ScriptReference/Networking.MultipartFormDataSection.html
        List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
        // 画像フォームで用意
        formData.Add(new MultipartFormFileSection("imageFile", dataImage, "01.jpg", "multipart/form-data"));

        // HTTP リクエストする(POST メソッド) UnityWebRequest を呼び出し
        // 第 2 引数で上記のフォームデータを割り当てて multipart/form-data のデータとして送ります
        UnityWebRequest request = UnityWebRequest.Post("http://localhost:1880/api/post/image", formData);

        // ダウンロード(サーバ→Unity)のハンドラを作成
        request.downloadHandler = new DownloadHandlerBuffer();

        // リクエスト開始
        yield return request.SendWebRequest();

        // 結果によって分岐
        switch (request.result)
        {
            case UnityWebRequest.Result.InProgress:
                Debug.Log("リクエスト中");
                break;

            case UnityWebRequest.Result.ProtocolError:
                Debug.Log("ProtocolError");
                Debug.Log(request.responseCode);
                Debug.Log(request.error);
                break;

            case UnityWebRequest.Result.ConnectionError:
                Debug.Log("ConnectionError");
                break;

            case UnityWebRequest.Result.Success:
                Debug.Log("リクエスト成功");

                // コンソールに表示
                Debug.Log($"responseData: {request.downloadHandler.text}");

                break;
        }


    }
}


Node-RED

このデータを受け取る Node-RED の仕組みです。

image

このようなフローをつくります。 http in ノードからhttp response ノードにつながり、http in ノードから change ノード・write file ノードでつないで受け取った画像を保存しています。

image

http in ノードのプロパティです。

image

http in ノードは multipart/form-data で画像を受け取るために「ファイルのアップロード」をチェックしておきます。 URL は /api/post/image にします。

image

change ノードのプロパティです。

image

change ノードでは http in ノードで multipart/form-data で付与された画像データを受け取っています。

このように msg.req.files[0].buffer で送られてきた 1 つめの画像を取得しています。

image

write file ノードでは取得したデータを画像ファイルとして保存しています。

image

今回はデスクトップに test.jpg で保存しています。

フロー JSON は以下の通りです。

[{"id":"f8aae4e3ce6f56d5","type":"http in","z":"2af3578e1e4de10b","name":"","url":"/api/post/image","method":"post","upload":true,"swaggerDoc":"","x":320,"y":540,"wires":[["d353b7ae8301b8d7","feca9055b60c7e47"]]},{"id":"d353b7ae8301b8d7","type":"change","z":"2af3578e1e4de10b","name":"buffer 取得","rules":[{"t":"set","p":"payload","pt":"msg","to":"req.files[0].buffer","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":550,"y":600,"wires":[["6092e9331dea1f3a"]]},{"id":"6092e9331dea1f3a","type":"file","z":"2af3578e1e4de10b","name":"test.jpg 保存","filename":"C:\\Users\\tnkse\\Desktop\\test.jpg","filenameType":"str","appendNewline":true,"createDir":false,"overwriteFile":"true","encoding":"none","x":770,"y":600,"wires":[[]]},{"id":"feca9055b60c7e47","type":"http response","z":"2af3578e1e4de10b","name":"","statusCode":"","headers":{},"x":530,"y":540,"wires":[]}]

動かしてみる

image

Unity で Play ボタンをクリックして動かしてみると、無事に送られます。

image

Node-RED にデータが届き、無事 test.jpg として保存されます。