注:原題は「HoloLensにデバイスポータル経由でアップロードした画像をUnityからスクリプトでテクスチャとして使う」でした
「HoloMagnetには笑い要素がないって言われたんだ」
「まあ、真面目なアプリだよね」
「で、棒磁石にHoloLensを操作する生徒の顔を貼り付けたら、ギャラリーにもウケるんじゃないか、というんだよね」
「それは面白そうだけど、大変そうだね」
「いやー、やりきったよ」
「いいの、これ?」
「聞かないで…」
- Windows10のカメラアプリで撮影した写真をデバイスポータル経由でHoloLensに入れる
- スクリプトでカメラロールのファイルリストを取得する
- スクリプトで任意のパスのPNG/JPGファイルをテクスチャとして取り込む
- スクリプトでテクスチャを正方形にクロップする
- スクリプトでテクスチャをPlaneに貼る
「HoloMagnetには笑い要素がない」というご指摘をいただき、棒磁石に本人の顔を貼り付けるという暴挙に出ました。Windows10のカメラアプリで撮影した写真をデバイスポータル経由でHoloLensに入れます。カメラロールのファイルリストを取得し、PNG/JPGファイルをテクスチャに取り込みます。テクスチャを正方形にクロップし、Planeに貼ります。
Windows10のカメラアプリで撮影した写真をデバイスポータル経由でHoloLensに入れる
注:実はHoloLensで撮った写真はカメラロールに保存され、そのまま使えます。音量ボタン同時押しでパシャパシャ撮って即使えます。
EdgeやChromeだとJavaScriptエラーが出ますがIEだと出ません(いいのか)。
以下のページを参考にしました:
Windows10でIE11を起動する方法 (IE11が見つからない) - ぼくんちのTV 別館
スクリプトでカメラロールのファイルリストを取得する
async void SetTextureFromCameraRollToPlane(GameObject planeNorth, GameObject planeSouth) { // カメラロールフォルダは以下のように取得する StorageFolder CameraFolder = Windows.Storage.KnownFolders.CameraRoll; // GetFilesAsync()でファイルのリストを取得する var filesInFolder = await CameraFolder.GetFilesAsync(); // await後の処理ここから int count = filesInFolder.Count; // 最後から2番目の写真をN極に貼り付けるために取得する string filePathNorth = filesInFolder[count - 2].Path; // 最後の写真をS極に貼り付けるために取得する string filePathSouth = filesInFolder[count - 1].Path; // 2枚の写真をそれぞれ貼り付ける SetTextureToPlane(filePathNorth, planeNorth); SetTextureToPlane(filePathSouth, planeSouth); // await後の処理ここまで }
ちなみに上のコードは下のプリプロセッサで囲まなければなりません。
#if !UNITY_EDITOR ... #endif
プリプロセッサで囲むとVisual Studioの補完が効かないし大変だな、と思っていたらアドバイスを頂きました。
HoloLens の話ですよね? Unity でビルド後のUWPプロジェクトを開いて、そちらでコードを書けば大丈夫ですよー
— たるこす (@tarukosu) 2018年2月17日
今見たです。。。
— takabrz (@takabrz1) 2018年2月17日
①ビルドするときにUnity C# Projectにチェックして一旦吐き出してから作る、②とりあえず#if使わずに書く、③player settingでNET4.6にするとか方法あります。③は試験的に導入されてる設定ですが、async/await使えます。
なるほど…これは必須テクニックですね。
あと以下の設定も必要です:
以下のページを参考にしました:
スクリプトで任意のパスのPNG/JPGファイルをテクスチャとして取り込む
public static Texture2D LoadJPGorPNG(string filePath) { Texture2D tex = null; byte[] fileData; if (File.Exists(filePath)) { fileData = File.ReadAllBytes(filePath); tex = new Texture2D(2, 2); tex.LoadImage(fileData); // 配列からテクスチャへ変換し PNG/JPG 画像を読み込みます } return tex; }
以下のページを参考にしました:
スクリプトでテクスチャを正方形にクロップする
Texture2D GetSquareCroppedTexture(Texture2D textureOriginal) { int length = textureOriginal.height; int margin = (textureOriginal.width - length) / 2; Color[] c = textureOriginal.GetPixels(margin, 0, length, length); Texture2D textureCropped = new Texture2D(length, length); textureCropped.SetPixels(c); textureCropped.Apply(); return textureCropped; }
スクリプトでテクスチャをPlaneに貼る
void SetTextureToPlane(string filePath, GameObject plane) { Texture2D texture = LoadJPGorPNG(filePath); // ファイルパスからテクスチャを取得する texture = GetSquareCroppedTexture(texture); // 正方形にする Material material = new Material(Shader.Find("HoloToolkit/StandardFast")); material.EnableKeyword("_EMISSION"); material.SetTexture("_EmissionMap", texture); material.SetColor("_EmissionColor", Color.gray); plane.GetComponent<Renderer>().material = material; }
以下のページを参考にしました:
https://forum.unity.com/threads/solved-apply-image-to-plane-primitive.320489/
さあ、明日の反応は吉と出るか凶と出るか…